blob: 8925d18b501829182b3a312dced42c2d5119fe63 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -080023 * Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
24 * All Rights Reserved.
25 * Qualcomm Atheros Confidential and Proprietary.
Kiet Lam842dad02014-02-18 18:44:02 -080026 *
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Jeff Johnson295189b2012-06-20 16:38:30 -070030/*========================================================================
31
32 \file wlan_hdd_main.c
33
34 \brief WLAN Host Device Driver implementation
35
36 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
37
38 Qualcomm Confidential and Proprietary.
39
40 ========================================================================*/
41
42/**=========================================================================
43
44 EDIT HISTORY FOR FILE
45
46
47 This section contains comments describing changes made to the module.
48 Notice that changes are listed in reverse chronological order.
49
50
51 $Header:$ $DateTime: $ $Author: $
52
53
54 when who what, where, why
55 -------- --- --------------------------------------------------------
56 04/5/09 Shailender Created module.
57 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
58 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
59 ==========================================================================*/
60
61/*--------------------------------------------------------------------------
62 Include Files
63 ------------------------------------------------------------------------*/
64//#include <wlan_qct_driver.h>
65#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <vos_api.h>
67#include <vos_sched.h>
68#include <vos_power.h>
69#include <linux/etherdevice.h>
70#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070071#ifdef ANI_BUS_TYPE_PLATFORM
72#include <linux/wcnss_wlan.h>
73#endif //ANI_BUS_TYPE_PLATFORM
74#ifdef ANI_BUS_TYPE_PCI
75#include "wcnss_wlan.h"
76#endif /* ANI_BUS_TYPE_PCI */
77#include <wlan_hdd_tx_rx.h>
78#include <palTimer.h>
79#include <wniApi.h>
80#include <wlan_nlink_srv.h>
81#include <wlan_btc_svc.h>
82#include <wlan_hdd_cfg.h>
83#include <wlan_ptt_sock_svc.h>
84#include <wlan_hdd_wowl.h>
85#include <wlan_hdd_misc.h>
86#include <wlan_hdd_wext.h>
87#ifdef WLAN_BTAMP_FEATURE
88#include <bap_hdd_main.h>
89#include <bapInternal.h>
90#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053091#include "wlan_hdd_trace.h"
92#include "vos_types.h"
93#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070094#include <linux/wireless.h>
95#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053096#include <linux/inetdevice.h>
97#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070098#include "wlan_hdd_cfg80211.h"
99#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700100#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700101int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700102#include "sapApi.h"
103#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700104#include <linux/ctype.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700105#include <mach/subsystem_restart.h>
106#include <wlan_hdd_hostapd.h>
107#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#include "wlan_hdd_dev_pwr.h"
110#ifdef WLAN_BTAMP_FEATURE
111#include "bap_hdd_misc.h"
112#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700113#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700114#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800115#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530116#ifdef FEATURE_WLAN_TDLS
117#include "wlan_hdd_tdls.h"
118#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700119#include "wlan_hdd_debugfs.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700120
121#ifdef MODULE
122#define WLAN_MODULE_NAME module_name(THIS_MODULE)
123#else
124#define WLAN_MODULE_NAME "wlan"
125#endif
126
127#ifdef TIMER_MANAGER
128#define TIMER_MANAGER_STR " +TIMER_MANAGER"
129#else
130#define TIMER_MANAGER_STR ""
131#endif
132
133#ifdef MEMORY_DEBUG
134#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
135#else
136#define MEMORY_DEBUG_STR ""
137#endif
138
139/* the Android framework expects this param even though we don't use it */
140#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700141static char fwpath_buffer[BUF_LEN];
142static struct kparam_string fwpath = {
143 .string = fwpath_buffer,
144 .maxlen = BUF_LEN,
145};
Arif Hussain66559122013-11-21 10:11:40 -0800146
147static char *country_code;
148static int enable_11d = -1;
149static int enable_dfs_chan_scan = -1;
150
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700151#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700152static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700153#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700154
Jeff Johnsone7245742012-09-05 17:12:55 -0700155/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800156 * spinlock for synchronizing asynchronous request/response
157 * (full description of use in wlan_hdd_main.h)
158 */
159DEFINE_SPINLOCK(hdd_context_lock);
160
161/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700162 * The rate at which the driver sends RESTART event to supplicant
163 * once the function 'vos_wlanRestart()' is called
164 *
165 */
166#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
167#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700168
169/*
170 * Size of Driver command strings from upper layer
171 */
172#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
173#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
174
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800175#ifdef FEATURE_CESIUM_PROPRIETARY
176/*
177 * Ibss prop IE from command will be of size 5 + 1(Element ID) + 1(length)
178 */
179#define WLAN_HDD_IBSS_PROP_IE_SIZE 7
180#define WLAN_HDD_IBSS_PROP_VENDOR_ID 0xDD
181#define WLAN_HDD_IBSS_PROP_OUI_DATA_LEN 0x05
182static tANI_U8 ibssPropIe[3] = {0x00,0x16,0x32};
183#endif
184
185#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700186#define TID_MIN_VALUE 0
187#define TID_MAX_VALUE 15
188static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
189 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800190static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
191 tCsrEseBeaconReq *pEseBcnReq);
192#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700193
Srinivas Girigowda4081bb12014-01-06 17:12:58 -0800194#define WLAN_PRIV_DATA_MAX_LEN 4096
195
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700196/*
197 * Driver miracast parameters 0-Disabled
198 * 1-Source, 2-Sink
199 */
200#define WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL 0
201#define WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL 2
202
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800203#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -0700204static struct wake_lock wlan_wake_lock;
Jeff Johnsone7245742012-09-05 17:12:55 -0700205#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700206/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700207static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700208
209//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700210static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
211static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
212static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
213void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800214void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700215
Jeff Johnson295189b2012-06-20 16:38:30 -0700216v_U16_t hdd_select_queue(struct net_device *dev,
217 struct sk_buff *skb);
218
219#ifdef WLAN_FEATURE_PACKET_FILTERING
220static void hdd_set_multicast_list(struct net_device *dev);
221#endif
222
223void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
224
225extern int hdd_setBand_helper(struct net_device *dev, tANI_U8* ptr);
Amar Singhal0a402232013-10-11 20:57:16 -0700226
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800227#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800228void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
229static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700230static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
231 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
232 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700233static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
234 tANI_U8 *pTargetApBssid,
235 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800236#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800237#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700238VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800239#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700240
Mihir Shetee1093ba2014-01-21 20:13:32 +0530241static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
242
Jeff Johnson295189b2012-06-20 16:38:30 -0700243static int hdd_netdev_notifier_call(struct notifier_block * nb,
244 unsigned long state,
245 void *ndev)
246{
247 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700248 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700249 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700250#ifdef WLAN_BTAMP_FEATURE
251 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700252#endif
253
254 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700255 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700256 (strncmp(dev->name, "p2p", 3)))
257 return NOTIFY_DONE;
258
Jeff Johnson295189b2012-06-20 16:38:30 -0700259 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700260 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700261
Jeff Johnson27cee452013-03-27 11:10:24 -0700262 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700263 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800264 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700265 VOS_ASSERT(0);
266 return NOTIFY_DONE;
267 }
268
Jeff Johnson27cee452013-03-27 11:10:24 -0700269 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
270 if (NULL == pHddCtx)
271 {
272 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
273 VOS_ASSERT(0);
274 return NOTIFY_DONE;
275 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800276 if (pHddCtx->isLogpInProgress)
277 return NOTIFY_DONE;
278
Jeff Johnson27cee452013-03-27 11:10:24 -0700279
280 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
281 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700282
283 switch (state) {
284 case NETDEV_REGISTER:
285 break;
286
287 case NETDEV_UNREGISTER:
288 break;
289
290 case NETDEV_UP:
291 break;
292
293 case NETDEV_DOWN:
294 break;
295
296 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700297 if(TRUE == pAdapter->isLinkUpSvcNeeded)
298 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700299 break;
300
301 case NETDEV_GOING_DOWN:
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700302 if( pHddCtx->scan_info.mScanPending != FALSE )
Jeff Johnson295189b2012-06-20 16:38:30 -0700303 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530304 long result;
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -0800305 INIT_COMPLETION(pHddCtx->scan_info.abortscan_event_var);
Srinivas, Dasari138af4f2014-02-07 11:13:45 +0530306 hdd_abort_mac_scan(pAdapter->pHddCtx, pAdapter->sessionId,
307 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -0700308 result = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -0800309 &pHddCtx->scan_info.abortscan_event_var,
Jeff Johnson295189b2012-06-20 16:38:30 -0700310 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530311 if (result <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -0700312 {
313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530314 "%s: Timeout occurred while waiting for abortscan %ld",
315 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700316 }
317 }
318 else
319 {
320 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700321 "%s: Scan is not Pending from user" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700322 }
323#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700325 status = WLANBAP_StopAmp();
326 if(VOS_STATUS_SUCCESS != status )
327 {
328 pHddCtx->isAmpAllowed = VOS_TRUE;
329 hddLog(VOS_TRACE_LEVEL_FATAL,
330 "%s: Failed to stop AMP", __func__);
331 }
332 else
333 {
334 //a state m/c implementation in PAL is TBD to avoid this delay
335 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700336 if ( pHddCtx->isAmpAllowed )
337 {
338 WLANBAP_DeregisterFromHCI();
339 pHddCtx->isAmpAllowed = VOS_FALSE;
340 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700341 }
342#endif //WLAN_BTAMP_FEATURE
343 break;
344
345 default:
346 break;
347 }
348
349 return NOTIFY_DONE;
350}
351
352struct notifier_block hdd_netdev_notifier = {
353 .notifier_call = hdd_netdev_notifier_call,
354};
355
356/*---------------------------------------------------------------------------
357 * Function definitions
358 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700359void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
360void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700361//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700362static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700363#ifndef MODULE
364/* current con_mode - used only for statically linked driver
365 * con_mode is changed by userspace to indicate a mode change which will
366 * result in calling the module exit and init functions. The module
367 * exit function will clean up based on the value of con_mode prior to it
368 * being changed by userspace. So curr_con_mode records the current con_mode
369 * for exit when con_mode becomes the next mode for init
370 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700371static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700372#endif
373
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800374/**---------------------------------------------------------------------------
375
376 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
377
378 Called immediately after the cfg.ini is read in order to configure
379 the desired trace levels.
380
381 \param - moduleId - module whose trace level is being configured
382 \param - bitmask - bitmask of log levels to be enabled
383
384 \return - void
385
386 --------------------------------------------------------------------------*/
387static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
388{
389 wpt_tracelevel level;
390
391 /* if the bitmask is the default value, then a bitmask was not
392 specified in cfg.ini, so leave the logging level alone (it
393 will remain at the "compiled in" default value) */
394 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
395 {
396 return;
397 }
398
399 /* a mask was specified. start by disabling all logging */
400 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
401
402 /* now cycle through the bitmask until all "set" bits are serviced */
403 level = VOS_TRACE_LEVEL_FATAL;
404 while (0 != bitmask)
405 {
406 if (bitmask & 1)
407 {
408 vos_trace_setValue(moduleId, level, 1);
409 }
410 level++;
411 bitmask >>= 1;
412 }
413}
414
415
Jeff Johnson295189b2012-06-20 16:38:30 -0700416/**---------------------------------------------------------------------------
417
418 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
419
420 Called immediately after the cfg.ini is read in order to configure
421 the desired trace levels in the WDI.
422
423 \param - moduleId - module whose trace level is being configured
424 \param - bitmask - bitmask of log levels to be enabled
425
426 \return - void
427
428 --------------------------------------------------------------------------*/
429static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
430{
431 wpt_tracelevel level;
432
433 /* if the bitmask is the default value, then a bitmask was not
434 specified in cfg.ini, so leave the logging level alone (it
435 will remain at the "compiled in" default value) */
436 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
437 {
438 return;
439 }
440
441 /* a mask was specified. start by disabling all logging */
442 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
443
444 /* now cycle through the bitmask until all "set" bits are serviced */
445 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
446 while (0 != bitmask)
447 {
448 if (bitmask & 1)
449 {
450 wpalTraceSetLevel(moduleId, level, 1);
451 }
452 level++;
453 bitmask >>= 1;
454 }
455}
Jeff Johnson295189b2012-06-20 16:38:30 -0700456
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530457/*
458 * FUNCTION: wlan_hdd_validate_context
459 * This function is used to check the HDD context
460 */
461int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
462{
463 ENTER();
464
465 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
466 {
467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
468 "%s: HDD context is Null", __func__);
469 return -ENODEV;
470 }
471
472 if (pHddCtx->isLogpInProgress)
473 {
474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
475 "%s: LOGP in Progress. Ignore!!!", __func__);
476 return -EAGAIN;
477 }
478
479 if (pHddCtx->isLoadUnloadInProgress)
480 {
481 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
482 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
483 return -EAGAIN;
484 }
485 return 0;
486}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700487#ifdef CONFIG_ENABLE_LINUX_REG
488void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
489{
490 hdd_adapter_t *pAdapter = NULL;
491 hdd_station_ctx_t *pHddStaCtx = NULL;
492 eCsrPhyMode phyMode;
493 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530494
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700495 if (NULL == pHddCtx)
496 {
497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
498 "HDD Context is null !!");
499 return ;
500 }
501
502 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
503 if (NULL == pAdapter)
504 {
505 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
506 "pAdapter is null !!");
507 return ;
508 }
509
510 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
511 if (NULL == pHddStaCtx)
512 {
513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
514 "pHddStaCtx is null !!");
515 return ;
516 }
517
518 cfg_param = pHddCtx->cfg_ini;
519 if (NULL == cfg_param)
520 {
521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
522 "cfg_params not available !!");
523 return ;
524 }
525
526 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
527
528 if (!pHddCtx->isVHT80Allowed)
529 {
530 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
531 (eCSR_DOT11_MODE_11ac == phyMode) ||
532 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
533 {
534 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
535 "Setting phymode to 11n!!");
536 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
537 }
538 }
539 else
540 {
541 /*New country Supports 11ac as well resetting value back from .ini*/
542 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
543 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
544 return ;
545 }
546
547 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
548 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
549 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
550 {
551 VOS_STATUS vosStatus;
552
553 // need to issue a disconnect to CSR.
554 INIT_COMPLETION(pAdapter->disconnect_comp_var);
555 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
556 pAdapter->sessionId,
557 eCSR_DISCONNECT_REASON_UNSPECIFIED );
558
559 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530560 {
561 long ret;
562
563 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700564 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530565 if (0 >= ret)
566 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
567 ret);
568 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700569
570 }
571}
572#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530573void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
574{
575 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
576 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
577 hdd_config_t *cfg_param;
578 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530579 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530580
581 if (NULL == pHddCtx)
582 {
583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
584 "HDD Context is null !!");
585 return ;
586 }
587
588 cfg_param = pHddCtx->cfg_ini;
589
590 if (NULL == cfg_param)
591 {
592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
593 "cfg_params not available !!");
594 return ;
595 }
596
597 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
598
599 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
600 {
601 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
602 (eCSR_DOT11_MODE_11ac == phyMode) ||
603 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
604 {
605 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
606 "Setting phymode to 11n!!");
607 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
608 }
609 }
610 else
611 {
612 /*New country Supports 11ac as well resetting value back from .ini*/
613 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
614 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
615 return ;
616 }
617
618 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
619 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
620 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
621 {
622 VOS_STATUS vosStatus;
623
624 // need to issue a disconnect to CSR.
625 INIT_COMPLETION(pAdapter->disconnect_comp_var);
626 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
627 pAdapter->sessionId,
628 eCSR_DISCONNECT_REASON_UNSPECIFIED );
629
630 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530631 {
632 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530633 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530634 if (ret <= 0)
635 {
636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
637 "wait on disconnect_comp_var is failed %ld", ret);
638 }
639 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530640
641 }
642}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700643#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530644
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700645void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
646{
647 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
648 hdd_config_t *cfg_param;
649
650 if (NULL == pHddCtx)
651 {
652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
653 "HDD Context is null !!");
654 return ;
655 }
656
657 cfg_param = pHddCtx->cfg_ini;
658
659 if (NULL == cfg_param)
660 {
661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
662 "cfg_params not available !!");
663 return ;
664 }
665
666 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code))
667 {
668 /*New country doesn't support DFS */
669 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
670 }
671 else
672 {
673 /*New country Supports DFS as well resetting value back from .ini*/
674 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
675 }
676
677}
678
Rajeev79dbe4c2013-10-05 11:03:42 +0530679#ifdef FEATURE_WLAN_BATCH_SCAN
680
681/**---------------------------------------------------------------------------
682
683 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
684 input string
685
686 This function extracts assigned integer from string in below format:
687 "STRING=10" : extracts integer 10 from this string
688
689 \param - pInPtr Pointer to input string
690 \param - base Base for string to int conversion(10 for decimal 16 for hex)
691 \param - pOutPtr Pointer to variable in which extracted integer needs to be
692 assigned
693 \param - pLastArg to tell whether it is last arguement in input string or
694 not
695
696 \return - NULL for failure cases
697 pointer to next arguement in input string for success cases
698 --------------------------------------------------------------------------*/
699static tANI_U8 *
700hdd_extract_assigned_int_from_str
701(
702 tANI_U8 *pInPtr,
703 tANI_U8 base,
704 tANI_U32 *pOutPtr,
705 tANI_U8 *pLastArg
706)
707{
708 int tempInt;
709 int v = 0;
710 char buf[32];
711 int val = 0;
712 *pLastArg = FALSE;
713
714 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
715 if (NULL == pInPtr)
716 {
717 return NULL;
718 }
719
720 pInPtr++;
721
722 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
723
724 val = sscanf(pInPtr, "%32s ", buf);
725 if (val < 0 && val > strlen(pInPtr))
726 {
727 return NULL;
728 }
729 pInPtr += val;
730 v = kstrtos32(buf, base, &tempInt);
731 if (v < 0)
732 {
733 return NULL;
734 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800735 if (tempInt < 0)
736 {
737 tempInt = 0;
738 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530739 *pOutPtr = tempInt;
740
741 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
742 if (NULL == pInPtr)
743 {
744 *pLastArg = TRUE;
745 return NULL;
746 }
747 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
748
749 return pInPtr;
750}
751
752/**---------------------------------------------------------------------------
753
754 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
755 input string
756
757 This function extracts assigned character from string in below format:
758 "STRING=A" : extracts char 'A' from this string
759
760 \param - pInPtr Pointer to input string
761 \param - pOutPtr Pointer to variable in which extracted char needs to be
762 assigned
763 \param - pLastArg to tell whether it is last arguement in input string or
764 not
765
766 \return - NULL for failure cases
767 pointer to next arguement in input string for success cases
768 --------------------------------------------------------------------------*/
769static tANI_U8 *
770hdd_extract_assigned_char_from_str
771(
772 tANI_U8 *pInPtr,
773 tANI_U8 *pOutPtr,
774 tANI_U8 *pLastArg
775)
776{
777 *pLastArg = FALSE;
778
779 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
780 if (NULL == pInPtr)
781 {
782 return NULL;
783 }
784
785 pInPtr++;
786
787 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
788
789 *pOutPtr = *pInPtr;
790
791 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
792 if (NULL == pInPtr)
793 {
794 *pLastArg = TRUE;
795 return NULL;
796 }
797 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
798
799 return pInPtr;
800}
801
802
803/**---------------------------------------------------------------------------
804
805 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
806
807 This function parses set batch scan command in below format:
808 WLS_BATCHING_SET <space> followed by below arguements
809 "SCANFREQ=XX" : Optional defaults to 30 sec
810 "MSCAN=XX" : Required number of scans to attempt to batch
811 "BESTN=XX" : Best Network (RSSI) defaults to 16
812 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
813 A. implies only 5 GHz , B. implies only 2.4GHz
814 "RTT=X" : optional defaults to 0
815 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
816 error
817
818 For example input commands:
819 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
820 translated into set batch scan with following parameters:
821 a) Frequence 60 seconds
822 b) Batch 10 scans together
823 c) Best RSSI to be 20
824 d) 5GHz band only
825 e) RTT is equal to 0
826
827 \param - pValue Pointer to input channel list
828 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
829
830 \return - 0 for success non-zero for failure
831
832 --------------------------------------------------------------------------*/
833static int
834hdd_parse_set_batchscan_command
835(
836 tANI_U8 *pValue,
837 tSirSetBatchScanReq *pHddSetBatchScanReq
838)
839{
840 tANI_U8 *inPtr = pValue;
841 tANI_U8 val = 0;
842 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800843 tANI_U32 nScanFreq;
844 tANI_U32 nMscan;
845 tANI_U32 nBestN;
846 tANI_U8 ucRfBand;
847 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800848 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530849
850 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800851 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
852 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
853 nRtt = 0;
854 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530855
856 /*go to space after WLS_BATCHING_SET command*/
857 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
858 /*no argument after the command*/
859 if (NULL == inPtr)
860 {
861 return -EINVAL;
862 }
863
864 /*no space after the command*/
865 else if (SPACE_ASCII_VALUE != *inPtr)
866 {
867 return -EINVAL;
868 }
869
870 /*removing empty spaces*/
871 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
872
873 /*no argument followed by spaces*/
874 if ('\0' == *inPtr)
875 {
876 return -EINVAL;
877 }
878
879 /*check and parse SCANFREQ*/
880 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
881 {
882 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800883 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800884
Rajeev Kumarc933d982013-11-18 20:04:20 -0800885 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800886 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800887 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800888 }
889
Rajeev79dbe4c2013-10-05 11:03:42 +0530890 if ( (NULL == inPtr) || (TRUE == lastArg))
891 {
892 return -EINVAL;
893 }
894 }
895
896 /*check and parse MSCAN*/
897 if ((strncmp(inPtr, "MSCAN", 5) == 0))
898 {
899 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800900 &nMscan, &lastArg);
901
902 if (0 == nMscan)
903 {
904 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
905 "invalid MSCAN=%d", nMscan);
906 return -EINVAL;
907 }
908
Rajeev79dbe4c2013-10-05 11:03:42 +0530909 if (TRUE == lastArg)
910 {
911 goto done;
912 }
913 else if (NULL == inPtr)
914 {
915 return -EINVAL;
916 }
917 }
918 else
919 {
920 return -EINVAL;
921 }
922
923 /*check and parse BESTN*/
924 if ((strncmp(inPtr, "BESTN", 5) == 0))
925 {
926 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800927 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800928
Rajeev Kumarc933d982013-11-18 20:04:20 -0800929 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800930 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800931 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800932 }
933
Rajeev79dbe4c2013-10-05 11:03:42 +0530934 if (TRUE == lastArg)
935 {
936 goto done;
937 }
938 else if (NULL == inPtr)
939 {
940 return -EINVAL;
941 }
942 }
943
944 /*check and parse CHANNEL*/
945 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
946 {
947 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800948
Rajeev79dbe4c2013-10-05 11:03:42 +0530949 if (('A' == val) || ('a' == val))
950 {
c_hpothuebf89732014-02-25 13:00:24 +0530951 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530952 }
953 else if (('B' == val) || ('b' == val))
954 {
c_hpothuebf89732014-02-25 13:00:24 +0530955 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530956 }
957 else
958 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800959 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
960 }
961
962 if (TRUE == lastArg)
963 {
964 goto done;
965 }
966 else if (NULL == inPtr)
967 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530968 return -EINVAL;
969 }
970 }
971
972 /*check and parse RTT*/
973 if ((strncmp(inPtr, "RTT", 3) == 0))
974 {
975 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800976 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530977 if (TRUE == lastArg)
978 {
979 goto done;
980 }
981 if (NULL == inPtr)
982 {
983 return -EINVAL;
984 }
985 }
986
987
988done:
989
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800990 pHddSetBatchScanReq->scanFrequency = nScanFreq;
991 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
992 pHddSetBatchScanReq->bestNetwork = nBestN;
993 pHddSetBatchScanReq->rfBand = ucRfBand;
994 pHddSetBatchScanReq->rtt = nRtt;
995
Rajeev79dbe4c2013-10-05 11:03:42 +0530996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
997 "Received WLS_BATCHING_SET with SCANFREQ=%d "
998 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
999 pHddSetBatchScanReq->scanFrequency,
1000 pHddSetBatchScanReq->numberOfScansToBatch,
1001 pHddSetBatchScanReq->bestNetwork,
1002 pHddSetBatchScanReq->rfBand,
1003 pHddSetBatchScanReq->rtt);
1004
1005 return 0;
1006}/*End of hdd_parse_set_batchscan_command*/
1007
1008/**---------------------------------------------------------------------------
1009
1010 \brief hdd_set_batch_scan_req_callback () - This function is called after
1011 receiving set batch scan response from FW and it saves set batch scan
1012 response data FW to HDD context and sets the completion event on
1013 which hdd_ioctl is waiting
1014
1015 \param - callbackContext Pointer to HDD adapter
1016 \param - pRsp Pointer to set batch scan response data received from FW
1017
1018 \return - nothing
1019
1020 --------------------------------------------------------------------------*/
1021static void hdd_set_batch_scan_req_callback
1022(
1023 void *callbackContext,
1024 tSirSetBatchScanRsp *pRsp
1025)
1026{
1027 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1028 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1029
1030 /*sanity check*/
1031 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1032 {
1033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1034 "%s: Invalid pAdapter magic", __func__);
1035 VOS_ASSERT(0);
1036 return;
1037 }
1038 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1039
1040 /*save set batch scan response*/
1041 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1042
1043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1044 "Received set batch scan rsp from FW with nScansToBatch=%d",
1045 pHddSetBatchScanRsp->nScansToBatch);
1046
1047 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1048 complete(&pAdapter->hdd_set_batch_scan_req_var);
1049
1050 return;
1051}/*End of hdd_set_batch_scan_req_callback*/
1052
1053
1054/**---------------------------------------------------------------------------
1055
1056 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1057 info in hdd batch scan response queue
1058
1059 \param - pAdapter Pointer to hdd adapter
1060 \param - pAPMetaInfo Pointer to access point meta info
1061 \param - scanId scan ID of batch scan response
1062 \param - isLastAp tells whether AP is last AP in batch scan response or not
1063
1064 \return - nothing
1065
1066 --------------------------------------------------------------------------*/
1067static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1068 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1069{
1070 tHddBatchScanRsp *pHead;
1071 tHddBatchScanRsp *pNode;
1072 tHddBatchScanRsp *pPrev;
1073 tHddBatchScanRsp *pTemp;
1074 tANI_U8 ssidLen;
1075
1076 /*head of hdd batch scan response queue*/
1077 pHead = pAdapter->pBatchScanRsp;
1078
1079 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1080 if (NULL == pNode)
1081 {
1082 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1083 "%s: Could not allocate memory", __func__);
1084 VOS_ASSERT(0);
1085 return;
1086 }
1087
1088 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1089 sizeof(pNode->ApInfo.bssid));
1090 ssidLen = strlen(pApMetaInfo->ssid);
1091 if (SIR_MAX_SSID_SIZE < ssidLen)
1092 {
1093 /*invalid scan result*/
1094 vos_mem_free(pNode);
1095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1096 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1097 return;
1098 }
1099 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1100 /*null terminate ssid*/
1101 pNode->ApInfo.ssid[ssidLen] = '\0';
1102 pNode->ApInfo.ch = pApMetaInfo->ch;
1103 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1104 pNode->ApInfo.age = pApMetaInfo->timestamp;
1105 pNode->ApInfo.batchId = scanId;
1106 pNode->ApInfo.isLastAp = isLastAp;
1107
1108 pNode->pNext = NULL;
1109 if (NULL == pHead)
1110 {
1111 pAdapter->pBatchScanRsp = pNode;
1112 }
1113 else
1114 {
1115 pTemp = pHead;
1116 while (NULL != pTemp)
1117 {
1118 pPrev = pTemp;
1119 pTemp = pTemp->pNext;
1120 }
1121 pPrev->pNext = pNode;
1122 }
1123
1124 return;
1125}/*End of hdd_populate_batch_scan_rsp_queue*/
1126
1127/**---------------------------------------------------------------------------
1128
1129 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1130 receiving batch scan response indication from FW. It saves get batch scan
1131 response data in HDD batch scan response queue. This callback sets the
1132 completion event on which hdd_ioctl is waiting only after getting complete
1133 batch scan response data from FW
1134
1135 \param - callbackContext Pointer to HDD adapter
1136 \param - pRsp Pointer to get batch scan response data received from FW
1137
1138 \return - nothing
1139
1140 --------------------------------------------------------------------------*/
1141static void hdd_batch_scan_result_ind_callback
1142(
1143 void *callbackContext,
1144 void *pRsp
1145)
1146{
1147 v_BOOL_t isLastAp;
1148 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001149 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301150 tANI_U32 numberScanList;
1151 tANI_U32 nextScanListOffset;
1152 tANI_U32 nextApMetaInfoOffset;
1153 hdd_adapter_t* pAdapter;
1154 tpSirBatchScanList pScanList;
1155 tpSirBatchScanNetworkInfo pApMetaInfo;
1156 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1157 tSirSetBatchScanReq *pReq;
1158
1159 pAdapter = (hdd_adapter_t *)callbackContext;
1160 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001161 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301162 {
1163 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1164 "%s: Invalid pAdapter magic", __func__);
1165 VOS_ASSERT(0);
1166 return;
1167 }
1168
1169 /*initialize locals*/
1170 pReq = &pAdapter->hddSetBatchScanReq;
1171 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1172 isLastAp = FALSE;
1173 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001174 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301175 numberScanList = 0;
1176 nextScanListOffset = 0;
1177 nextApMetaInfoOffset = 0;
1178 pScanList = NULL;
1179 pApMetaInfo = NULL;
1180
1181 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1182 {
1183 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1184 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1185 isLastAp = TRUE;
1186 goto done;
1187 }
1188
1189 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1191 "Batch scan rsp: numberScalList %d", numberScanList);
1192
1193 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1194 {
1195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1196 "%s: numberScanList %d", __func__, numberScanList);
1197 isLastAp = TRUE;
1198 goto done;
1199 }
1200
1201 while (numberScanList)
1202 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001203 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301204 nextScanListOffset);
1205 if (NULL == pScanList)
1206 {
1207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1208 "%s: pScanList is %p", __func__, pScanList);
1209 isLastAp = TRUE;
1210 goto done;
1211 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001212 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001214 "Batch scan rsp: numApMetaInfo %d scanId %d",
1215 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301216
1217 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1218 {
1219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1220 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1221 isLastAp = TRUE;
1222 goto done;
1223 }
1224
Rajeev Kumarce651e42013-10-21 18:57:15 -07001225 /*Initialize next AP meta info offset for next scan list*/
1226 nextApMetaInfoOffset = 0;
1227
Rajeev79dbe4c2013-10-05 11:03:42 +05301228 while (numApMetaInfo)
1229 {
1230 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1231 nextApMetaInfoOffset);
1232 if (NULL == pApMetaInfo)
1233 {
1234 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1235 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1236 isLastAp = TRUE;
1237 goto done;
1238 }
1239 /*calculate AP age*/
1240 pApMetaInfo->timestamp =
1241 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1242
1243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001244 "%s: bssId "MAC_ADDRESS_STR
1245 " ch %d rssi %d timestamp %d", __func__,
1246 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1247 pApMetaInfo->ch, pApMetaInfo->rssi,
1248 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301249
1250 /*mark last AP in batch scan response*/
1251 if ((TRUE == pBatchScanRsp->isLastResult) &&
1252 (1 == numberScanList) && (1 == numApMetaInfo))
1253 {
1254 isLastAp = TRUE;
1255 }
1256
1257 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1258 /*store batch scan repsonse in hdd queue*/
1259 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1260 pScanList->scanId, isLastAp);
1261 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1262
1263 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1264 numApMetaInfo--;
1265 }
1266
Rajeev Kumarce651e42013-10-21 18:57:15 -07001267 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1268 + (sizeof(tSirBatchScanNetworkInfo)
1269 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301270 numberScanList--;
1271 }
1272
1273done:
1274
1275 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1276 requested from hdd_ioctl*/
1277 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1278 (TRUE == isLastAp))
1279 {
1280 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1281 complete(&pAdapter->hdd_get_batch_scan_req_var);
1282 }
1283
1284 return;
1285}/*End of hdd_batch_scan_result_ind_callback*/
1286
1287/**---------------------------------------------------------------------------
1288
1289 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1290 response as per batch scan FR request format by putting proper markers
1291
1292 \param - pDest pointer to destination buffer
1293 \param - cur_len current length
1294 \param - tot_len total remaining size which can be written to user space
1295 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1296 \param - pAdapter Pointer to HDD adapter
1297
1298 \return - ret no of characters written
1299
1300 --------------------------------------------------------------------------*/
1301static tANI_U32
1302hdd_format_batch_scan_rsp
1303(
1304 tANI_U8 *pDest,
1305 tANI_U32 cur_len,
1306 tANI_U32 tot_len,
1307 tHddBatchScanRsp *pApMetaInfo,
1308 hdd_adapter_t* pAdapter
1309)
1310{
1311 tANI_U32 ret = 0;
1312 tANI_U32 rem_len = 0;
1313 tANI_U8 temp_len = 0;
1314 tANI_U8 temp_total_len = 0;
1315 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1316 tANI_U8 *pTemp = temp;
1317
1318 /*Batch scan reponse needs to be returned to user space in
1319 following format:
1320 "scancount=X\n" where X is the number of scans in current batch
1321 batch
1322 "trunc\n" optional present if current scan truncated
1323 "bssid=XX:XX:XX:XX:XX:XX\n"
1324 "ssid=XXXX\n"
1325 "freq=X\n" frequency in Mhz
1326 "level=XX\n"
1327 "age=X\n" ms
1328 "dist=X\n" cm (-1 if not available)
1329 "errror=X\n" (-1if not available)
1330 "====\n" (end of ap marker)
1331 "####\n" (end of scan marker)
1332 "----\n" (end of results)*/
1333 /*send scan result in above format to user space based on
1334 available length*/
1335 /*The GET response may have more data than the driver can return in its
1336 buffer. In that case the buffer should be filled to the nearest complete
1337 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1338 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1339 The final buffer should end with "----\n"*/
1340
1341 /*sanity*/
1342 if (cur_len > tot_len)
1343 {
1344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1345 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1346 return 0;
1347 }
1348 else
1349 {
1350 rem_len = (tot_len - cur_len);
1351 }
1352
1353 /*end scan marker*/
1354 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1355 {
1356 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1357 pTemp += temp_len;
1358 temp_total_len += temp_len;
1359 }
1360
1361 /*bssid*/
1362 temp_len = snprintf(pTemp, sizeof(temp),
1363 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1364 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1365 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1366 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1367 pTemp += temp_len;
1368 temp_total_len += temp_len;
1369
1370 /*ssid*/
1371 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1372 pApMetaInfo->ApInfo.ssid);
1373 pTemp += temp_len;
1374 temp_total_len += temp_len;
1375
1376 /*freq*/
1377 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001378 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301379 pTemp += temp_len;
1380 temp_total_len += temp_len;
1381
1382 /*level*/
1383 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1384 pApMetaInfo->ApInfo.rssi);
1385 pTemp += temp_len;
1386 temp_total_len += temp_len;
1387
1388 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001389 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301390 pApMetaInfo->ApInfo.age);
1391 pTemp += temp_len;
1392 temp_total_len += temp_len;
1393
1394 /*dist*/
1395 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1396 pTemp += temp_len;
1397 temp_total_len += temp_len;
1398
1399 /*error*/
1400 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1401 pTemp += temp_len;
1402 temp_total_len += temp_len;
1403
1404 /*end AP marker*/
1405 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1406 pTemp += temp_len;
1407 temp_total_len += temp_len;
1408
1409 /*last AP in batch scan response*/
1410 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1411 {
1412 /*end scan marker*/
1413 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1414 pTemp += temp_len;
1415 temp_total_len += temp_len;
1416
1417 /*end batch scan result marker*/
1418 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1419 pTemp += temp_len;
1420 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001421
Rajeev79dbe4c2013-10-05 11:03:42 +05301422 }
1423
1424 if (temp_total_len < rem_len)
1425 {
1426 ret = temp_total_len + 1;
1427 strlcpy(pDest, temp, ret);
1428 pAdapter->isTruncated = FALSE;
1429 }
1430 else
1431 {
1432 pAdapter->isTruncated = TRUE;
1433 if (rem_len >= strlen("%%%%"))
1434 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001435 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301436 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001437 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301438 {
1439 ret = 0;
1440 }
1441 }
1442
1443 return ret;
1444
1445}/*End of hdd_format_batch_scan_rsp*/
1446
1447/**---------------------------------------------------------------------------
1448
1449 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1450 buffer starting with head of hdd batch scan response queue
1451
1452 \param - pAdapter Pointer to HDD adapter
1453 \param - pDest Pointer to user data buffer
1454 \param - cur_len current offset in user buffer
1455 \param - rem_len remaining no of bytes in user buffer
1456
1457 \return - number of bytes written in user buffer
1458
1459 --------------------------------------------------------------------------*/
1460
1461tANI_U32 hdd_populate_user_batch_scan_rsp
1462(
1463 hdd_adapter_t* pAdapter,
1464 tANI_U8 *pDest,
1465 tANI_U32 cur_len,
1466 tANI_U32 rem_len
1467)
1468{
1469 tHddBatchScanRsp *pHead;
1470 tHddBatchScanRsp *pPrev;
1471 tANI_U32 len;
1472
Rajeev79dbe4c2013-10-05 11:03:42 +05301473 pAdapter->isTruncated = FALSE;
1474
1475 /*head of hdd batch scan response queue*/
1476 pHead = pAdapter->pBatchScanRsp;
1477 while (pHead)
1478 {
1479 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1480 pAdapter);
1481 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001482 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301483 cur_len += len;
1484 if(TRUE == pAdapter->isTruncated)
1485 {
1486 /*result is truncated return rest of scan rsp in next req*/
1487 cur_len = rem_len;
1488 break;
1489 }
1490 pPrev = pHead;
1491 pHead = pHead->pNext;
1492 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001493 if (TRUE == pPrev->ApInfo.isLastAp)
1494 {
1495 pAdapter->prev_batch_id = 0;
1496 }
1497 else
1498 {
1499 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1500 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301501 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001502 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301503 }
1504
1505 return cur_len;
1506}/*End of hdd_populate_user_batch_scan_rsp*/
1507
1508/**---------------------------------------------------------------------------
1509
1510 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1511 scan response data from HDD queue to user space
1512 It does following in detail:
1513 a) if HDD has enough data in its queue then it 1st copies data to user
1514 space and then send get batch scan indication message to FW. In this
1515 case it does not wait on any event and batch scan response data will
1516 be populated in HDD response queue in MC thread context after receiving
1517 indication from FW
1518 b) else send get batch scan indication message to FW and wait on an event
1519 which will be set once HDD receives complete batch scan response from
1520 FW and then this function returns batch scan response to user space
1521
1522 \param - pAdapter Pointer to HDD adapter
1523 \param - pPrivData Pointer to priv_data
1524
1525 \return - 0 for success -EFAULT for failure
1526
1527 --------------------------------------------------------------------------*/
1528
1529int hdd_return_batch_scan_rsp_to_user
1530(
1531 hdd_adapter_t* pAdapter,
1532 hdd_priv_data_t *pPrivData,
1533 tANI_U8 *command
1534)
1535{
1536 tANI_U8 *pDest;
1537 tANI_U32 count = 0;
1538 tANI_U32 len = 0;
1539 tANI_U32 cur_len = 0;
1540 tANI_U32 rem_len = 0;
1541 eHalStatus halStatus;
1542 unsigned long rc;
1543 tSirTriggerBatchScanResultInd *pReq;
1544
1545 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1546 pReq->param = 0;/*batch scan client*/
1547 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1548 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1549
1550 cur_len = pPrivData->used_len;
1551 if (pPrivData->total_len > pPrivData->used_len)
1552 {
1553 rem_len = pPrivData->total_len - pPrivData->used_len;
1554 }
1555 else
1556 {
1557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1558 "%s: Invalid user data buffer total_len %d used_len %d",
1559 __func__, pPrivData->total_len, pPrivData->used_len);
1560 return -EFAULT;
1561 }
1562
1563 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1564 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1565 cur_len, rem_len);
1566 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1567
1568 /*enough scan result available in cache to return to user space or
1569 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001570 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301571 {
1572 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1573 halStatus = sme_TriggerBatchScanResultInd(
1574 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1575 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1576 pAdapter);
1577 if ( eHAL_STATUS_SUCCESS == halStatus )
1578 {
1579 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1580 {
1581 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1582 rc = wait_for_completion_timeout(
1583 &pAdapter->hdd_get_batch_scan_req_var,
1584 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1585 if (0 == rc)
1586 {
1587 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1588 "%s: Timeout waiting to fetch batch scan rsp from fw",
1589 __func__);
1590 return -EFAULT;
1591 }
1592 }
1593
1594 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001595 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301596 pDest += len;
1597 cur_len += len;
1598
1599 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1600 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1601 cur_len, rem_len);
1602 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1603
1604 count = 0;
1605 len = (len - pPrivData->used_len);
1606 pDest = (command + pPrivData->used_len);
1607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001608 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301609 while(count < len)
1610 {
1611 printk("%c", *(pDest + count));
1612 count++;
1613 }
1614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1615 "%s: copy %d data to user buffer", __func__, len);
1616 if (copy_to_user(pPrivData->buf, pDest, len))
1617 {
1618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1619 "%s: failed to copy data to user buffer", __func__);
1620 return -EFAULT;
1621 }
1622 }
1623 else
1624 {
1625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1626 "sme_GetBatchScanScan returned failure halStatus %d",
1627 halStatus);
1628 return -EINVAL;
1629 }
1630 }
1631 else
1632 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301633 count = 0;
1634 len = (len - pPrivData->used_len);
1635 pDest = (command + pPrivData->used_len);
1636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001637 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301638 while(count < len)
1639 {
1640 printk("%c", *(pDest + count));
1641 count++;
1642 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1644 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301645 if (copy_to_user(pPrivData->buf, pDest, len))
1646 {
1647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1648 "%s: failed to copy data to user buffer", __func__);
1649 return -EFAULT;
1650 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301651 }
1652
1653 return 0;
1654} /*End of hdd_return_batch_scan_rsp_to_user*/
1655
Rajeev Kumar8b373292014-01-08 20:36:55 -08001656
1657/**---------------------------------------------------------------------------
1658
1659 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1660 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1661 WLS_BATCHING VERSION
1662 WLS_BATCHING SET
1663 WLS_BATCHING GET
1664 WLS_BATCHING STOP
1665
1666 \param - pAdapter Pointer to HDD adapter
1667 \param - pPrivdata Pointer to priv_data
1668 \param - command Pointer to command
1669
1670 \return - 0 for success -EFAULT for failure
1671
1672 --------------------------------------------------------------------------*/
1673
1674int hdd_handle_batch_scan_ioctl
1675(
1676 hdd_adapter_t *pAdapter,
1677 hdd_priv_data_t *pPrivdata,
1678 tANI_U8 *command
1679)
1680{
1681 int ret = 0;
1682
1683 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1684 {
1685 char extra[32];
1686 tANI_U8 len = 0;
1687 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1688
1689 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1690 {
1691 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1692 "%s: Batch scan feature is not supported by FW", __func__);
1693 ret = -EINVAL;
1694 goto exit;
1695 }
1696
1697 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1698 version);
1699 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1700 {
1701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1702 "%s: failed to copy data to user buffer", __func__);
1703 ret = -EFAULT;
1704 goto exit;
1705 }
1706 ret = HDD_BATCH_SCAN_VERSION;
1707 }
1708 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1709 {
1710 int status;
1711 tANI_U8 *value = (command + 16);
1712 eHalStatus halStatus;
1713 unsigned long rc;
1714 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1715 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1716
1717 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1718 {
1719 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1720 "%s: Batch scan feature is not supported by FW", __func__);
1721 ret = -EINVAL;
1722 goto exit;
1723 }
1724
1725 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1726 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1727 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1728 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1729 {
1730 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1731 "Received WLS_BATCHING SET command in invalid mode %d "
1732 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
1733 pAdapter->device_mode);
1734 ret = -EINVAL;
1735 goto exit;
1736 }
1737
1738 status = hdd_parse_set_batchscan_command(value, pReq);
1739 if (status)
1740 {
1741 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1742 "Invalid WLS_BATCHING SET command");
1743 ret = -EINVAL;
1744 goto exit;
1745 }
1746
1747
1748 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1749 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1750 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1751 pAdapter);
1752
1753 if ( eHAL_STATUS_SUCCESS == halStatus )
1754 {
1755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1756 "sme_SetBatchScanReq returned success halStatus %d",
1757 halStatus);
1758 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1759 {
1760 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1761 rc = wait_for_completion_timeout(
1762 &pAdapter->hdd_set_batch_scan_req_var,
1763 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1764 if (0 == rc)
1765 {
1766 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1767 "%s: Timeout waiting for set batch scan to complete",
1768 __func__);
1769 ret = -EINVAL;
1770 goto exit;
1771 }
1772 }
1773 if ( !pRsp->nScansToBatch )
1774 {
1775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1776 "%s: Received set batch scan failure response from FW",
1777 __func__);
1778 ret = -EINVAL;
1779 goto exit;
1780 }
1781 /*As per the Batch Scan Framework API we should return the MIN of
1782 either MSCAN or the max # of scans firmware can cache*/
1783 ret = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
1784
1785 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1786
1787 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1788 "%s: request MSCAN %d response MSCAN %d ret %d",
1789 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, ret);
1790 }
1791 else
1792 {
1793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1794 "sme_SetBatchScanReq returned failure halStatus %d",
1795 halStatus);
1796 ret = -EINVAL;
1797 goto exit;
1798 }
1799 }
1800 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1801 {
1802 eHalStatus halStatus;
1803 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1804 pInd->param = 0;
1805
1806 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1807 {
1808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1809 "%s: Batch scan feature is not supported by FW", __func__);
1810 ret = -EINVAL;
1811 goto exit;
1812 }
1813
1814 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1815 {
1816 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1817 "Batch scan is not yet enabled batch scan state %d",
1818 pAdapter->batchScanState);
1819 ret = -EINVAL;
1820 goto exit;
1821 }
1822
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001823 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1824 hdd_deinit_batch_scan(pAdapter);
1825 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1826
Rajeev Kumar8b373292014-01-08 20:36:55 -08001827 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1828
1829 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1830 pAdapter->sessionId);
1831 if ( eHAL_STATUS_SUCCESS == halStatus )
1832 {
1833 ret = 0;
1834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1835 "sme_StopBatchScanInd returned success halStatus %d",
1836 halStatus);
1837 }
1838 else
1839 {
1840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1841 "sme_StopBatchScanInd returned failure halStatus %d",
1842 halStatus);
1843 ret = -EINVAL;
1844 goto exit;
1845 }
1846 }
1847 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1848 {
1849 tANI_U32 remain_len;
1850
1851 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1852 {
1853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1854 "%s: Batch scan feature is not supported by FW", __func__);
1855 ret = -EINVAL;
1856 goto exit;
1857 }
1858
1859 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1860 {
1861 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1862 "Batch scan is not yet enabled could not return results"
1863 "Batch Scan state %d",
1864 pAdapter->batchScanState);
1865 ret = -EINVAL;
1866 goto exit;
1867 }
1868
1869 pPrivdata->used_len = 16;
1870 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1871 if (remain_len < pPrivdata->total_len)
1872 {
1873 /*Clear previous batch scan response data if any*/
1874 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1875 }
1876 else
1877 {
1878 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1879 "Invalid total length from user space can't fetch batch"
1880 " scan response total_len %d used_len %d remain len %d",
1881 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1882 ret = -EINVAL;
1883 goto exit;
1884 }
1885 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1886 }
1887
1888exit:
1889
1890 return ret;
1891}
1892
1893
Rajeev79dbe4c2013-10-05 11:03:42 +05301894#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1895
Jeff Johnson295189b2012-06-20 16:38:30 -07001896int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1897{
1898 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1899 hdd_priv_data_t priv_data;
1900 tANI_U8 *command = NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301901 long ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001902
1903 if (NULL == pAdapter)
1904 {
1905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05301906 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001907 ret = -ENODEV;
1908 goto exit;
1909 }
1910
Jeff Johnsone7245742012-09-05 17:12:55 -07001911 if ((!ifr) || (!ifr->ifr_data))
Jeff Johnson295189b2012-06-20 16:38:30 -07001912 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1914 "%s: invalid data", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001915 ret = -EINVAL;
1916 goto exit;
1917 }
1918
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07001919 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1920 {
1921 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1922 "%s:LOGP in Progress. Ignore!!!", __func__);
1923 ret = -EBUSY;
1924 goto exit;
1925 }
1926
Jeff Johnson295189b2012-06-20 16:38:30 -07001927 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(hdd_priv_data_t)))
1928 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301929 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1930 FL("failed to get data from user buffer"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001931 ret = -EFAULT;
1932 goto exit;
1933 }
1934
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08001935 if (priv_data.total_len <= 0 ||
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301936 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07001937 {
1938 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1939 "%s:invalid priv_data.total_len(%d)!!!", __func__,
1940 priv_data.total_len);
1941 ret = -EINVAL;
1942 goto exit;
1943 }
1944
1945 /* Allocate +1 for '\0' */
1946 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07001947 if (!command)
1948 {
1949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301950 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001951 ret = -ENOMEM;
1952 goto exit;
1953 }
1954
1955 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
1956 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1958 FL("failed to get data from user buffer"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001959 ret = -EFAULT;
1960 goto exit;
1961 }
1962
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07001963 /* Making sure the command is NUL-terminated */
1964 command[priv_data.total_len] = '\0';
1965
Jeff Johnson295189b2012-06-20 16:38:30 -07001966 if ((SIOCDEVPRIVATE + 1) == cmd)
1967 {
1968 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
1969
1970 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07001971 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07001972
1973 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
1974 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301975 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
1976 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
1977 pAdapter->sessionId, (unsigned)
1978 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
1979 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
1980 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
1981 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07001982 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
1983 sizeof(tSirMacAddr)))
1984 {
1985 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001986 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001987 ret = -EFAULT;
1988 }
1989 }
Amar Singhal0974e402013-02-12 14:27:46 -08001990 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07001991 {
Amar Singhal0974e402013-02-12 14:27:46 -08001992 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08001993
Jeff Johnson295189b2012-06-20 16:38:30 -07001994 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08001995
1996 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07001997 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001998 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08001999 "%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 -07002000 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002001 ret = hdd_setBand_helper(dev, ptr);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302002 if(ret != 0)
2003 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2004 "%s: failed to set band ret=%ld",__func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002005 }
Kiet Lamf040f472013-11-20 21:15:23 +05302006 else if(strncmp(command, "SETWMMPS", 8) == 0)
2007 {
2008 tANI_U8 *ptr = command;
2009 ret = hdd_wmmps_helper(pAdapter, ptr);
2010 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002011 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2012 {
2013 char *country_code;
2014
2015 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002016
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002017 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002018 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002019#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302020 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002021#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002022 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2023 (void *)(tSmeChangeCountryCallback)
2024 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302025 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002026 if (eHAL_STATUS_SUCCESS == ret)
2027 {
2028 ret = wait_for_completion_interruptible_timeout(
2029 &pAdapter->change_country_code,
2030 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2031 if (0 >= ret)
2032 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302033 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %ld",
2034 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002035 }
2036 }
2037 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002038 {
2039 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302040 "%s: SME Change Country code fail ret=%ld", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002041 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002042 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002043
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002044 }
2045 /*
2046 command should be a string having format
2047 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2048 */
Amar Singhal0974e402013-02-12 14:27:46 -08002049 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002050 {
Amar Singhal0974e402013-02-12 14:27:46 -08002051 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002052
2053 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002054 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002055
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002056 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002057 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002058 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2059 {
2060 int suspend = 0;
2061 tANI_U8 *ptr = (tANI_U8*)command + 15;
2062
2063 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302064 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2065 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2066 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002067 hdd_set_wlan_suspend_mode(suspend);
2068 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002069#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2070 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2071 {
2072 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002073 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002074 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2075 eHalStatus status = eHAL_STATUS_SUCCESS;
2076
2077 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2078 value = value + 15;
2079
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002080 /* Convert the value from ascii to integer */
2081 ret = kstrtos8(value, 10, &rssi);
2082 if (ret < 0)
2083 {
2084 /* If the input value is greater than max value of datatype, then also
2085 kstrtou8 fails */
2086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2087 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002088 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002089 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2090 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2091 ret = -EINVAL;
2092 goto exit;
2093 }
2094
Srinivas Girigowdade697412013-02-14 16:31:48 -08002095 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002096
Srinivas Girigowdade697412013-02-14 16:31:48 -08002097 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2098 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2099 {
2100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2101 "Neighbor lookup threshold value %d is out of range"
2102 " (Min: %d Max: %d)", lookUpThreshold,
2103 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2104 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2105 ret = -EINVAL;
2106 goto exit;
2107 }
2108
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302109 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2110 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2111 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2113 "%s: Received Command to Set Roam trigger"
2114 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2115
2116 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2117 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2118 if (eHAL_STATUS_SUCCESS != status)
2119 {
2120 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2121 "%s: Failed to set roam trigger, try again", __func__);
2122 ret = -EPERM;
2123 goto exit;
2124 }
2125
2126 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
2127 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2128 }
2129 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2130 {
2131 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2132 int rssi = (-1) * lookUpThreshold;
2133 char extra[32];
2134 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302135 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2136 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2137 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002138 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002139 if (copy_to_user(priv_data.buf, &extra, len + 1))
2140 {
2141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2142 "%s: failed to copy data to user buffer", __func__);
2143 ret = -EFAULT;
2144 goto exit;
2145 }
2146 }
2147 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2148 {
2149 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002150 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002151 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002152
Srinivas Girigowdade697412013-02-14 16:31:48 -08002153 /* input refresh period is in terms of seconds */
2154 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2155 value = value + 18;
2156 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002157 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002158 if (ret < 0)
2159 {
2160 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002161 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002163 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002164 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002165 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2166 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002167 ret = -EINVAL;
2168 goto exit;
2169 }
2170
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002171 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2172 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002173 {
2174 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002175 "Roam scan period value %d is out of range"
2176 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002177 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2178 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002179 ret = -EINVAL;
2180 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302181 }
2182 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2183 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2184 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002185 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002186
2187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2188 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002189 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002190
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002191 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2192 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002193 }
2194 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2195 {
2196 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2197 char extra[32];
2198 tANI_U8 len = 0;
2199
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302200 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2201 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2202 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002203 len = scnprintf(extra, sizeof(extra), "%s %d",
2204 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002205 /* Returned value is in units of seconds */
2206 if (copy_to_user(priv_data.buf, &extra, len + 1))
2207 {
2208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2209 "%s: failed to copy data to user buffer", __func__);
2210 ret = -EFAULT;
2211 goto exit;
2212 }
2213 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002214 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2215 {
2216 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002217 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002218 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002219
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002220 /* input refresh period is in terms of seconds */
2221 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2222 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002223
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002224 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002225 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002226 if (ret < 0)
2227 {
2228 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002229 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002230 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002231 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002232 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002233 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2234 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2235 ret = -EINVAL;
2236 goto exit;
2237 }
2238
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002239 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2240 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2241 {
2242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2243 "Neighbor scan results refresh period value %d is out of range"
2244 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2245 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2246 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2247 ret = -EINVAL;
2248 goto exit;
2249 }
2250 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2251
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2253 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002254 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002255
2256 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2257 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2258 }
2259 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2260 {
2261 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2262 char extra[32];
2263 tANI_U8 len = 0;
2264
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002265 len = scnprintf(extra, sizeof(extra), "%s %d",
2266 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002267 /* Returned value is in units of seconds */
2268 if (copy_to_user(priv_data.buf, &extra, len + 1))
2269 {
2270 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2271 "%s: failed to copy data to user buffer", __func__);
2272 ret = -EFAULT;
2273 goto exit;
2274 }
2275 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002276#ifdef FEATURE_WLAN_LFR
2277 /* SETROAMMODE */
2278 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2279 {
2280 tANI_U8 *value = command;
2281 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2282
2283 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2284 value = value + SIZE_OF_SETROAMMODE + 1;
2285
2286 /* Convert the value from ascii to integer */
2287 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2288 if (ret < 0)
2289 {
2290 /* If the input value is greater than max value of datatype, then also
2291 kstrtou8 fails */
2292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2293 "%s: kstrtou8 failed range [%d - %d]", __func__,
2294 CFG_LFR_FEATURE_ENABLED_MIN,
2295 CFG_LFR_FEATURE_ENABLED_MAX);
2296 ret = -EINVAL;
2297 goto exit;
2298 }
2299 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2300 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2301 {
2302 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2303 "Roam Mode value %d is out of range"
2304 " (Min: %d Max: %d)", roamMode,
2305 CFG_LFR_FEATURE_ENABLED_MIN,
2306 CFG_LFR_FEATURE_ENABLED_MAX);
2307 ret = -EINVAL;
2308 goto exit;
2309 }
2310
2311 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2312 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2313 /*
2314 * Note that
2315 * SETROAMMODE 0 is to enable LFR while
2316 * SETROAMMODE 1 is to disable LFR, but
2317 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2318 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2319 */
2320 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2321 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2322 else
2323 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2324
2325 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2326 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2327 }
2328 /* GETROAMMODE */
2329 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2330 {
2331 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2332 char extra[32];
2333 tANI_U8 len = 0;
2334
2335 /*
2336 * roamMode value shall be inverted because the sementics is different.
2337 */
2338 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2339 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2340 else
2341 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2342
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002343 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002344 if (copy_to_user(priv_data.buf, &extra, len + 1))
2345 {
2346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2347 "%s: failed to copy data to user buffer", __func__);
2348 ret = -EFAULT;
2349 goto exit;
2350 }
2351 }
2352#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002353#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002354#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002355 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2356 {
2357 tANI_U8 *value = command;
2358 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2359
2360 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2361 value = value + 13;
2362 /* Convert the value from ascii to integer */
2363 ret = kstrtou8(value, 10, &roamRssiDiff);
2364 if (ret < 0)
2365 {
2366 /* If the input value is greater than max value of datatype, then also
2367 kstrtou8 fails */
2368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2369 "%s: kstrtou8 failed range [%d - %d]", __func__,
2370 CFG_ROAM_RSSI_DIFF_MIN,
2371 CFG_ROAM_RSSI_DIFF_MAX);
2372 ret = -EINVAL;
2373 goto exit;
2374 }
2375
2376 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2377 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2378 {
2379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2380 "Roam rssi diff value %d is out of range"
2381 " (Min: %d Max: %d)", roamRssiDiff,
2382 CFG_ROAM_RSSI_DIFF_MIN,
2383 CFG_ROAM_RSSI_DIFF_MAX);
2384 ret = -EINVAL;
2385 goto exit;
2386 }
2387
2388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2389 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2390
2391 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2392 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2393 }
2394 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2395 {
2396 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2397 char extra[32];
2398 tANI_U8 len = 0;
2399
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302400 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2401 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2402 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002403 len = scnprintf(extra, sizeof(extra), "%s %d",
2404 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002405 if (copy_to_user(priv_data.buf, &extra, len + 1))
2406 {
2407 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2408 "%s: failed to copy data to user buffer", __func__);
2409 ret = -EFAULT;
2410 goto exit;
2411 }
2412 }
2413#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002414#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002415 else if (strncmp(command, "GETBAND", 7) == 0)
2416 {
2417 int band = -1;
2418 char extra[32];
2419 tANI_U8 len = 0;
2420 hdd_getBand_helper(pHddCtx, &band);
2421
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302422 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2423 TRACE_CODE_HDD_GETBAND_IOCTL,
2424 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002425 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002426 if (copy_to_user(priv_data.buf, &extra, len + 1))
2427 {
2428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2429 "%s: failed to copy data to user buffer", __func__);
2430 ret = -EFAULT;
2431 goto exit;
2432 }
2433 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002434 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2435 {
2436 tANI_U8 *value = command;
2437 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2438 tANI_U8 numChannels = 0;
2439 eHalStatus status = eHAL_STATUS_SUCCESS;
2440
2441 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2442 if (eHAL_STATUS_SUCCESS != status)
2443 {
2444 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2445 "%s: Failed to parse channel list information", __func__);
2446 ret = -EINVAL;
2447 goto exit;
2448 }
2449
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302450 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2451 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2452 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002453 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2454 {
2455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2456 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2457 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2458 ret = -EINVAL;
2459 goto exit;
2460 }
2461 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2462 numChannels);
2463 if (eHAL_STATUS_SUCCESS != status)
2464 {
2465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2466 "%s: Failed to update channel list information", __func__);
2467 ret = -EINVAL;
2468 goto exit;
2469 }
2470 }
2471 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2472 {
2473 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2474 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002475 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002476 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002477 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002478
2479 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2480 ChannelList, &numChannels ))
2481 {
2482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2483 "%s: failed to get roam scan channel list", __func__);
2484 ret = -EFAULT;
2485 goto exit;
2486 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302487 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2488 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2489 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002490 /* output channel list is of the format
2491 [Number of roam scan channels][Channel1][Channel2]... */
2492 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002493 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002494 for (j = 0; (j < numChannels); j++)
2495 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002496 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2497 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002498 }
2499
2500 if (copy_to_user(priv_data.buf, &extra, len + 1))
2501 {
2502 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2503 "%s: failed to copy data to user buffer", __func__);
2504 ret = -EFAULT;
2505 goto exit;
2506 }
2507 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002508 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2509 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002510 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002511 char extra[32];
2512 tANI_U8 len = 0;
2513
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002514 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002515 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002516 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002517 hdd_is_okc_mode_enabled(pHddCtx) &&
2518 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2519 {
2520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002521 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002522 " hence this operation is not permitted!", __func__);
2523 ret = -EPERM;
2524 goto exit;
2525 }
2526
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002527 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002528 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002529 if (copy_to_user(priv_data.buf, &extra, len + 1))
2530 {
2531 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2532 "%s: failed to copy data to user buffer", __func__);
2533 ret = -EFAULT;
2534 goto exit;
2535 }
2536 }
2537 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2538 {
2539 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2540 char extra[32];
2541 tANI_U8 len = 0;
2542
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002543 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002544 then this operation is not permitted (return FAILURE) */
2545 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002546 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002547 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2548 {
2549 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002550 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002551 " hence this operation is not permitted!", __func__);
2552 ret = -EPERM;
2553 goto exit;
2554 }
2555
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002556 len = scnprintf(extra, sizeof(extra), "%s %d",
2557 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002558 if (copy_to_user(priv_data.buf, &extra, len + 1))
2559 {
2560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2561 "%s: failed to copy data to user buffer", __func__);
2562 ret = -EFAULT;
2563 goto exit;
2564 }
2565 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002566 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002567 {
2568 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2569 char extra[32];
2570 tANI_U8 len = 0;
2571
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002572 len = scnprintf(extra, sizeof(extra), "%s %d",
2573 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002574 if (copy_to_user(priv_data.buf, &extra, len + 1))
2575 {
2576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2577 "%s: failed to copy data to user buffer", __func__);
2578 ret = -EFAULT;
2579 goto exit;
2580 }
2581 }
2582 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2583 {
2584 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2585 char extra[32];
2586 tANI_U8 len = 0;
2587
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002588 len = scnprintf(extra, sizeof(extra), "%s %d",
2589 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002590 if (copy_to_user(priv_data.buf, &extra, len + 1))
2591 {
2592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2593 "%s: failed to copy data to user buffer", __func__);
2594 ret = -EFAULT;
2595 goto exit;
2596 }
2597 }
2598 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2599 {
2600 tANI_U8 *value = command;
2601 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2602
2603 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2604 value = value + 26;
2605 /* Convert the value from ascii to integer */
2606 ret = kstrtou8(value, 10, &minTime);
2607 if (ret < 0)
2608 {
2609 /* If the input value is greater than max value of datatype, then also
2610 kstrtou8 fails */
2611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2612 "%s: kstrtou8 failed range [%d - %d]", __func__,
2613 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2614 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2615 ret = -EINVAL;
2616 goto exit;
2617 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002618 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2619 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2620 {
2621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2622 "scan min channel time value %d is out of range"
2623 " (Min: %d Max: %d)", minTime,
2624 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2625 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2626 ret = -EINVAL;
2627 goto exit;
2628 }
2629
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302630 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2631 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2632 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002633 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2634 "%s: Received Command to change channel min time = %d", __func__, minTime);
2635
2636 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2637 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2638 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002639 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2640 {
2641 tANI_U8 *value = command;
2642 tANI_U8 channel = 0;
2643 tANI_U8 dwellTime = 0;
2644 tANI_U8 bufLen = 0;
2645 tANI_U8 *buf = NULL;
2646 tSirMacAddr targetApBssid;
2647 eHalStatus status = eHAL_STATUS_SUCCESS;
2648 struct ieee80211_channel chan;
2649 tANI_U8 finalLen = 0;
2650 tANI_U8 *finalBuf = NULL;
2651 tANI_U8 temp = 0;
2652 u64 cookie;
2653 hdd_station_ctx_t *pHddStaCtx = NULL;
2654 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2655
2656 /* if not associated, no need to send action frame */
2657 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2658 {
2659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2660 ret = -EINVAL;
2661 goto exit;
2662 }
2663
2664 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2665 &dwellTime, &buf, &bufLen);
2666 if (eHAL_STATUS_SUCCESS != status)
2667 {
2668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2669 "%s: Failed to parse send action frame data", __func__);
2670 ret = -EINVAL;
2671 goto exit;
2672 }
2673
2674 /* if the target bssid is different from currently associated AP,
2675 then no need to send action frame */
2676 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2677 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2678 {
2679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2680 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002681 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002682 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002683 goto exit;
2684 }
2685
2686 /* if the channel number is different from operating channel then
2687 no need to send action frame */
2688 if (channel != pHddStaCtx->conn_info.operationChannel)
2689 {
2690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2691 "%s: channel(%d) is different from operating channel(%d)",
2692 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2693 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002694 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002695 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002696 goto exit;
2697 }
2698 chan.center_freq = sme_ChnToFreq(channel);
2699
2700 finalLen = bufLen + 24;
2701 finalBuf = vos_mem_malloc(finalLen);
2702 if (NULL == finalBuf)
2703 {
2704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2705 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002706 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002707 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002708 goto exit;
2709 }
2710 vos_mem_zero(finalBuf, finalLen);
2711
2712 /* Fill subtype */
2713 temp = SIR_MAC_MGMT_ACTION << 4;
2714 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2715
2716 /* Fill type */
2717 temp = SIR_MAC_MGMT_FRAME;
2718 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2719
2720 /* Fill destination address (bssid of the AP) */
2721 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2722
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002723 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002724 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
2725
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002726 /* Fill BSSID (AP mac address) */
2727 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002728
2729 /* Fill received buffer from 24th address */
2730 vos_mem_copy(finalBuf + 24, buf, bufLen);
2731
Jeff Johnson11c33152013-04-16 17:52:40 -07002732 /* done with the parsed buffer */
2733 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002734 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002735
DARAM SUDHA39eede62014-02-12 11:16:40 +05302736 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07002737#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2738 &(pAdapter->wdev),
2739#else
2740 dev,
2741#endif
2742 &chan, 0,
2743#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2744 NL80211_CHAN_HT20, 1,
2745#endif
2746 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002747 1, &cookie );
2748 vos_mem_free(finalBuf);
2749 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002750 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
2751 {
2752 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
2753 char extra[32];
2754 tANI_U8 len = 0;
2755
2756 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002757 len = scnprintf(extra, sizeof(extra), "%s %d",
2758 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302759 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2760 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
2761 pAdapter->sessionId, val));
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 }
2770 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
2771 {
2772 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002773 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002774
2775 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
2776 value = value + 19;
2777 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002778 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002779 if (ret < 0)
2780 {
2781 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002782 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002783 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002784 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002785 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2786 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2787 ret = -EINVAL;
2788 goto exit;
2789 }
2790
2791 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
2792 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
2793 {
2794 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2795 "lfr mode value %d is out of range"
2796 " (Min: %d Max: %d)", maxTime,
2797 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2798 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2799 ret = -EINVAL;
2800 goto exit;
2801 }
2802
2803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2804 "%s: Received Command to change channel max time = %d", __func__, maxTime);
2805
2806 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
2807 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
2808 }
2809 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
2810 {
2811 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
2812 char extra[32];
2813 tANI_U8 len = 0;
2814
2815 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002816 len = scnprintf(extra, sizeof(extra), "%s %d",
2817 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002818 if (copy_to_user(priv_data.buf, &extra, len + 1))
2819 {
2820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2821 "%s: failed to copy data to user buffer", __func__);
2822 ret = -EFAULT;
2823 goto exit;
2824 }
2825 }
2826 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
2827 {
2828 tANI_U8 *value = command;
2829 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
2830
2831 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
2832 value = value + 16;
2833 /* Convert the value from ascii to integer */
2834 ret = kstrtou16(value, 10, &val);
2835 if (ret < 0)
2836 {
2837 /* If the input value is greater than max value of datatype, then also
2838 kstrtou16 fails */
2839 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2840 "%s: kstrtou16 failed range [%d - %d]", __func__,
2841 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
2842 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
2843 ret = -EINVAL;
2844 goto exit;
2845 }
2846
2847 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
2848 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
2849 {
2850 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2851 "scan home time value %d is out of range"
2852 " (Min: %d Max: %d)", val,
2853 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
2854 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
2855 ret = -EINVAL;
2856 goto exit;
2857 }
2858
2859 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2860 "%s: Received Command to change scan home time = %d", __func__, val);
2861
2862 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
2863 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
2864 }
2865 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
2866 {
2867 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
2868 char extra[32];
2869 tANI_U8 len = 0;
2870
2871 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002872 len = scnprintf(extra, sizeof(extra), "%s %d",
2873 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002874 if (copy_to_user(priv_data.buf, &extra, len + 1))
2875 {
2876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2877 "%s: failed to copy data to user buffer", __func__);
2878 ret = -EFAULT;
2879 goto exit;
2880 }
2881 }
2882 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
2883 {
2884 tANI_U8 *value = command;
2885 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
2886
2887 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
2888 value = value + 17;
2889 /* Convert the value from ascii to integer */
2890 ret = kstrtou8(value, 10, &val);
2891 if (ret < 0)
2892 {
2893 /* If the input value is greater than max value of datatype, then also
2894 kstrtou8 fails */
2895 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2896 "%s: kstrtou8 failed range [%d - %d]", __func__,
2897 CFG_ROAM_INTRA_BAND_MIN,
2898 CFG_ROAM_INTRA_BAND_MAX);
2899 ret = -EINVAL;
2900 goto exit;
2901 }
2902
2903 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
2904 (val > CFG_ROAM_INTRA_BAND_MAX))
2905 {
2906 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2907 "intra band mode value %d is out of range"
2908 " (Min: %d Max: %d)", val,
2909 CFG_ROAM_INTRA_BAND_MIN,
2910 CFG_ROAM_INTRA_BAND_MAX);
2911 ret = -EINVAL;
2912 goto exit;
2913 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2915 "%s: Received Command to change intra band = %d", __func__, val);
2916
2917 pHddCtx->cfg_ini->nRoamIntraBand = val;
2918 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
2919 }
2920 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
2921 {
2922 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
2923 char extra[32];
2924 tANI_U8 len = 0;
2925
2926 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002927 len = scnprintf(extra, sizeof(extra), "%s %d",
2928 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002929 if (copy_to_user(priv_data.buf, &extra, len + 1))
2930 {
2931 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2932 "%s: failed to copy data to user buffer", __func__);
2933 ret = -EFAULT;
2934 goto exit;
2935 }
2936 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002937 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
2938 {
2939 tANI_U8 *value = command;
2940 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
2941
2942 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
2943 value = value + 15;
2944 /* Convert the value from ascii to integer */
2945 ret = kstrtou8(value, 10, &nProbes);
2946 if (ret < 0)
2947 {
2948 /* If the input value is greater than max value of datatype, then also
2949 kstrtou8 fails */
2950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2951 "%s: kstrtou8 failed range [%d - %d]", __func__,
2952 CFG_ROAM_SCAN_N_PROBES_MIN,
2953 CFG_ROAM_SCAN_N_PROBES_MAX);
2954 ret = -EINVAL;
2955 goto exit;
2956 }
2957
2958 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
2959 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
2960 {
2961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2962 "NProbes value %d is out of range"
2963 " (Min: %d Max: %d)", nProbes,
2964 CFG_ROAM_SCAN_N_PROBES_MIN,
2965 CFG_ROAM_SCAN_N_PROBES_MAX);
2966 ret = -EINVAL;
2967 goto exit;
2968 }
2969
2970 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2971 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
2972
2973 pHddCtx->cfg_ini->nProbes = nProbes;
2974 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
2975 }
2976 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
2977 {
2978 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
2979 char extra[32];
2980 tANI_U8 len = 0;
2981
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002982 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002983 if (copy_to_user(priv_data.buf, &extra, len + 1))
2984 {
2985 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2986 "%s: failed to copy data to user buffer", __func__);
2987 ret = -EFAULT;
2988 goto exit;
2989 }
2990 }
2991 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
2992 {
2993 tANI_U8 *value = command;
2994 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
2995
2996 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
2997 /* input value is in units of msec */
2998 value = value + 20;
2999 /* Convert the value from ascii to integer */
3000 ret = kstrtou16(value, 10, &homeAwayTime);
3001 if (ret < 0)
3002 {
3003 /* If the input value is greater than max value of datatype, then also
3004 kstrtou8 fails */
3005 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3006 "%s: kstrtou8 failed range [%d - %d]", __func__,
3007 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3008 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3009 ret = -EINVAL;
3010 goto exit;
3011 }
3012
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003013 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3014 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3015 {
3016 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3017 "homeAwayTime value %d is out of range"
3018 " (Min: %d Max: %d)", homeAwayTime,
3019 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3020 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3021 ret = -EINVAL;
3022 goto exit;
3023 }
3024
3025 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3026 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003027 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3028 {
3029 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3030 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3031 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003032 }
3033 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3034 {
3035 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3036 char extra[32];
3037 tANI_U8 len = 0;
3038
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003039 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003040 if (copy_to_user(priv_data.buf, &extra, len + 1))
3041 {
3042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3043 "%s: failed to copy data to user buffer", __func__);
3044 ret = -EFAULT;
3045 goto exit;
3046 }
3047 }
3048 else if (strncmp(command, "REASSOC", 7) == 0)
3049 {
3050 tANI_U8 *value = command;
3051 tANI_U8 channel = 0;
3052 tSirMacAddr targetApBssid;
3053 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003054#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3055 tCsrHandoffRequest handoffInfo;
3056#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003057 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003058 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3059
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003060 /* if not associated, no need to proceed with reassoc */
3061 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3062 {
3063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3064 ret = -EINVAL;
3065 goto exit;
3066 }
3067
3068 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3069 if (eHAL_STATUS_SUCCESS != status)
3070 {
3071 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3072 "%s: Failed to parse reassoc command data", __func__);
3073 ret = -EINVAL;
3074 goto exit;
3075 }
3076
3077 /* if the target bssid is same as currently associated AP,
3078 then no need to proceed with reassoc */
3079 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3080 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3081 {
3082 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3083 ret = -EINVAL;
3084 goto exit;
3085 }
3086
3087 /* Check channel number is a valid channel number */
3088 if(VOS_STATUS_SUCCESS !=
3089 wlan_hdd_validate_operation_channel(pAdapter, channel))
3090 {
3091 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003092 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003093 return -EINVAL;
3094 }
3095
3096 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003097#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3098 handoffInfo.channel = channel;
3099 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3100 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3101#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003102 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003103 else if (strncmp(command, "SETWESMODE", 10) == 0)
3104 {
3105 tANI_U8 *value = command;
3106 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3107
3108 /* Move pointer to ahead of SETWESMODE<delimiter> */
3109 value = value + 11;
3110 /* Convert the value from ascii to integer */
3111 ret = kstrtou8(value, 10, &wesMode);
3112 if (ret < 0)
3113 {
3114 /* If the input value is greater than max value of datatype, then also
3115 kstrtou8 fails */
3116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3117 "%s: kstrtou8 failed range [%d - %d]", __func__,
3118 CFG_ENABLE_WES_MODE_NAME_MIN,
3119 CFG_ENABLE_WES_MODE_NAME_MAX);
3120 ret = -EINVAL;
3121 goto exit;
3122 }
3123
3124 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3125 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3126 {
3127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3128 "WES Mode value %d is out of range"
3129 " (Min: %d Max: %d)", wesMode,
3130 CFG_ENABLE_WES_MODE_NAME_MIN,
3131 CFG_ENABLE_WES_MODE_NAME_MAX);
3132 ret = -EINVAL;
3133 goto exit;
3134 }
3135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3136 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3137
3138 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3139 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3140 }
3141 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3142 {
3143 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3144 char extra[32];
3145 tANI_U8 len = 0;
3146
Arif Hussain826d9412013-11-12 16:44:54 -08003147 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003148 if (copy_to_user(priv_data.buf, &extra, len + 1))
3149 {
3150 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3151 "%s: failed to copy data to user buffer", __func__);
3152 ret = -EFAULT;
3153 goto exit;
3154 }
3155 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003156#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003157#ifdef FEATURE_WLAN_LFR
3158 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3159 {
3160 tANI_U8 *value = command;
3161 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3162
3163 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3164 value = value + 12;
3165 /* Convert the value from ascii to integer */
3166 ret = kstrtou8(value, 10, &lfrMode);
3167 if (ret < 0)
3168 {
3169 /* If the input value is greater than max value of datatype, then also
3170 kstrtou8 fails */
3171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3172 "%s: kstrtou8 failed range [%d - %d]", __func__,
3173 CFG_LFR_FEATURE_ENABLED_MIN,
3174 CFG_LFR_FEATURE_ENABLED_MAX);
3175 ret = -EINVAL;
3176 goto exit;
3177 }
3178
3179 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3180 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3181 {
3182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3183 "lfr mode value %d is out of range"
3184 " (Min: %d Max: %d)", lfrMode,
3185 CFG_LFR_FEATURE_ENABLED_MIN,
3186 CFG_LFR_FEATURE_ENABLED_MAX);
3187 ret = -EINVAL;
3188 goto exit;
3189 }
3190
3191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3192 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3193
3194 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3195 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3196 }
3197#endif
3198#ifdef WLAN_FEATURE_VOWIFI_11R
3199 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3200 {
3201 tANI_U8 *value = command;
3202 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3203
3204 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3205 value = value + 18;
3206 /* Convert the value from ascii to integer */
3207 ret = kstrtou8(value, 10, &ft);
3208 if (ret < 0)
3209 {
3210 /* If the input value is greater than max value of datatype, then also
3211 kstrtou8 fails */
3212 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3213 "%s: kstrtou8 failed range [%d - %d]", __func__,
3214 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3215 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3216 ret = -EINVAL;
3217 goto exit;
3218 }
3219
3220 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3221 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3222 {
3223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3224 "ft mode value %d is out of range"
3225 " (Min: %d Max: %d)", ft,
3226 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3227 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3228 ret = -EINVAL;
3229 goto exit;
3230 }
3231
3232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3233 "%s: Received Command to change ft mode = %d", __func__, ft);
3234
3235 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3236 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3237 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303238
3239 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3240 {
3241 tANI_U8 *value = command;
3242 tSirMacAddr targetApBssid;
3243 tANI_U8 trigger = 0;
3244 eHalStatus status = eHAL_STATUS_SUCCESS;
3245 hdd_station_ctx_t *pHddStaCtx = NULL;
3246 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3247
3248 /* if not associated, no need to proceed with reassoc */
3249 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3250 {
3251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3252 ret = -EINVAL;
3253 goto exit;
3254 }
3255
3256 status = hdd_parse_reassoc_command_data(value, targetApBssid, &trigger);
3257 if (eHAL_STATUS_SUCCESS != status)
3258 {
3259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3260 "%s: Failed to parse reassoc command data", __func__);
3261 ret = -EINVAL;
3262 goto exit;
3263 }
3264
3265 /* if the target bssid is same as currently associated AP,
3266 then no need to proceed with reassoc */
3267 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3268 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3269 {
3270 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3271 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3272 __func__);
3273 ret = -EINVAL;
3274 goto exit;
3275 }
3276
3277 /* Proceed with scan/roam */
3278 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3279 &targetApBssid[0],
3280 (tSmeFastRoamTrigger)(trigger));
3281 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003282#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003283#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003284 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3285 {
3286 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003287 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003288
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003289 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003290 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003291 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003292 hdd_is_okc_mode_enabled(pHddCtx) &&
3293 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3294 {
3295 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003296 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003297 " hence this operation is not permitted!", __func__);
3298 ret = -EPERM;
3299 goto exit;
3300 }
3301
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003302 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3303 value = value + 11;
3304 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003305 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003306 if (ret < 0)
3307 {
3308 /* If the input value is greater than max value of datatype, then also
3309 kstrtou8 fails */
3310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3311 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003312 CFG_ESE_FEATURE_ENABLED_MIN,
3313 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003314 ret = -EINVAL;
3315 goto exit;
3316 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003317 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3318 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003319 {
3320 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003321 "Ese mode value %d is out of range"
3322 " (Min: %d Max: %d)", eseMode,
3323 CFG_ESE_FEATURE_ENABLED_MIN,
3324 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003325 ret = -EINVAL;
3326 goto exit;
3327 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003329 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003330
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003331 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3332 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003333 }
3334#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003335 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3336 {
3337 tANI_U8 *value = command;
3338 tANI_BOOLEAN roamScanControl = 0;
3339
3340 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3341 value = value + 19;
3342 /* Convert the value from ascii to integer */
3343 ret = kstrtou8(value, 10, &roamScanControl);
3344 if (ret < 0)
3345 {
3346 /* If the input value is greater than max value of datatype, then also
3347 kstrtou8 fails */
3348 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3349 "%s: kstrtou8 failed ", __func__);
3350 ret = -EINVAL;
3351 goto exit;
3352 }
3353
3354 if (0 != roamScanControl)
3355 {
3356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3357 "roam scan control invalid value = %d",
3358 roamScanControl);
3359 ret = -EINVAL;
3360 goto exit;
3361 }
3362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3363 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3364
3365 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3366 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003367#ifdef FEATURE_WLAN_OKC
3368 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3369 {
3370 tANI_U8 *value = command;
3371 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3372
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003373 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003374 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003375 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003376 hdd_is_okc_mode_enabled(pHddCtx) &&
3377 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3378 {
3379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003380 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003381 " hence this operation is not permitted!", __func__);
3382 ret = -EPERM;
3383 goto exit;
3384 }
3385
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003386 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3387 value = value + 11;
3388 /* Convert the value from ascii to integer */
3389 ret = kstrtou8(value, 10, &okcMode);
3390 if (ret < 0)
3391 {
3392 /* If the input value is greater than max value of datatype, then also
3393 kstrtou8 fails */
3394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3395 "%s: kstrtou8 failed range [%d - %d]", __func__,
3396 CFG_OKC_FEATURE_ENABLED_MIN,
3397 CFG_OKC_FEATURE_ENABLED_MAX);
3398 ret = -EINVAL;
3399 goto exit;
3400 }
3401
3402 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3403 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3404 {
3405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3406 "Okc mode value %d is out of range"
3407 " (Min: %d Max: %d)", okcMode,
3408 CFG_OKC_FEATURE_ENABLED_MIN,
3409 CFG_OKC_FEATURE_ENABLED_MAX);
3410 ret = -EINVAL;
3411 goto exit;
3412 }
3413
3414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3415 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3416
3417 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3418 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003419#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003420 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3421 {
3422 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3423 char extra[32];
3424 tANI_U8 len = 0;
3425
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003426 len = scnprintf(extra, sizeof(extra), "%s %d",
3427 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003428 if (copy_to_user(priv_data.buf, &extra, len + 1))
3429 {
3430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3431 "%s: failed to copy data to user buffer", __func__);
3432 ret = -EFAULT;
3433 goto exit;
3434 }
3435 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303436#ifdef WLAN_FEATURE_PACKET_FILTERING
3437 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3438 {
3439 tANI_U8 filterType = 0;
3440 tANI_U8 *value = command;
3441
3442 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3443 value = value + 22;
3444
3445 /* Convert the value from ascii to integer */
3446 ret = kstrtou8(value, 10, &filterType);
3447 if (ret < 0)
3448 {
3449 /* If the input value is greater than max value of datatype,
3450 * then also kstrtou8 fails
3451 */
3452 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3453 "%s: kstrtou8 failed range ", __func__);
3454 ret = -EINVAL;
3455 goto exit;
3456 }
3457
3458 if (filterType != 0 && filterType != 1)
3459 {
3460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3461 "%s: Accepted Values are 0 and 1 ", __func__);
3462 ret = -EINVAL;
3463 goto exit;
3464 }
3465 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3466 pAdapter->sessionId);
3467 }
3468#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303469 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3470 {
3471 char *dhcpPhase;
c_hpothu9b781ba2013-12-30 20:57:45 +05303472 dhcpPhase = command + 11;
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303473 if ('1' == *dhcpPhase)
3474 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu0b0cab72014-02-13 21:52:40 +05303476 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303477
3478 pHddCtx->btCoexModeSet = TRUE;
3479
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303480 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
c_hpothu0b0cab72014-02-13 21:52:40 +05303481 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303482 }
3483 else if ('2' == *dhcpPhase)
3484 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303485 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu0b0cab72014-02-13 21:52:40 +05303486 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303487
3488 pHddCtx->btCoexModeSet = FALSE;
3489
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303490 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
c_hpothu0b0cab72014-02-13 21:52:40 +05303491 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303492 }
3493 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003494 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3495 {
3496 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
3497 }
3498 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3499 {
3500 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
3501 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303502 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3503 {
3504 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3505 char extra[32];
3506 tANI_U8 len = 0;
3507
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003508 len = scnprintf(extra, sizeof(extra), "GETDWELLTIME %u\n",
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303509 (int)pCfg->nActiveMaxChnTime);
3510 if (copy_to_user(priv_data.buf, &extra, len + 1))
3511 {
3512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3513 "%s: failed to copy data to user buffer", __func__);
3514 ret = -EFAULT;
3515 goto exit;
3516 }
3517 ret = len;
3518 }
3519 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3520 {
3521 tANI_U8 *value = command;
3522 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3523 int val = 0, temp;
3524
3525 value = value + 13;
3526 temp = kstrtou32(value, 10, &val);
3527 if ( temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3528 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3529 {
3530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3531 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3532 ret = -EFAULT;
3533 goto exit;
3534 }
3535 pCfg->nActiveMaxChnTime = val;
3536 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003537 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3538 {
3539 tANI_U8 filterType = 0;
3540 tANI_U8 *value;
3541 value = command + 9;
3542
3543 /* Convert the value from ascii to integer */
3544 ret = kstrtou8(value, 10, &filterType);
3545 if (ret < 0)
3546 {
3547 /* If the input value is greater than max value of datatype,
3548 * then also kstrtou8 fails
3549 */
3550 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3551 "%s: kstrtou8 failed range ", __func__);
3552 ret = -EINVAL;
3553 goto exit;
3554 }
3555 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3556 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3557 {
3558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3559 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3560 " 2-Sink ", __func__);
3561 ret = -EINVAL;
3562 goto exit;
3563 }
3564 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3565 pHddCtx->drvr_miracast = filterType;
3566 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
3567 }
Leo Chang614d2072013-08-22 14:59:44 -07003568 else if (strncmp(command, "SETMCRATE", 9) == 0)
3569 {
Leo Chang614d2072013-08-22 14:59:44 -07003570 tANI_U8 *value = command;
3571 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003572 tSirRateUpdateInd *rateUpdate;
3573 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003574
3575 /* Only valid for SAP mode */
3576 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3577 {
3578 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3579 "%s: SAP mode is not running", __func__);
3580 ret = -EFAULT;
3581 goto exit;
3582 }
3583
3584 /* Move pointer to ahead of SETMCRATE<delimiter> */
3585 /* input value is in units of hundred kbps */
3586 value = value + 10;
3587 /* Convert the value from ascii to integer, decimal base */
3588 ret = kstrtouint(value, 10, &targetRate);
3589
Leo Chang1f98cbd2013-10-17 15:03:52 -07003590 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3591 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003592 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003593 hddLog(VOS_TRACE_LEVEL_ERROR,
3594 "%s: SETMCRATE indication alloc fail", __func__);
3595 ret = -EFAULT;
3596 goto exit;
3597 }
3598 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3599
3600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3601 "MC Target rate %d", targetRate);
3602 /* Ignore unicast */
3603 rateUpdate->ucastDataRate = -1;
3604 rateUpdate->mcastDataRate24GHz = targetRate;
3605 rateUpdate->mcastDataRate5GHz = targetRate;
3606 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3607 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3608 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3609 if (eHAL_STATUS_SUCCESS != status)
3610 {
3611 hddLog(VOS_TRACE_LEVEL_ERROR,
3612 "%s: SET_MC_RATE failed", __func__);
3613 vos_mem_free(rateUpdate);
3614 ret = -EFAULT;
3615 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003616 }
3617 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303618#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003619 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303620 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003621 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303622 }
3623#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003624#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003625 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3626 {
3627 tANI_U8 *value = command;
3628 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3629 tANI_U8 numChannels = 0;
3630 eHalStatus status = eHAL_STATUS_SUCCESS;
3631
3632 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3633 if (eHAL_STATUS_SUCCESS != status)
3634 {
3635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3636 "%s: Failed to parse channel list information", __func__);
3637 ret = -EINVAL;
3638 goto exit;
3639 }
3640
3641 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3642 {
3643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3644 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3645 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3646 ret = -EINVAL;
3647 goto exit;
3648 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003649 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003650 ChannelList,
3651 numChannels);
3652 if (eHAL_STATUS_SUCCESS != status)
3653 {
3654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3655 "%s: Failed to update channel list information", __func__);
3656 ret = -EINVAL;
3657 goto exit;
3658 }
3659 }
3660 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3661 {
3662 tANI_U8 *value = command;
3663 char extra[128] = {0};
3664 int len = 0;
3665 tANI_U8 tid = 0;
3666 hdd_station_ctx_t *pHddStaCtx = NULL;
3667 tAniTrafStrmMetrics tsmMetrics;
3668 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3669
3670 /* if not associated, return error */
3671 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3672 {
3673 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3674 ret = -EINVAL;
3675 goto exit;
3676 }
3677
3678 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3679 value = value + 12;
3680 /* Convert the value from ascii to integer */
3681 ret = kstrtou8(value, 10, &tid);
3682 if (ret < 0)
3683 {
3684 /* If the input value is greater than max value of datatype, then also
3685 kstrtou8 fails */
3686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3687 "%s: kstrtou8 failed range [%d - %d]", __func__,
3688 TID_MIN_VALUE,
3689 TID_MAX_VALUE);
3690 ret = -EINVAL;
3691 goto exit;
3692 }
3693
3694 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
3695 {
3696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3697 "tid value %d is out of range"
3698 " (Min: %d Max: %d)", tid,
3699 TID_MIN_VALUE,
3700 TID_MAX_VALUE);
3701 ret = -EINVAL;
3702 goto exit;
3703 }
3704
3705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3706 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
3707
3708 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
3709 {
3710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3711 "%s: failed to get tsm stats", __func__);
3712 ret = -EFAULT;
3713 goto exit;
3714 }
3715
3716 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3717 "UplinkPktQueueDly(%d)\n"
3718 "UplinkPktQueueDlyHist[0](%d)\n"
3719 "UplinkPktQueueDlyHist[1](%d)\n"
3720 "UplinkPktQueueDlyHist[2](%d)\n"
3721 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05303722 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003723 "UplinkPktLoss(%d)\n"
3724 "UplinkPktCount(%d)\n"
3725 "RoamingCount(%d)\n"
3726 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
3727 tsmMetrics.UplinkPktQueueDlyHist[0],
3728 tsmMetrics.UplinkPktQueueDlyHist[1],
3729 tsmMetrics.UplinkPktQueueDlyHist[2],
3730 tsmMetrics.UplinkPktQueueDlyHist[3],
3731 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
3732 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
3733
3734 /* Output TSM stats is of the format
3735 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
3736 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003737 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003738 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
3739 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
3740 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
3741 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
3742 tsmMetrics.RoamingDly);
3743
3744 if (copy_to_user(priv_data.buf, &extra, len + 1))
3745 {
3746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3747 "%s: failed to copy data to user buffer", __func__);
3748 ret = -EFAULT;
3749 goto exit;
3750 }
3751 }
3752 else if (strncmp(command, "SETCCKMIE", 9) == 0)
3753 {
3754 tANI_U8 *value = command;
3755 tANI_U8 *cckmIe = NULL;
3756 tANI_U8 cckmIeLen = 0;
3757 eHalStatus status = eHAL_STATUS_SUCCESS;
3758
3759 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
3760 if (eHAL_STATUS_SUCCESS != status)
3761 {
3762 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3763 "%s: Failed to parse cckm ie data", __func__);
3764 ret = -EINVAL;
3765 goto exit;
3766 }
3767
3768 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
3769 {
3770 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3771 "%s: CCKM Ie input length is more than max[%d]", __func__,
3772 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003773 vos_mem_free(cckmIe);
3774 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003775 ret = -EINVAL;
3776 goto exit;
3777 }
3778 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003779 vos_mem_free(cckmIe);
3780 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003781 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003782 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
3783 {
3784 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003785 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003786 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003787 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003788 if (eHAL_STATUS_SUCCESS != status)
3789 {
3790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003791 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003792 ret = -EINVAL;
3793 goto exit;
3794 }
3795
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003796 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
3797 if (eHAL_STATUS_SUCCESS != status)
3798 {
3799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3800 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
3801 ret = -EINVAL;
3802 goto exit;
3803 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003804 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003805#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003806 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303807 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3808 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
3809 pAdapter->sessionId, 0));
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003810 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s",
3811 __func__, command);
3812 }
3813
Jeff Johnson295189b2012-06-20 16:38:30 -07003814 }
3815exit:
3816 if (command)
3817 {
3818 kfree(command);
3819 }
3820 return ret;
3821}
3822
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003823
3824
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003825#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003826/**---------------------------------------------------------------------------
3827
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003828 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003829
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003830 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003831 CCXBEACONREQ<space><Number of fields><space><Measurement token>
3832 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
3833 <space>Scan Mode N<space>Meas Duration N
3834 if the Number of bcn req fields (N) does not match with the actual number of fields passed
3835 then take N.
3836 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
3837 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
3838 This function does not take care of removing duplicate channels from the list
3839
3840 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003841 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003842
3843 \return - 0 for success non-zero for failure
3844
3845 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003846static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
3847 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003848{
3849 tANI_U8 *inPtr = pValue;
3850 int tempInt = 0;
3851 int j = 0, i = 0, v = 0;
3852 char buf[32];
3853
3854 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
3855 /*no argument after the command*/
3856 if (NULL == inPtr)
3857 {
3858 return -EINVAL;
3859 }
3860 /*no space after the command*/
3861 else if (SPACE_ASCII_VALUE != *inPtr)
3862 {
3863 return -EINVAL;
3864 }
3865
3866 /*removing empty spaces*/
3867 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
3868
3869 /*no argument followed by spaces*/
3870 if ('\0' == *inPtr) return -EINVAL;
3871
3872 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08003873 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003874 if (1 != v) return -EINVAL;
3875
3876 v = kstrtos32(buf, 10, &tempInt);
3877 if ( v < 0) return -EINVAL;
3878
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003879 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003880
3881 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003882 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003883
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003884 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003885 {
3886 for (i = 0; i < 4; i++)
3887 {
3888 /*inPtr pointing to the beginning of first space after number of ie fields*/
3889 inPtr = strpbrk( inPtr, " " );
3890 /*no ie data after the number of ie fields argument*/
3891 if (NULL == inPtr) return -EINVAL;
3892
3893 /*removing empty space*/
3894 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
3895
3896 /*no ie data after the number of ie fields argument and spaces*/
3897 if ( '\0' == *inPtr ) return -EINVAL;
3898
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08003899 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003900 if (1 != v) return -EINVAL;
3901
3902 v = kstrtos32(buf, 10, &tempInt);
3903 if (v < 0) return -EINVAL;
3904
3905 switch (i)
3906 {
3907 case 0: /* Measurement token */
3908 if (tempInt <= 0)
3909 {
3910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3911 "Invalid Measurement Token(%d)", tempInt);
3912 return -EINVAL;
3913 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003914 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003915 break;
3916
3917 case 1: /* Channel number */
3918 if ((tempInt <= 0) ||
3919 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
3920 {
3921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3922 "Invalid Channel Number(%d)", tempInt);
3923 return -EINVAL;
3924 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003925 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003926 break;
3927
3928 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08003929 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003930 {
3931 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3932 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
3933 return -EINVAL;
3934 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003935 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003936 break;
3937
3938 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003939 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
3940 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003941 {
3942 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3943 "Invalid Measurement Duration(%d)", tempInt);
3944 return -EINVAL;
3945 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003946 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003947 break;
3948 }
3949 }
3950 }
3951
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003952 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003953 {
3954 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05303955 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003956 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003957 pEseBcnReq->bcnReq[j].measurementToken,
3958 pEseBcnReq->bcnReq[j].channel,
3959 pEseBcnReq->bcnReq[j].scanMode,
3960 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003961 }
3962
3963 return VOS_STATUS_SUCCESS;
3964}
3965
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003966static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
3967{
3968 struct statsContext *pStatsContext = NULL;
3969 hdd_adapter_t *pAdapter = NULL;
3970
3971 if (NULL == pContext)
3972 {
3973 hddLog(VOS_TRACE_LEVEL_ERROR,
3974 "%s: Bad param, pContext [%p]",
3975 __func__, pContext);
3976 return;
3977 }
3978
Jeff Johnson72a40512013-12-19 10:14:15 -08003979 /* there is a race condition that exists between this callback
3980 function and the caller since the caller could time out either
3981 before or while this code is executing. we use a spinlock to
3982 serialize these actions */
3983 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003984
3985 pStatsContext = pContext;
3986 pAdapter = pStatsContext->pAdapter;
3987 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
3988 {
3989 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08003990 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003991 hddLog(VOS_TRACE_LEVEL_WARN,
3992 "%s: Invalid context, pAdapter [%p] magic [%08x]",
3993 __func__, pAdapter, pStatsContext->magic);
3994 return;
3995 }
3996
Jeff Johnson72a40512013-12-19 10:14:15 -08003997 /* context is valid so caller is still waiting */
3998
3999 /* paranoia: invalidate the magic */
4000 pStatsContext->magic = 0;
4001
4002 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004003 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4004 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4005 tsmMetrics.UplinkPktQueueDlyHist,
4006 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4007 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4008 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4009 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4010 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4011 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4012 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4013
Jeff Johnson72a40512013-12-19 10:14:15 -08004014 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004015 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004016
4017 /* serialization is complete */
4018 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004019}
4020
4021
4022
4023static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4024 tAniTrafStrmMetrics* pTsmMetrics)
4025{
4026 hdd_station_ctx_t *pHddStaCtx = NULL;
4027 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004028 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004029 long lrc;
4030 struct statsContext context;
4031 hdd_context_t *pHddCtx = NULL;
4032
4033 if (NULL == pAdapter)
4034 {
4035 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4036 return VOS_STATUS_E_FAULT;
4037 }
4038
4039 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4040 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4041
4042 /* we are connected prepare our callback context */
4043 init_completion(&context.completion);
4044 context.pAdapter = pAdapter;
4045 context.magic = STATS_CONTEXT_MAGIC;
4046
4047 /* query tsm stats */
4048 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4049 pHddStaCtx->conn_info.staId[ 0 ],
4050 pHddStaCtx->conn_info.bssId,
4051 &context, pHddCtx->pvosContext, tid);
4052
4053 if (eHAL_STATUS_SUCCESS != hstatus)
4054 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004055 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4056 __func__);
4057 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004058 }
4059 else
4060 {
4061 /* request was sent -- wait for the response */
4062 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4063 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004064 if (lrc <= 0)
4065 {
4066 hddLog(VOS_TRACE_LEVEL_ERROR,
4067 "%s: SME %s while retrieving statistics",
4068 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004069 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004070 }
4071 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004072
Jeff Johnson72a40512013-12-19 10:14:15 -08004073 /* either we never sent a request, we sent a request and received a
4074 response or we sent a request and timed out. if we never sent a
4075 request or if we sent a request and got a response, we want to
4076 clear the magic out of paranoia. if we timed out there is a
4077 race condition such that the callback function could be
4078 executing at the same time we are. of primary concern is if the
4079 callback function had already verified the "magic" but had not
4080 yet set the completion variable when a timeout occurred. we
4081 serialize these activities by invalidating the magic while
4082 holding a shared spinlock which will cause us to block if the
4083 callback is currently executing */
4084 spin_lock(&hdd_context_lock);
4085 context.magic = 0;
4086 spin_unlock(&hdd_context_lock);
4087
4088 if (VOS_STATUS_SUCCESS == vstatus)
4089 {
4090 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4091 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4092 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4093 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4094 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4095 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4096 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4097 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4098 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4099 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4100 }
4101 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004102}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004103#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004104
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004105#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004106void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4107{
4108 eCsrBand band = -1;
4109 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4110 switch (band)
4111 {
4112 case eCSR_BAND_ALL:
4113 *pBand = WLAN_HDD_UI_BAND_AUTO;
4114 break;
4115
4116 case eCSR_BAND_24:
4117 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4118 break;
4119
4120 case eCSR_BAND_5G:
4121 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4122 break;
4123
4124 default:
4125 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4126 *pBand = -1;
4127 break;
4128 }
4129}
4130
4131/**---------------------------------------------------------------------------
4132
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004133 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4134
4135 This function parses the send action frame data passed in the format
4136 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4137
Srinivas Girigowda56076852013-08-20 14:00:50 -07004138 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004139 \param - pTargetApBssid Pointer to target Ap bssid
4140 \param - pChannel Pointer to the Target AP channel
4141 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4142 \param - pBuf Pointer to data
4143 \param - pBufLen Pointer to data length
4144
4145 \return - 0 for success non-zero for failure
4146
4147 --------------------------------------------------------------------------*/
4148VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4149 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4150{
4151 tANI_U8 *inPtr = pValue;
4152 tANI_U8 *dataEnd;
4153 int tempInt;
4154 int j = 0;
4155 int i = 0;
4156 int v = 0;
4157 tANI_U8 tempBuf[32];
4158 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004159 /* 12 hexa decimal digits, 5 ':' and '\0' */
4160 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004161
4162 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4163 /*no argument after the command*/
4164 if (NULL == inPtr)
4165 {
4166 return -EINVAL;
4167 }
4168
4169 /*no space after the command*/
4170 else if (SPACE_ASCII_VALUE != *inPtr)
4171 {
4172 return -EINVAL;
4173 }
4174
4175 /*removing empty spaces*/
4176 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4177
4178 /*no argument followed by spaces*/
4179 if ('\0' == *inPtr)
4180 {
4181 return -EINVAL;
4182 }
4183
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004184 v = sscanf(inPtr, "%17s", macAddress);
4185 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004186 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4188 "Invalid MAC address or All hex inputs are not read (%d)", v);
4189 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004190 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004191
4192 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4193 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4194 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4195 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4196 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4197 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004198
4199 /* point to the next argument */
4200 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4201 /*no argument after the command*/
4202 if (NULL == inPtr) return -EINVAL;
4203
4204 /*removing empty spaces*/
4205 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4206
4207 /*no argument followed by spaces*/
4208 if ('\0' == *inPtr)
4209 {
4210 return -EINVAL;
4211 }
4212
4213 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004214 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004215 if (1 != v) return -EINVAL;
4216
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004217 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashishc0126762014-02-17 19:30:26 +05304218 if ( v < 0 || tempInt < 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304219 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004220
4221 *pChannel = tempInt;
4222
4223 /* point to the next argument */
4224 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4225 /*no argument after the command*/
4226 if (NULL == inPtr) return -EINVAL;
4227 /*removing empty spaces*/
4228 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4229
4230 /*no argument followed by spaces*/
4231 if ('\0' == *inPtr)
4232 {
4233 return -EINVAL;
4234 }
4235
4236 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004237 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004238 if (1 != v) return -EINVAL;
4239
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004240 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004241 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004242
4243 *pDwellTime = tempInt;
4244
4245 /* point to the next argument */
4246 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4247 /*no argument after the command*/
4248 if (NULL == inPtr) return -EINVAL;
4249 /*removing empty spaces*/
4250 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4251
4252 /*no argument followed by spaces*/
4253 if ('\0' == *inPtr)
4254 {
4255 return -EINVAL;
4256 }
4257
4258 /* find the length of data */
4259 dataEnd = inPtr;
4260 while(('\0' != *dataEnd) )
4261 {
4262 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004263 }
Kiet Lambe150c22013-11-21 16:30:32 +05304264 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004265 if ( *pBufLen <= 0) return -EINVAL;
4266
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004267 /* Allocate the number of bytes based on the number of input characters
4268 whether it is even or odd.
4269 if the number of input characters are even, then we need N/2 byte.
4270 if the number of input characters are odd, then we need do (N+1)/2 to
4271 compensate rounding off.
4272 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4273 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4274 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004275 if (NULL == *pBuf)
4276 {
4277 hddLog(VOS_TRACE_LEVEL_FATAL,
4278 "%s: vos_mem_alloc failed ", __func__);
4279 return -EINVAL;
4280 }
4281
4282 /* the buffer received from the upper layer is character buffer,
4283 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4284 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4285 and f0 in 3rd location */
4286 for (i = 0, j = 0; j < *pBufLen; j += 2)
4287 {
Kiet Lambe150c22013-11-21 16:30:32 +05304288 if( j+1 == *pBufLen)
4289 {
4290 tempByte = hdd_parse_hex(inPtr[j]);
4291 }
4292 else
4293 {
4294 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4295 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004296 (*pBuf)[i++] = tempByte;
4297 }
4298 *pBufLen = i;
4299 return VOS_STATUS_SUCCESS;
4300}
4301
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004302/**---------------------------------------------------------------------------
4303
Srinivas Girigowdade697412013-02-14 16:31:48 -08004304 \brief hdd_parse_channellist() - HDD Parse channel list
4305
4306 This function parses the channel list passed in the format
4307 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004308 if the Number of channels (N) does not match with the actual number of channels passed
4309 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4310 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4311 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4312 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004313
4314 \param - pValue Pointer to input channel list
4315 \param - ChannelList Pointer to local output array to record channel list
4316 \param - pNumChannels Pointer to number of roam scan channels
4317
4318 \return - 0 for success non-zero for failure
4319
4320 --------------------------------------------------------------------------*/
4321VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4322{
4323 tANI_U8 *inPtr = pValue;
4324 int tempInt;
4325 int j = 0;
4326 int v = 0;
4327 char buf[32];
4328
4329 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4330 /*no argument after the command*/
4331 if (NULL == inPtr)
4332 {
4333 return -EINVAL;
4334 }
4335
4336 /*no space after the command*/
4337 else if (SPACE_ASCII_VALUE != *inPtr)
4338 {
4339 return -EINVAL;
4340 }
4341
4342 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004343 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004344
4345 /*no argument followed by spaces*/
4346 if ('\0' == *inPtr)
4347 {
4348 return -EINVAL;
4349 }
4350
4351 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004352 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004353 if (1 != v) return -EINVAL;
4354
Srinivas Girigowdade697412013-02-14 16:31:48 -08004355 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004356 if ((v < 0) ||
4357 (tempInt <= 0) ||
4358 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4359 {
4360 return -EINVAL;
4361 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004362
4363 *pNumChannels = tempInt;
4364
4365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4366 "Number of channels are: %d", *pNumChannels);
4367
4368 for (j = 0; j < (*pNumChannels); j++)
4369 {
4370 /*inPtr pointing to the beginning of first space after number of channels*/
4371 inPtr = strpbrk( inPtr, " " );
4372 /*no channel list after the number of channels argument*/
4373 if (NULL == inPtr)
4374 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004375 if (0 != j)
4376 {
4377 *pNumChannels = j;
4378 return VOS_STATUS_SUCCESS;
4379 }
4380 else
4381 {
4382 return -EINVAL;
4383 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004384 }
4385
4386 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004387 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004388
4389 /*no channel list after the number of channels argument and spaces*/
4390 if ( '\0' == *inPtr )
4391 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004392 if (0 != j)
4393 {
4394 *pNumChannels = j;
4395 return VOS_STATUS_SUCCESS;
4396 }
4397 else
4398 {
4399 return -EINVAL;
4400 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004401 }
4402
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004403 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004404 if (1 != v) return -EINVAL;
4405
Srinivas Girigowdade697412013-02-14 16:31:48 -08004406 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004407 if ((v < 0) ||
4408 (tempInt <= 0) ||
4409 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4410 {
4411 return -EINVAL;
4412 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004413 pChannelList[j] = tempInt;
4414
4415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4416 "Channel %d added to preferred channel list",
4417 pChannelList[j] );
4418 }
4419
Srinivas Girigowdade697412013-02-14 16:31:48 -08004420 return VOS_STATUS_SUCCESS;
4421}
4422
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004423
4424/**---------------------------------------------------------------------------
4425
4426 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
4427
4428 This function parses the reasoc command data passed in the format
4429 REASSOC<space><bssid><space><channel>
4430
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004431 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004432 \param - pTargetApBssid Pointer to target Ap bssid
4433 \param - pChannel Pointer to the Target AP channel
4434
4435 \return - 0 for success non-zero for failure
4436
4437 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004438VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
4439 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004440{
4441 tANI_U8 *inPtr = pValue;
4442 int tempInt;
4443 int v = 0;
4444 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08004445 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004446 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004447
4448 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4449 /*no argument after the command*/
4450 if (NULL == inPtr)
4451 {
4452 return -EINVAL;
4453 }
4454
4455 /*no space after the command*/
4456 else if (SPACE_ASCII_VALUE != *inPtr)
4457 {
4458 return -EINVAL;
4459 }
4460
4461 /*removing empty spaces*/
4462 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4463
4464 /*no argument followed by spaces*/
4465 if ('\0' == *inPtr)
4466 {
4467 return -EINVAL;
4468 }
4469
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004470 v = sscanf(inPtr, "%17s", macAddress);
4471 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004472 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4474 "Invalid MAC address or All hex inputs are not read (%d)", v);
4475 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004476 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004477
4478 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4479 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4480 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4481 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4482 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4483 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004484
4485 /* point to the next argument */
4486 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4487 /*no argument after the command*/
4488 if (NULL == inPtr) return -EINVAL;
4489
4490 /*removing empty spaces*/
4491 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4492
4493 /*no argument followed by spaces*/
4494 if ('\0' == *inPtr)
4495 {
4496 return -EINVAL;
4497 }
4498
4499 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004500 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004501 if (1 != v) return -EINVAL;
4502
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004503 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004504 if ((v < 0) ||
4505 (tempInt <= 0) ||
4506 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4507 {
4508 return -EINVAL;
4509 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004510
4511 *pChannel = tempInt;
4512 return VOS_STATUS_SUCCESS;
4513}
4514
4515#endif
4516
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004517#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004518/**---------------------------------------------------------------------------
4519
4520 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
4521
4522 This function parses the SETCCKM IE command
4523 SETCCKMIE<space><ie data>
4524
4525 \param - pValue Pointer to input data
4526 \param - pCckmIe Pointer to output cckm Ie
4527 \param - pCckmIeLen Pointer to output cckm ie length
4528
4529 \return - 0 for success non-zero for failure
4530
4531 --------------------------------------------------------------------------*/
4532VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
4533 tANI_U8 *pCckmIeLen)
4534{
4535 tANI_U8 *inPtr = pValue;
4536 tANI_U8 *dataEnd;
4537 int j = 0;
4538 int i = 0;
4539 tANI_U8 tempByte = 0;
4540
4541 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4542 /*no argument after the command*/
4543 if (NULL == inPtr)
4544 {
4545 return -EINVAL;
4546 }
4547
4548 /*no space after the command*/
4549 else if (SPACE_ASCII_VALUE != *inPtr)
4550 {
4551 return -EINVAL;
4552 }
4553
4554 /*removing empty spaces*/
4555 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4556
4557 /*no argument followed by spaces*/
4558 if ('\0' == *inPtr)
4559 {
4560 return -EINVAL;
4561 }
4562
4563 /* find the length of data */
4564 dataEnd = inPtr;
4565 while(('\0' != *dataEnd) )
4566 {
4567 dataEnd++;
4568 ++(*pCckmIeLen);
4569 }
4570 if ( *pCckmIeLen <= 0) return -EINVAL;
4571
4572 /* Allocate the number of bytes based on the number of input characters
4573 whether it is even or odd.
4574 if the number of input characters are even, then we need N/2 byte.
4575 if the number of input characters are odd, then we need do (N+1)/2 to
4576 compensate rounding off.
4577 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4578 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4579 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
4580 if (NULL == *pCckmIe)
4581 {
4582 hddLog(VOS_TRACE_LEVEL_FATAL,
4583 "%s: vos_mem_alloc failed ", __func__);
4584 return -EINVAL;
4585 }
4586 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
4587 /* the buffer received from the upper layer is character buffer,
4588 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4589 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4590 and f0 in 3rd location */
4591 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
4592 {
4593 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4594 (*pCckmIe)[i++] = tempByte;
4595 }
4596 *pCckmIeLen = i;
4597
4598 return VOS_STATUS_SUCCESS;
4599}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004600#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004601
Jeff Johnson295189b2012-06-20 16:38:30 -07004602/**---------------------------------------------------------------------------
4603
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004604 \brief hdd_is_valid_mac_address() - Validate MAC address
4605
4606 This function validates whether the given MAC address is valid or not
4607 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
4608 where X is the hexa decimal digit character and separated by ':'
4609 This algorithm works even if MAC address is not separated by ':'
4610
4611 This code checks given input string mac contains exactly 12 hexadecimal digits.
4612 and a separator colon : appears in the input string only after
4613 an even number of hex digits.
4614
4615 \param - pMacAddr pointer to the input MAC address
4616 \return - 1 for valid and 0 for invalid
4617
4618 --------------------------------------------------------------------------*/
4619
4620v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
4621{
4622 int xdigit = 0;
4623 int separator = 0;
4624 while (*pMacAddr)
4625 {
4626 if (isxdigit(*pMacAddr))
4627 {
4628 xdigit++;
4629 }
4630 else if (':' == *pMacAddr)
4631 {
4632 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
4633 break;
4634
4635 ++separator;
4636 }
4637 else
4638 {
4639 separator = -1;
4640 /* Invalid MAC found */
4641 return 0;
4642 }
4643 ++pMacAddr;
4644 }
4645 return (xdigit == 12 && (separator == 5 || separator == 0));
4646}
4647
4648/**---------------------------------------------------------------------------
4649
Jeff Johnson295189b2012-06-20 16:38:30 -07004650 \brief hdd_open() - HDD Open function
4651
4652 This is called in response to ifconfig up
4653
4654 \param - dev Pointer to net_device structure
4655
4656 \return - 0 for success non-zero for failure
4657
4658 --------------------------------------------------------------------------*/
4659int hdd_open (struct net_device *dev)
4660{
4661 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4662 hdd_context_t *pHddCtx;
4663 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4664 VOS_STATUS status;
4665 v_BOOL_t in_standby = TRUE;
4666
4667 if (NULL == pAdapter)
4668 {
4669 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05304670 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004671 return -ENODEV;
4672 }
4673
4674 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304675 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
4676 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07004677 if (NULL == pHddCtx)
4678 {
4679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004680 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004681 return -ENODEV;
4682 }
4683
4684 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4685 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
4686 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004687 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
4688 {
4689 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05304690 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004691 in_standby = FALSE;
4692 break;
4693 }
4694 else
4695 {
4696 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4697 pAdapterNode = pNext;
4698 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004699 }
4700
4701 if (TRUE == in_standby)
4702 {
4703 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
4704 {
4705 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
4706 "wlan out of power save", __func__);
4707 return -EINVAL;
4708 }
4709 }
4710
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004711 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07004712 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
4713 {
4714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004715 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004716 /* Enable TX queues only when we are connected */
4717 netif_tx_start_all_queues(dev);
4718 }
4719
4720 return 0;
4721}
4722
4723int hdd_mon_open (struct net_device *dev)
4724{
4725 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4726
4727 if(pAdapter == NULL) {
4728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004729 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08004730 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004731 }
4732
4733 netif_start_queue(dev);
4734
4735 return 0;
4736}
4737/**---------------------------------------------------------------------------
4738
4739 \brief hdd_stop() - HDD stop function
4740
4741 This is called in response to ifconfig down
4742
4743 \param - dev Pointer to net_device structure
4744
4745 \return - 0 for success non-zero for failure
4746
4747 --------------------------------------------------------------------------*/
4748
4749int hdd_stop (struct net_device *dev)
4750{
4751 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4752 hdd_context_t *pHddCtx;
4753 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4754 VOS_STATUS status;
4755 v_BOOL_t enter_standby = TRUE;
4756
4757 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07004758 if (NULL == pAdapter)
4759 {
4760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05304761 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004762 return -ENODEV;
4763 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304764 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
4765 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07004766 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
4767 if (NULL == pHddCtx)
4768 {
4769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004770 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004771 return -ENODEV;
4772 }
4773
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004774 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07004775 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
4776 netif_tx_disable(pAdapter->dev);
4777 netif_carrier_off(pAdapter->dev);
4778
4779
4780 /* SoftAP ifaces should never go in power save mode
4781 making sure same here. */
4782 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
4783 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07004784 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07004785 )
4786 {
4787 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304788 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4789 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004790 EXIT();
4791 return 0;
4792 }
4793
4794 /* Find if any iface is up then
4795 if any iface is up then can't put device to sleep/ power save mode. */
4796 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4797 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
4798 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004799 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
4800 {
4801 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05304802 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004803 enter_standby = FALSE;
4804 break;
4805 }
4806 else
4807 {
4808 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4809 pAdapterNode = pNext;
4810 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004811 }
4812
4813 if (TRUE == enter_standby)
4814 {
4815 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
4816 "entering standby", __func__);
4817 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
4818 {
4819 /*log and return success*/
4820 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
4821 "wlan in power save", __func__);
4822 }
4823 }
4824
4825 EXIT();
4826 return 0;
4827}
4828
4829/**---------------------------------------------------------------------------
4830
4831 \brief hdd_uninit() - HDD uninit function
4832
4833 This is called during the netdev unregister to uninitialize all data
4834associated with the device
4835
4836 \param - dev Pointer to net_device structure
4837
4838 \return - void
4839
4840 --------------------------------------------------------------------------*/
4841static void hdd_uninit (struct net_device *dev)
4842{
4843 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4844
4845 ENTER();
4846
4847 do
4848 {
4849 if (NULL == pAdapter)
4850 {
4851 hddLog(VOS_TRACE_LEVEL_FATAL,
4852 "%s: NULL pAdapter", __func__);
4853 break;
4854 }
4855
4856 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
4857 {
4858 hddLog(VOS_TRACE_LEVEL_FATAL,
4859 "%s: Invalid magic", __func__);
4860 break;
4861 }
4862
4863 if (NULL == pAdapter->pHddCtx)
4864 {
4865 hddLog(VOS_TRACE_LEVEL_FATAL,
4866 "%s: NULL pHddCtx", __func__);
4867 break;
4868 }
4869
4870 if (dev != pAdapter->dev)
4871 {
4872 hddLog(VOS_TRACE_LEVEL_FATAL,
4873 "%s: Invalid device reference", __func__);
4874 /* we haven't validated all cases so let this go for now */
4875 }
4876
4877 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
4878
4879 /* after uninit our adapter structure will no longer be valid */
4880 pAdapter->dev = NULL;
4881 pAdapter->magic = 0;
4882 } while (0);
4883
4884 EXIT();
4885}
4886
4887/**---------------------------------------------------------------------------
4888
4889 \brief hdd_release_firmware() -
4890
4891 This function calls the release firmware API to free the firmware buffer.
4892
4893 \param - pFileName Pointer to the File Name.
4894 pCtx - Pointer to the adapter .
4895
4896
4897 \return - 0 for success, non zero for failure
4898
4899 --------------------------------------------------------------------------*/
4900
4901VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
4902{
4903 VOS_STATUS status = VOS_STATUS_SUCCESS;
4904 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
4905 ENTER();
4906
4907
4908 if (!strcmp(WLAN_FW_FILE, pFileName)) {
4909
4910 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
4911
4912 if(pHddCtx->fw) {
4913 release_firmware(pHddCtx->fw);
4914 pHddCtx->fw = NULL;
4915 }
4916 else
4917 status = VOS_STATUS_E_FAILURE;
4918 }
4919 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
4920 if(pHddCtx->nv) {
4921 release_firmware(pHddCtx->nv);
4922 pHddCtx->nv = NULL;
4923 }
4924 else
4925 status = VOS_STATUS_E_FAILURE;
4926
4927 }
4928
4929 EXIT();
4930 return status;
4931}
4932
4933/**---------------------------------------------------------------------------
4934
4935 \brief hdd_request_firmware() -
4936
4937 This function reads the firmware file using the request firmware
4938 API and returns the the firmware data and the firmware file size.
4939
4940 \param - pfileName - Pointer to the file name.
4941 - pCtx - Pointer to the adapter .
4942 - ppfw_data - Pointer to the pointer of the firmware data.
4943 - pSize - Pointer to the file size.
4944
4945 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
4946
4947 --------------------------------------------------------------------------*/
4948
4949
4950VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
4951{
4952 int status;
4953 VOS_STATUS retval = VOS_STATUS_SUCCESS;
4954 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
4955 ENTER();
4956
4957 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
4958
4959 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
4960
4961 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
4962 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
4963 __func__, pfileName);
4964 retval = VOS_STATUS_E_FAILURE;
4965 }
4966
4967 else {
4968 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
4969 *pSize = pHddCtx->fw->size;
4970 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
4971 __func__, *pSize);
4972 }
4973 }
4974 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
4975
4976 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
4977
4978 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
4979 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
4980 __func__, pfileName);
4981 retval = VOS_STATUS_E_FAILURE;
4982 }
4983
4984 else {
4985 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
4986 *pSize = pHddCtx->nv->size;
4987 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
4988 __func__, *pSize);
4989 }
4990 }
4991
4992 EXIT();
4993 return retval;
4994}
4995/**---------------------------------------------------------------------------
4996 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
4997
4998 This is the function invoked by SME to inform the result of a full power
4999 request issued by HDD
5000
5001 \param - callbackcontext - Pointer to cookie
5002 status - result of request
5003
5004 \return - None
5005
5006--------------------------------------------------------------------------*/
5007void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5008{
5009 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5010
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005011 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005012 if(&pHddCtx->full_pwr_comp_var)
5013 {
5014 complete(&pHddCtx->full_pwr_comp_var);
5015 }
5016}
5017
5018/**---------------------------------------------------------------------------
5019
5020 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5021
5022 This is the function invoked by SME to inform the result of BMPS
5023 request issued by HDD
5024
5025 \param - callbackcontext - Pointer to cookie
5026 status - result of request
5027
5028 \return - None
5029
5030--------------------------------------------------------------------------*/
5031void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5032{
5033
5034 struct completion *completion_var = (struct completion*) callbackContext;
5035
Arif Hussain6d2a3322013-11-17 19:50:10 -08005036 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005037 if(completion_var != NULL)
5038 {
5039 complete(completion_var);
5040 }
5041}
5042
5043/**---------------------------------------------------------------------------
5044
5045 \brief hdd_get_cfg_file_size() -
5046
5047 This function reads the configuration file using the request firmware
5048 API and returns the configuration file size.
5049
5050 \param - pCtx - Pointer to the adapter .
5051 - pFileName - Pointer to the file name.
5052 - pBufSize - Pointer to the buffer size.
5053
5054 \return - 0 for success, non zero for failure
5055
5056 --------------------------------------------------------------------------*/
5057
5058VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5059{
5060 int status;
5061 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5062
5063 ENTER();
5064
5065 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5066
5067 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5068 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5069 status = VOS_STATUS_E_FAILURE;
5070 }
5071 else {
5072 *pBufSize = pHddCtx->fw->size;
5073 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5074 release_firmware(pHddCtx->fw);
5075 pHddCtx->fw = NULL;
5076 }
5077
5078 EXIT();
5079 return VOS_STATUS_SUCCESS;
5080}
5081
5082/**---------------------------------------------------------------------------
5083
5084 \brief hdd_read_cfg_file() -
5085
5086 This function reads the configuration file using the request firmware
5087 API and returns the cfg data and the buffer size of the configuration file.
5088
5089 \param - pCtx - Pointer to the adapter .
5090 - pFileName - Pointer to the file name.
5091 - pBuffer - Pointer to the data buffer.
5092 - pBufSize - Pointer to the buffer size.
5093
5094 \return - 0 for success, non zero for failure
5095
5096 --------------------------------------------------------------------------*/
5097
5098VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5099 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5100{
5101 int status;
5102 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5103
5104 ENTER();
5105
5106 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5107
5108 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5109 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5110 return VOS_STATUS_E_FAILURE;
5111 }
5112 else {
5113 if(*pBufSize != pHddCtx->fw->size) {
5114 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5115 "file size", __func__);
5116 release_firmware(pHddCtx->fw);
5117 pHddCtx->fw = NULL;
5118 return VOS_STATUS_E_FAILURE;
5119 }
5120 else {
5121 if(pBuffer) {
5122 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5123 }
5124 release_firmware(pHddCtx->fw);
5125 pHddCtx->fw = NULL;
5126 }
5127 }
5128
5129 EXIT();
5130
5131 return VOS_STATUS_SUCCESS;
5132}
5133
5134/**---------------------------------------------------------------------------
5135
Jeff Johnson295189b2012-06-20 16:38:30 -07005136 \brief hdd_set_mac_address() -
5137
5138 This function sets the user specified mac address using
5139 the command ifconfig wlanX hw ether <mac adress>.
5140
5141 \param - dev - Pointer to the net device.
5142 - addr - Pointer to the sockaddr.
5143 \return - 0 for success, non zero for failure
5144
5145 --------------------------------------------------------------------------*/
5146
5147static int hdd_set_mac_address(struct net_device *dev, void *addr)
5148{
5149 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5150 struct sockaddr *psta_mac_addr = addr;
5151 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5152
5153 ENTER();
5154
5155 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
5156
5157#ifdef HDD_SESSIONIZE
5158 // set the MAC address though the STA ID CFG.
5159 halStatus = ccmCfgSetStr( pAdapter->hHal, WNI_CFG_STA_ID,
5160 (v_U8_t *)&pAdapter->macAddressCurrent,
5161 sizeof( pAdapter->macAddressCurrent ),
5162 hdd_set_mac_addr_cb, VOS_FALSE );
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305163
5164 if(eHAL_STATUS_SUCCESS != halStatus)
5165 {
5166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5167 "%s: failed to set MAC address in CFG", __func__);
5168 }
5169
Jeff Johnson295189b2012-06-20 16:38:30 -07005170#endif
5171
5172 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5173
5174 EXIT();
5175 return halStatus;
5176}
5177
5178tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5179{
5180 int i;
5181 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5182 {
Abhishek Singheb183782014-02-06 13:37:21 +05305183 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005184 break;
5185 }
5186
5187 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5188 return NULL;
5189
5190 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5191 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5192}
5193
5194void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5195{
5196 int i;
5197 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5198 {
5199 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5200 {
5201 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5202 break;
5203 }
5204 }
5205 return;
5206}
5207
5208#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5209 static struct net_device_ops wlan_drv_ops = {
5210 .ndo_open = hdd_open,
5211 .ndo_stop = hdd_stop,
5212 .ndo_uninit = hdd_uninit,
5213 .ndo_start_xmit = hdd_hard_start_xmit,
5214 .ndo_tx_timeout = hdd_tx_timeout,
5215 .ndo_get_stats = hdd_stats,
5216 .ndo_do_ioctl = hdd_ioctl,
5217 .ndo_set_mac_address = hdd_set_mac_address,
5218 .ndo_select_queue = hdd_select_queue,
5219#ifdef WLAN_FEATURE_PACKET_FILTERING
5220#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5221 .ndo_set_rx_mode = hdd_set_multicast_list,
5222#else
5223 .ndo_set_multicast_list = hdd_set_multicast_list,
5224#endif //LINUX_VERSION_CODE
5225#endif
5226 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005227 static struct net_device_ops wlan_mon_drv_ops = {
5228 .ndo_open = hdd_mon_open,
5229 .ndo_stop = hdd_stop,
5230 .ndo_uninit = hdd_uninit,
5231 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5232 .ndo_tx_timeout = hdd_tx_timeout,
5233 .ndo_get_stats = hdd_stats,
5234 .ndo_do_ioctl = hdd_ioctl,
5235 .ndo_set_mac_address = hdd_set_mac_address,
5236 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005237
5238#endif
5239
5240void hdd_set_station_ops( struct net_device *pWlanDev )
5241{
5242#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005243 pWlanDev->netdev_ops = &wlan_drv_ops;
5244#else
5245 pWlanDev->open = hdd_open;
5246 pWlanDev->stop = hdd_stop;
5247 pWlanDev->uninit = hdd_uninit;
5248 pWlanDev->hard_start_xmit = NULL;
5249 pWlanDev->tx_timeout = hdd_tx_timeout;
5250 pWlanDev->get_stats = hdd_stats;
5251 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07005252 pWlanDev->set_mac_address = hdd_set_mac_address;
5253#endif
5254}
5255
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005256static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07005257{
5258 struct net_device *pWlanDev = NULL;
5259 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005260 /*
5261 * cfg80211 initialization and registration....
5262 */
5263 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
5264
Jeff Johnson295189b2012-06-20 16:38:30 -07005265 if(pWlanDev != NULL)
5266 {
5267
5268 //Save the pointer to the net_device in the HDD adapter
5269 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
5270
Jeff Johnson295189b2012-06-20 16:38:30 -07005271 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
5272
5273 pAdapter->dev = pWlanDev;
5274 pAdapter->pHddCtx = pHddCtx;
5275 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
5276
5277 init_completion(&pAdapter->session_open_comp_var);
5278 init_completion(&pAdapter->session_close_comp_var);
5279 init_completion(&pAdapter->disconnect_comp_var);
5280 init_completion(&pAdapter->linkup_event_var);
5281 init_completion(&pAdapter->cancel_rem_on_chan_var);
5282 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05305283 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005284#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5285 init_completion(&pAdapter->offchannel_tx_event);
5286#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005287 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005288#ifdef FEATURE_WLAN_TDLS
5289 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07005290 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08005291 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05305292 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005293#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005294 init_completion(&pHddCtx->mc_sus_event_var);
5295 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05305296 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07005297 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07005298 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07005299
Rajeev79dbe4c2013-10-05 11:03:42 +05305300#ifdef FEATURE_WLAN_BATCH_SCAN
5301 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
5302 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
5303 pAdapter->pBatchScanRsp = NULL;
5304 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07005305 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005306 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05305307 mutex_init(&pAdapter->hdd_batch_scan_lock);
5308#endif
5309
Jeff Johnson295189b2012-06-20 16:38:30 -07005310 pAdapter->isLinkUpSvcNeeded = FALSE;
5311 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
5312 //Init the net_device structure
5313 strlcpy(pWlanDev->name, name, IFNAMSIZ);
5314
5315 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
5316 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
5317 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
5318 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
5319
5320 hdd_set_station_ops( pAdapter->dev );
5321
5322 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005323 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
5324 pAdapter->wdev.wiphy = pHddCtx->wiphy;
5325 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005326 /* set pWlanDev's parent to underlying device */
5327 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
5328 }
5329
5330 return pAdapter;
5331}
5332
5333VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
5334{
5335 struct net_device *pWlanDev = pAdapter->dev;
5336 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5337 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5338 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5339
5340 if( rtnl_lock_held )
5341 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08005342 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07005343 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
5344 {
5345 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
5346 return VOS_STATUS_E_FAILURE;
5347 }
5348 }
5349 if (register_netdevice(pWlanDev))
5350 {
5351 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
5352 return VOS_STATUS_E_FAILURE;
5353 }
5354 }
5355 else
5356 {
5357 if(register_netdev(pWlanDev))
5358 {
5359 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
5360 return VOS_STATUS_E_FAILURE;
5361 }
5362 }
5363 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
5364
5365 return VOS_STATUS_SUCCESS;
5366}
5367
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005368static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07005369{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005370 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07005371
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005372 if (NULL == pAdapter)
5373 {
5374 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
5375 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07005376 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005377
5378 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5379 {
5380 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
5381 return eHAL_STATUS_NOT_INITIALIZED;
5382 }
5383
5384 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
5385
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005386#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005387 /* need to make sure all of our scheduled work has completed.
5388 * This callback is called from MC thread context, so it is safe to
5389 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005390 *
5391 * Even though this is called from MC thread context, if there is a faulty
5392 * work item in the system, that can hang this call forever. So flushing
5393 * this global work queue is not safe; and now we make sure that
5394 * individual work queues are stopped correctly. But the cancel work queue
5395 * is a GPL only API, so the proprietary version of the driver would still
5396 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005397 */
5398 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005399#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005400
5401 /* We can be blocked while waiting for scheduled work to be
5402 * flushed, and the adapter structure can potentially be freed, in
5403 * which case the magic will have been reset. So make sure the
5404 * magic is still good, and hence the adapter structure is still
5405 * valid, before signaling completion */
5406 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
5407 {
5408 complete(&pAdapter->session_close_comp_var);
5409 }
5410
Jeff Johnson295189b2012-06-20 16:38:30 -07005411 return eHAL_STATUS_SUCCESS;
5412}
5413
5414VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
5415{
5416 struct net_device *pWlanDev = pAdapter->dev;
5417 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5418 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5419 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5420 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305421 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005422
5423 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005424 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005425 //Open a SME session for future operation
5426 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005427 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005428 if ( !HAL_STATUS_SUCCESS( halStatus ) )
5429 {
5430 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005431 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005432 halStatus, halStatus );
5433 status = VOS_STATUS_E_FAILURE;
5434 goto error_sme_open;
5435 }
5436
5437 //Block on a completion variable. Can't wait forever though.
5438 rc = wait_for_completion_interruptible_timeout(
5439 &pAdapter->session_open_comp_var,
5440 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305441 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005442 {
5443 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305444 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07005445 status = VOS_STATUS_E_FAILURE;
5446 goto error_sme_open;
5447 }
5448
5449 // Register wireless extensions
5450 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
5451 {
5452 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005453 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005454 halStatus, halStatus );
5455 status = VOS_STATUS_E_FAILURE;
5456 goto error_register_wext;
5457 }
5458 //Safe to register the hard_start_xmit function again
5459#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5460 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
5461#else
5462 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
5463#endif
5464
5465 //Set the Connection State to Not Connected
5466 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5467
5468 //Set the default operation channel
5469 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
5470
5471 /* Make the default Auth Type as OPEN*/
5472 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5473
5474 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
5475 {
5476 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005477 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005478 status, status );
5479 goto error_init_txrx;
5480 }
5481
5482 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5483
5484 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
5485 {
5486 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005487 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005488 status, status );
5489 goto error_wmm_init;
5490 }
5491
5492 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5493
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005494#ifdef FEATURE_WLAN_TDLS
5495 if(0 != wlan_hdd_tdls_init(pAdapter))
5496 {
5497 status = VOS_STATUS_E_FAILURE;
5498 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_tdls_init failed",__func__);
5499 goto error_tdls_init;
5500 }
5501 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5502#endif
5503
Jeff Johnson295189b2012-06-20 16:38:30 -07005504 return VOS_STATUS_SUCCESS;
5505
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005506#ifdef FEATURE_WLAN_TDLS
5507error_tdls_init:
5508 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5509 hdd_wmm_adapter_close(pAdapter);
5510#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005511error_wmm_init:
5512 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5513 hdd_deinit_tx_rx(pAdapter);
5514error_init_txrx:
5515 hdd_UnregisterWext(pWlanDev);
5516error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005517 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005518 {
5519 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005520 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005521 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005522 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07005523 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305524 unsigned long rc;
5525
Jeff Johnson295189b2012-06-20 16:38:30 -07005526 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305527 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005528 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005529 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305530 if (rc <= 0)
5531 hddLog(VOS_TRACE_LEVEL_ERROR,
5532 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005533 }
5534}
5535error_sme_open:
5536 return status;
5537}
5538
Jeff Johnson295189b2012-06-20 16:38:30 -07005539void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5540{
5541 hdd_cfg80211_state_t *cfgState;
5542
5543 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
5544
5545 if( NULL != cfgState->buf )
5546 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305547 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07005548 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
5549 rc = wait_for_completion_interruptible_timeout(
5550 &pAdapter->tx_action_cnf_event,
5551 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305552 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005553 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08005554 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305555 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
5556 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005557 }
5558 }
5559 return;
5560}
Jeff Johnson295189b2012-06-20 16:38:30 -07005561
5562void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5563{
5564 ENTER();
5565 switch ( pAdapter->device_mode )
5566 {
5567 case WLAN_HDD_INFRA_STATION:
5568 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005569 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005570 {
5571 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5572 {
5573 hdd_deinit_tx_rx( pAdapter );
5574 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5575 }
5576
5577 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5578 {
5579 hdd_wmm_adapter_close( pAdapter );
5580 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5581 }
5582
Jeff Johnson295189b2012-06-20 16:38:30 -07005583 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005584#ifdef FEATURE_WLAN_TDLS
5585 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
5586 {
5587 wlan_hdd_tdls_exit(pAdapter);
5588 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5589 }
5590#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005591
5592 break;
5593 }
5594
5595 case WLAN_HDD_SOFTAP:
5596 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005597 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05305598
5599 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5600 {
5601 hdd_wmm_adapter_close( pAdapter );
5602 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5603 }
5604
Jeff Johnson295189b2012-06-20 16:38:30 -07005605 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005606
5607 hdd_unregister_hostapd(pAdapter);
5608 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07005609 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07005610 break;
5611 }
5612
5613 case WLAN_HDD_MONITOR:
5614 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005615 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005616 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5617 {
5618 hdd_deinit_tx_rx( pAdapter );
5619 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5620 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005621 if(NULL != pAdapterforTx)
5622 {
5623 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
5624 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005625 break;
5626 }
5627
5628
5629 default:
5630 break;
5631 }
5632
5633 EXIT();
5634}
5635
5636void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
5637{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08005638 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305639
5640 ENTER();
5641 if (NULL == pAdapter)
5642 {
5643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5644 "%s: HDD adapter is Null", __func__);
5645 return;
5646 }
5647
5648 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005649
Rajeev79dbe4c2013-10-05 11:03:42 +05305650#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305651 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
5652 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08005653 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305654 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
5655 )
5656 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005657 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05305658 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005659 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
5660 {
5661 hdd_deinit_batch_scan(pAdapter);
5662 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305663 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08005664 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305665#endif
5666
Jeff Johnson295189b2012-06-20 16:38:30 -07005667 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
5668 if( rtnl_held )
5669 {
5670 unregister_netdevice(pWlanDev);
5671 }
5672 else
5673 {
5674 unregister_netdev(pWlanDev);
5675 }
5676 // note that the pAdapter is no longer valid at this point
5677 // since the memory has been reclaimed
5678 }
5679
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305680 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005681}
5682
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005683void hdd_set_pwrparams(hdd_context_t *pHddCtx)
5684{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305685 VOS_STATUS status;
5686 hdd_adapter_t *pAdapter = NULL;
5687 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005688
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305689 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005690
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305691 /*loop through all adapters.*/
5692 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005693 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305694 pAdapter = pAdapterNode->pAdapter;
5695 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
5696 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005697
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305698 { // we skip this registration for modes other than STA and P2P client modes.
5699 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5700 pAdapterNode = pNext;
5701 continue;
5702 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005703
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305704 //Apply Dynamic DTIM For P2P
5705 //Only if ignoreDynamicDtimInP2pMode is not set in ini
5706 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
5707 pHddCtx->cfg_ini->enableModulatedDTIM) &&
5708 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5709 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
5710 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
5711 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
5712 (eConnectionState_Associated ==
5713 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
5714 (pHddCtx->cfg_ini->fIsBmpsEnabled))
5715 {
5716 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005717
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305718 powerRequest.uIgnoreDTIM = 1;
5719 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
5720
5721 if (pHddCtx->cfg_ini->enableModulatedDTIM)
5722 {
5723 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
5724 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
5725 }
5726 else
5727 {
5728 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
5729 }
5730
5731 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
5732 * specified during Enter/Exit BMPS when LCD off*/
5733 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
5734 NULL, eANI_BOOLEAN_FALSE);
5735 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
5736 NULL, eANI_BOOLEAN_FALSE);
5737
5738 /* switch to the DTIM specified in cfg.ini */
5739 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5740 "Switch to DTIM %d", powerRequest.uListenInterval);
5741 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
5742 break;
5743
5744 }
5745
5746 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5747 pAdapterNode = pNext;
5748 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005749}
5750
5751void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
5752{
5753 /*Switch back to DTIM 1*/
5754 tSirSetPowerParamsReq powerRequest = { 0 };
5755
5756 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
5757 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07005758 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005759
5760 /* Update ignoreDTIM and ListedInterval in CFG with default values */
5761 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
5762 NULL, eANI_BOOLEAN_FALSE);
5763 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
5764 NULL, eANI_BOOLEAN_FALSE);
5765
5766 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5767 "Switch to DTIM%d",powerRequest.uListenInterval);
5768 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
5769
5770}
5771
Jeff Johnson295189b2012-06-20 16:38:30 -07005772VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
5773{
5774 VOS_STATUS status = VOS_STATUS_SUCCESS;
5775
5776 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
5777 {
5778 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
5779 }
5780
5781 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
5782 {
5783 sme_StartAutoBmpsTimer(pHddCtx->hHal);
5784 }
5785
5786 if (pHddCtx->cfg_ini->fIsImpsEnabled)
5787 {
5788 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
5789 }
5790
5791 return status;
5792}
5793
5794VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
5795{
5796 hdd_adapter_t *pAdapter = NULL;
5797 eHalStatus halStatus;
5798 VOS_STATUS status = VOS_STATUS_E_INVAL;
5799 v_BOOL_t disableBmps = FALSE;
5800 v_BOOL_t disableImps = FALSE;
5801
5802 switch(session_type)
5803 {
5804 case WLAN_HDD_INFRA_STATION:
5805 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07005806 case WLAN_HDD_P2P_CLIENT:
5807 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005808 //Exit BMPS -> Is Sta/P2P Client is already connected
5809 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
5810 if((NULL != pAdapter)&&
5811 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5812 {
5813 disableBmps = TRUE;
5814 }
5815
5816 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
5817 if((NULL != pAdapter)&&
5818 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5819 {
5820 disableBmps = TRUE;
5821 }
5822
5823 //Exit both Bmps and Imps incase of Go/SAP Mode
5824 if((WLAN_HDD_SOFTAP == session_type) ||
5825 (WLAN_HDD_P2P_GO == session_type))
5826 {
5827 disableBmps = TRUE;
5828 disableImps = TRUE;
5829 }
5830
5831 if(TRUE == disableImps)
5832 {
5833 if (pHddCtx->cfg_ini->fIsImpsEnabled)
5834 {
5835 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
5836 }
5837 }
5838
5839 if(TRUE == disableBmps)
5840 {
5841 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
5842 {
5843 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
5844
5845 if(eHAL_STATUS_SUCCESS != halStatus)
5846 {
5847 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08005848 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005849 VOS_ASSERT(0);
5850 return status;
5851 }
5852 }
5853
5854 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
5855 {
5856 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
5857
5858 if(eHAL_STATUS_SUCCESS != halStatus)
5859 {
5860 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08005861 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005862 VOS_ASSERT(0);
5863 return status;
5864 }
5865 }
5866 }
5867
5868 if((TRUE == disableBmps) ||
5869 (TRUE == disableImps))
5870 {
5871 /* Now, get the chip into Full Power now */
5872 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
5873 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
5874 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
5875
5876 if(halStatus != eHAL_STATUS_SUCCESS)
5877 {
5878 if(halStatus == eHAL_STATUS_PMC_PENDING)
5879 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305880 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005881 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305882 ret = wait_for_completion_interruptible_timeout(
5883 &pHddCtx->full_pwr_comp_var,
5884 msecs_to_jiffies(1000));
5885 if (ret <= 0)
5886 {
5887 hddLog(VOS_TRACE_LEVEL_ERROR,
5888 "%s: wait on full_pwr_comp_var failed %ld",
5889 __func__, ret);
5890 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005891 }
5892 else
5893 {
5894 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08005895 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005896 VOS_ASSERT(0);
5897 return status;
5898 }
5899 }
5900
5901 status = VOS_STATUS_SUCCESS;
5902 }
5903
5904 break;
5905 }
5906 return status;
5907}
5908
5909hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005910 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07005911 tANI_U8 rtnl_held )
5912{
5913 hdd_adapter_t *pAdapter = NULL;
5914 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
5915 VOS_STATUS status = VOS_STATUS_E_FAILURE;
5916 VOS_STATUS exitbmpsStatus;
5917
Arif Hussain6d2a3322013-11-17 19:50:10 -08005918 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07005919
Nirav Shah436658f2014-02-28 17:05:45 +05305920 if(macAddr == NULL)
5921 {
5922 /* Not received valid macAddr */
5923 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5924 "%s:Unable to add virtual intf: Not able to get"
5925 "valid mac address",__func__);
5926 return NULL;
5927 }
5928
Jeff Johnson295189b2012-06-20 16:38:30 -07005929 //Disable BMPS incase of Concurrency
5930 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
5931
5932 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
5933 {
5934 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305935 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005936 VOS_ASSERT(0);
5937 return NULL;
5938 }
5939
5940 switch(session_type)
5941 {
5942 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07005943 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005944 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005945 {
5946 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
5947
5948 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305949 {
5950 hddLog(VOS_TRACE_LEVEL_FATAL,
5951 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07005952 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305953 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005954
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05305955#ifdef FEATURE_WLAN_TDLS
5956 /* A Mutex Lock is introduced while changing/initializing the mode to
5957 * protect the concurrent access for the Adapters by TDLS module.
5958 */
5959 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
5960 {
5961 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5962 "%s: unable to lock list", __func__);
5963 return NULL;
5964 }
5965#endif
5966
Jeff Johnsone7245742012-09-05 17:12:55 -07005967 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
5968 NL80211_IFTYPE_P2P_CLIENT:
5969 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07005970
Jeff Johnson295189b2012-06-20 16:38:30 -07005971 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05305972#ifdef FEATURE_WLAN_TDLS
5973 mutex_unlock(&pHddCtx->tdls_lock);
5974#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05305975
5976 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07005977 if( VOS_STATUS_SUCCESS != status )
5978 goto err_free_netdev;
5979
5980 status = hdd_register_interface( pAdapter, rtnl_held );
5981 if( VOS_STATUS_SUCCESS != status )
5982 {
5983 hdd_deinit_adapter(pHddCtx, pAdapter);
5984 goto err_free_netdev;
5985 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05305986
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05305987 // Workqueue which gets scheduled in IPv4 notification callback.
5988 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
5989
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05305990#ifdef WLAN_NS_OFFLOAD
5991 // Workqueue which gets scheduled in IPv6 notification callback.
5992 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
5993#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005994 //Stop the Interface TX queue.
5995 netif_tx_disable(pAdapter->dev);
5996 //netif_tx_disable(pWlanDev);
5997 netif_carrier_off(pAdapter->dev);
5998
5999 break;
6000 }
6001
Jeff Johnson295189b2012-06-20 16:38:30 -07006002 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006003 case WLAN_HDD_SOFTAP:
6004 {
6005 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6006 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306007 {
6008 hddLog(VOS_TRACE_LEVEL_FATAL,
6009 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006010 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306011 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006012
Jeff Johnson295189b2012-06-20 16:38:30 -07006013 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6014 NL80211_IFTYPE_AP:
6015 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006016 pAdapter->device_mode = session_type;
6017
6018 status = hdd_init_ap_mode(pAdapter);
6019 if( VOS_STATUS_SUCCESS != status )
6020 goto err_free_netdev;
6021
6022 status = hdd_register_hostapd( pAdapter, rtnl_held );
6023 if( VOS_STATUS_SUCCESS != status )
6024 {
6025 hdd_deinit_adapter(pHddCtx, pAdapter);
6026 goto err_free_netdev;
6027 }
6028
6029 netif_tx_disable(pAdapter->dev);
6030 netif_carrier_off(pAdapter->dev);
6031
6032 hdd_set_conparam( 1 );
6033 break;
6034 }
6035 case WLAN_HDD_MONITOR:
6036 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006037 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6038 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306039 {
6040 hddLog(VOS_TRACE_LEVEL_FATAL,
6041 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006042 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306043 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006044
6045 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6046 pAdapter->device_mode = session_type;
6047 status = hdd_register_interface( pAdapter, rtnl_held );
6048#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6049 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6050#else
6051 pAdapter->dev->open = hdd_mon_open;
6052 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6053#endif
6054 hdd_init_tx_rx( pAdapter );
6055 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6056 //Set adapter to be used for data tx. It will use either GO or softap.
6057 pAdapter->sessionCtx.monitor.pAdapterForTx =
6058 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006059 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6060 {
6061 pAdapter->sessionCtx.monitor.pAdapterForTx =
6062 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6063 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006064 /* This workqueue will be used to transmit management packet over
6065 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006066 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6067 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6068 return NULL;
6069 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006070
Jeff Johnson295189b2012-06-20 16:38:30 -07006071 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6072 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006073 }
6074 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006075 case WLAN_HDD_FTM:
6076 {
6077 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6078
6079 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306080 {
6081 hddLog(VOS_TRACE_LEVEL_FATAL,
6082 FL("failed to allocate adapter for session %d"), session_type);
6083 return NULL;
6084 }
6085
Jeff Johnson295189b2012-06-20 16:38:30 -07006086 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6087 * message while loading driver in FTM mode. */
6088 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6089 pAdapter->device_mode = session_type;
6090 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306091
6092 hdd_init_tx_rx( pAdapter );
6093
6094 //Stop the Interface TX queue.
6095 netif_tx_disable(pAdapter->dev);
6096 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006097 }
6098 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006099 default:
6100 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306101 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6102 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006103 VOS_ASSERT(0);
6104 return NULL;
6105 }
6106 }
6107
Jeff Johnson295189b2012-06-20 16:38:30 -07006108 if( VOS_STATUS_SUCCESS == status )
6109 {
6110 //Add it to the hdd's session list.
6111 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6112 if( NULL == pHddAdapterNode )
6113 {
6114 status = VOS_STATUS_E_NOMEM;
6115 }
6116 else
6117 {
6118 pHddAdapterNode->pAdapter = pAdapter;
6119 status = hdd_add_adapter_back ( pHddCtx,
6120 pHddAdapterNode );
6121 }
6122 }
6123
6124 if( VOS_STATUS_SUCCESS != status )
6125 {
6126 if( NULL != pAdapter )
6127 {
6128 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6129 pAdapter = NULL;
6130 }
6131 if( NULL != pHddAdapterNode )
6132 {
6133 vos_mem_free( pHddAdapterNode );
6134 }
6135
6136 goto resume_bmps;
6137 }
6138
6139 if(VOS_STATUS_SUCCESS == status)
6140 {
6141 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6142
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006143 //Initialize the WoWL service
6144 if(!hdd_init_wowl(pAdapter))
6145 {
6146 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6147 goto err_free_netdev;
6148 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006149 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006150 return pAdapter;
6151
6152err_free_netdev:
6153 free_netdev(pAdapter->dev);
6154 wlan_hdd_release_intf_addr( pHddCtx,
6155 pAdapter->macAddressCurrent.bytes );
6156
6157resume_bmps:
6158 //If bmps disabled enable it
6159 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6160 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306161 if (pHddCtx->hdd_wlan_suspended)
6162 {
6163 hdd_set_pwrparams(pHddCtx);
6164 }
6165 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006166 }
6167 return NULL;
6168}
6169
6170VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6171 tANI_U8 rtnl_held )
6172{
6173 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6174 VOS_STATUS status;
6175
6176 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6177 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306178 {
6179 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6180 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006181 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306182 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006183
6184 while ( pCurrent->pAdapter != pAdapter )
6185 {
6186 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6187 if( VOS_STATUS_SUCCESS != status )
6188 break;
6189
6190 pCurrent = pNext;
6191 }
6192 pAdapterNode = pCurrent;
6193 if( VOS_STATUS_SUCCESS == status )
6194 {
6195 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6196 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306197
6198#ifdef FEATURE_WLAN_TDLS
6199
6200 /* A Mutex Lock is introduced while changing/initializing the mode to
6201 * protect the concurrent access for the Adapters by TDLS module.
6202 */
6203 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
6204 {
6205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6206 "%s: unable to lock list", __func__);
6207 return VOS_STATUS_E_FAILURE;
6208 }
6209#endif
6210
Jeff Johnson295189b2012-06-20 16:38:30 -07006211 hdd_remove_adapter( pHddCtx, pAdapterNode );
6212 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006213 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006214
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306215#ifdef FEATURE_WLAN_TDLS
6216 mutex_unlock(&pHddCtx->tdls_lock);
6217#endif
6218
Jeff Johnson295189b2012-06-20 16:38:30 -07006219
6220 /* If there is a single session of STA/P2P client, re-enable BMPS */
6221 if ((!vos_concurrent_sessions_running()) &&
6222 ((pHddCtx->no_of_sessions[VOS_STA_MODE] >= 1) ||
6223 (pHddCtx->no_of_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
6224 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306225 if (pHddCtx->hdd_wlan_suspended)
6226 {
6227 hdd_set_pwrparams(pHddCtx);
6228 }
6229 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006230 }
6231
6232 return VOS_STATUS_SUCCESS;
6233 }
6234
6235 return VOS_STATUS_E_FAILURE;
6236}
6237
6238VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6239{
6240 hdd_adapter_list_node_t *pHddAdapterNode;
6241 VOS_STATUS status;
6242
6243 ENTER();
6244
6245 do
6246 {
6247 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6248 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6249 {
6250 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
6251 vos_mem_free( pHddAdapterNode );
6252 }
6253 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
6254
6255 EXIT();
6256
6257 return VOS_STATUS_SUCCESS;
6258}
6259
6260void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
6261{
6262 v_U8_t addIE[1] = {0};
6263
6264 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6265 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
6266 eANI_BOOLEAN_FALSE) )
6267 {
6268 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006269 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006270 }
6271
6272 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6273 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6274 eANI_BOOLEAN_FALSE) )
6275 {
6276 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006277 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006278 }
6279
6280 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6281 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6282 eANI_BOOLEAN_FALSE) )
6283 {
6284 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006285 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006286 }
6287}
6288
6289VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6290{
6291 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6292 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6293 union iwreq_data wrqu;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306294 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006295
6296 ENTER();
6297
6298 switch(pAdapter->device_mode)
6299 {
6300 case WLAN_HDD_INFRA_STATION:
6301 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006302 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006303 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
6304 {
6305 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
6306 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6307 pAdapter->sessionId,
6308 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6309 else
6310 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6311 pAdapter->sessionId,
6312 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6313 //success implies disconnect command got queued up successfully
6314 if(halStatus == eHAL_STATUS_SUCCESS)
6315 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306316 ret = wait_for_completion_interruptible_timeout(
6317 &pAdapter->disconnect_comp_var,
6318 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6319 if (ret <= 0)
6320 {
6321 hddLog(VOS_TRACE_LEVEL_ERROR,
6322 "%s: wait on disconnect_comp_var failed %ld",
6323 __func__, ret);
6324 }
6325 }
6326 else
6327 {
6328 hddLog(LOGE, "%s: failed to post disconnect event to SME",
6329 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006330 }
6331 memset(&wrqu, '\0', sizeof(wrqu));
6332 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6333 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6334 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
6335 }
6336 else
6337 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306338 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6339 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07006340 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306341#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306342#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306343 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
6344#endif
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306345 if (pAdapter->ipv6_notifier_registered)
6346 {
6347 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
6348 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
6349 pAdapter->ipv6_notifier_registered = false;
6350 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306351#endif
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05306352 if (pAdapter->ipv4_notifier_registered)
6353 {
6354 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
6355 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
6356 pAdapter->ipv4_notifier_registered = false;
6357 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306358#ifdef WLAN_OPEN_SOURCE
6359 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
6360#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006361 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
6362 {
6363 INIT_COMPLETION(pAdapter->session_close_comp_var);
6364 if (eHAL_STATUS_SUCCESS ==
6365 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
6366 hdd_smeCloseSessionCallback, pAdapter))
6367 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306368 unsigned long ret;
6369
Jeff Johnson295189b2012-06-20 16:38:30 -07006370 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306371 ret = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006372 &pAdapter->session_close_comp_var,
6373 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306374 if ( 0 >= ret)
6375 {
6376 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
6377 __func__, ret);
6378 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006379 }
6380 }
6381
6382 break;
6383
6384 case WLAN_HDD_SOFTAP:
6385 case WLAN_HDD_P2P_GO:
6386 //Any softap specific cleanup here...
6387 mutex_lock(&pHddCtx->sap_lock);
6388 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6389 {
6390 VOS_STATUS status;
6391 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6392
6393 //Stop Bss.
6394 status = WLANSAP_StopBss(pHddCtx->pvosContext);
6395 if (VOS_IS_STATUS_SUCCESS(status))
6396 {
6397 hdd_hostapd_state_t *pHostapdState =
6398 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6399
6400 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6401
6402 if (!VOS_IS_STATUS_SUCCESS(status))
6403 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306404 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
6405 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006406 }
6407 }
6408 else
6409 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006410 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006411 }
6412 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
6413
6414 if (eHAL_STATUS_FAILURE ==
6415 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
6416 0, NULL, eANI_BOOLEAN_FALSE))
6417 {
6418 hddLog(LOGE,
6419 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006420 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006421 }
6422
6423 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6424 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6425 eANI_BOOLEAN_FALSE) )
6426 {
6427 hddLog(LOGE,
6428 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
6429 }
6430
6431 // Reset WNI_CFG_PROBE_RSP Flags
6432 wlan_hdd_reset_prob_rspies(pAdapter);
6433 kfree(pAdapter->sessionCtx.ap.beacon);
6434 pAdapter->sessionCtx.ap.beacon = NULL;
6435 }
6436 mutex_unlock(&pHddCtx->sap_lock);
6437 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006438
Jeff Johnson295189b2012-06-20 16:38:30 -07006439 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006440#ifdef WLAN_OPEN_SOURCE
6441 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
6442#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006444
Jeff Johnson295189b2012-06-20 16:38:30 -07006445 default:
6446 break;
6447 }
6448
6449 EXIT();
6450 return VOS_STATUS_SUCCESS;
6451}
6452
6453VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
6454{
6455 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6456 VOS_STATUS status;
6457 hdd_adapter_t *pAdapter;
6458
6459 ENTER();
6460
6461 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6462
6463 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6464 {
6465 pAdapter = pAdapterNode->pAdapter;
6466 netif_tx_disable(pAdapter->dev);
6467 netif_carrier_off(pAdapter->dev);
6468
6469 hdd_stop_adapter( pHddCtx, pAdapter );
6470
6471 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6472 pAdapterNode = pNext;
6473 }
6474
6475 EXIT();
6476
6477 return VOS_STATUS_SUCCESS;
6478}
6479
Rajeev Kumarf999e582014-01-09 17:33:29 -08006480
6481#ifdef FEATURE_WLAN_BATCH_SCAN
6482/**---------------------------------------------------------------------------
6483
6484 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
6485 structures
6486
6487 \param - pAdapter Pointer to HDD adapter
6488
6489 \return - None
6490
6491 --------------------------------------------------------------------------*/
6492void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
6493{
6494 tHddBatchScanRsp *pNode;
6495 tHddBatchScanRsp *pPrev;
6496
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306497 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006498 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306499 hddLog(VOS_TRACE_LEVEL_ERROR,
6500 "%s: Adapter context is Null", __func__);
6501 return;
6502 }
6503
6504 pNode = pAdapter->pBatchScanRsp;
6505 while (pNode)
6506 {
6507 pPrev = pNode;
6508 pNode = pNode->pNext;
6509 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08006510 }
6511
6512 pAdapter->pBatchScanRsp = NULL;
6513 pAdapter->numScanList = 0;
6514 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
6515 pAdapter->prev_batch_id = 0;
6516
6517 return;
6518}
6519#endif
6520
6521
Jeff Johnson295189b2012-06-20 16:38:30 -07006522VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
6523{
6524 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6525 VOS_STATUS status;
6526 hdd_adapter_t *pAdapter;
6527
6528 ENTER();
6529
6530 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6531
6532 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6533 {
6534 pAdapter = pAdapterNode->pAdapter;
6535 netif_tx_disable(pAdapter->dev);
6536 netif_carrier_off(pAdapter->dev);
6537
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006538 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
6539
Jeff Johnson295189b2012-06-20 16:38:30 -07006540 hdd_deinit_tx_rx(pAdapter);
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306541 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6542 {
6543 hdd_wmm_adapter_close( pAdapter );
6544 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6545 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006546
Rajeev Kumarf999e582014-01-09 17:33:29 -08006547#ifdef FEATURE_WLAN_BATCH_SCAN
6548 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6549 {
6550 hdd_deinit_batch_scan(pAdapter);
6551 }
6552#endif
6553
Jeff Johnson295189b2012-06-20 16:38:30 -07006554 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6555 pAdapterNode = pNext;
6556 }
6557
6558 EXIT();
6559
6560 return VOS_STATUS_SUCCESS;
6561}
6562
6563VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
6564{
6565 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6566 VOS_STATUS status;
6567 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306568 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07006569
6570 ENTER();
6571
6572 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6573
6574 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6575 {
6576 pAdapter = pAdapterNode->pAdapter;
6577
6578 switch(pAdapter->device_mode)
6579 {
6580 case WLAN_HDD_INFRA_STATION:
6581 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006582 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306583
6584 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
6585
Jeff Johnson295189b2012-06-20 16:38:30 -07006586 hdd_init_station_mode(pAdapter);
6587 /* Open the gates for HDD to receive Wext commands */
6588 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006589 pHddCtx->scan_info.mScanPending = FALSE;
6590 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006591
6592 //Trigger the initial scan
6593 hdd_wlan_initial_scan(pAdapter);
6594
6595 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306596 if (eConnectionState_Associated == connState ||
6597 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07006598 {
6599 union iwreq_data wrqu;
6600 memset(&wrqu, '\0', sizeof(wrqu));
6601 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6602 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6603 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006604 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006605
Jeff Johnson295189b2012-06-20 16:38:30 -07006606 /* indicate disconnected event to nl80211 */
6607 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
6608 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006609 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306610 else if (eConnectionState_Connecting == connState)
6611 {
6612 /*
6613 * Indicate connect failure to supplicant if we were in the
6614 * process of connecting
6615 */
6616 cfg80211_connect_result(pAdapter->dev, NULL,
6617 NULL, 0, NULL, 0,
6618 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
6619 GFP_KERNEL);
6620 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006621 break;
6622
6623 case WLAN_HDD_SOFTAP:
6624 /* softAP can handle SSR */
6625 break;
6626
6627 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006628 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07006629 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006630 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006631 break;
6632
6633 case WLAN_HDD_MONITOR:
6634 /* monitor interface start */
6635 break;
6636 default:
6637 break;
6638 }
6639
6640 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6641 pAdapterNode = pNext;
6642 }
6643
6644 EXIT();
6645
6646 return VOS_STATUS_SUCCESS;
6647}
6648
6649VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
6650{
6651 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6652 hdd_adapter_t *pAdapter;
6653 VOS_STATUS status;
6654 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306655 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006656
6657 ENTER();
6658
6659 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6660
6661 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6662 {
6663 pAdapter = pAdapterNode->pAdapter;
6664
6665 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6666 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
6667 {
6668 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6669 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6670
6671 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6672 init_completion(&pAdapter->disconnect_comp_var);
6673 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
6674 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6675
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306676 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006677 &pAdapter->disconnect_comp_var,
6678 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306679 if (0 >= ret)
6680 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
6681 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07006682
6683 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
6684 pHddCtx->isAmpAllowed = VOS_FALSE;
6685 sme_RoamConnect(pHddCtx->hHal,
6686 pAdapter->sessionId, &(pWextState->roamProfile),
6687 &roamId);
6688 }
6689
6690 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6691 pAdapterNode = pNext;
6692 }
6693
6694 EXIT();
6695
6696 return VOS_STATUS_SUCCESS;
6697}
6698
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07006699void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
6700{
6701 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6702 VOS_STATUS status;
6703 hdd_adapter_t *pAdapter;
6704 hdd_station_ctx_t *pHddStaCtx;
6705 hdd_ap_ctx_t *pHddApCtx;
6706 hdd_hostapd_state_t * pHostapdState;
6707 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
6708 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
6709 const char *p2pMode = "DEV";
6710 const char *ccMode = "Standalone";
6711 int n;
6712
6713 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6714 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6715 {
6716 pAdapter = pAdapterNode->pAdapter;
6717 switch (pAdapter->device_mode) {
6718 case WLAN_HDD_INFRA_STATION:
6719 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6720 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
6721 staChannel = pHddStaCtx->conn_info.operationChannel;
6722 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
6723 }
6724 break;
6725 case WLAN_HDD_P2P_CLIENT:
6726 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6727 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
6728 p2pChannel = pHddStaCtx->conn_info.operationChannel;
6729 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
6730 p2pMode = "CLI";
6731 }
6732 break;
6733 case WLAN_HDD_P2P_GO:
6734 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
6735 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6736 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
6737 p2pChannel = pHddApCtx->operatingChannel;
6738 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
6739 }
6740 p2pMode = "GO";
6741 break;
6742 case WLAN_HDD_SOFTAP:
6743 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
6744 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6745 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
6746 apChannel = pHddApCtx->operatingChannel;
6747 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
6748 }
6749 break;
6750 default:
6751 break;
6752 }
6753 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6754 pAdapterNode = pNext;
6755 }
6756 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
6757 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
6758 }
6759 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
6760 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
6761 if (p2pChannel > 0) {
6762 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
6763 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
6764 }
6765 if (apChannel > 0) {
6766 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
6767 apChannel, MAC_ADDR_ARRAY(apBssid));
6768 }
6769
6770 if (p2pChannel > 0 && apChannel > 0) {
6771 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
6772 }
6773}
6774
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006775bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07006776{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006777 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07006778}
6779
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006780/* Once SSR is disabled then it cannot be set. */
6781void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07006782{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006783 if (HDD_SSR_DISABLED == isSsrRequired)
6784 return;
6785
Jeff Johnson295189b2012-06-20 16:38:30 -07006786 isSsrRequired = value;
6787}
6788
6789VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
6790 hdd_adapter_list_node_t** ppAdapterNode)
6791{
6792 VOS_STATUS status;
6793 spin_lock(&pHddCtx->hddAdapters.lock);
6794 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
6795 (hdd_list_node_t**) ppAdapterNode );
6796 spin_unlock(&pHddCtx->hddAdapters.lock);
6797 return status;
6798}
6799
6800VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
6801 hdd_adapter_list_node_t* pAdapterNode,
6802 hdd_adapter_list_node_t** pNextAdapterNode)
6803{
6804 VOS_STATUS status;
6805 spin_lock(&pHddCtx->hddAdapters.lock);
6806 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
6807 (hdd_list_node_t*) pAdapterNode,
6808 (hdd_list_node_t**)pNextAdapterNode );
6809
6810 spin_unlock(&pHddCtx->hddAdapters.lock);
6811 return status;
6812}
6813
6814VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
6815 hdd_adapter_list_node_t* pAdapterNode)
6816{
6817 VOS_STATUS status;
6818 spin_lock(&pHddCtx->hddAdapters.lock);
6819 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
6820 &pAdapterNode->node );
6821 spin_unlock(&pHddCtx->hddAdapters.lock);
6822 return status;
6823}
6824
6825VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
6826 hdd_adapter_list_node_t** ppAdapterNode)
6827{
6828 VOS_STATUS status;
6829 spin_lock(&pHddCtx->hddAdapters.lock);
6830 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
6831 (hdd_list_node_t**) ppAdapterNode );
6832 spin_unlock(&pHddCtx->hddAdapters.lock);
6833 return status;
6834}
6835
6836VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
6837 hdd_adapter_list_node_t* pAdapterNode)
6838{
6839 VOS_STATUS status;
6840 spin_lock(&pHddCtx->hddAdapters.lock);
6841 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
6842 (hdd_list_node_t*) pAdapterNode );
6843 spin_unlock(&pHddCtx->hddAdapters.lock);
6844 return status;
6845}
6846
6847VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
6848 hdd_adapter_list_node_t* pAdapterNode)
6849{
6850 VOS_STATUS status;
6851 spin_lock(&pHddCtx->hddAdapters.lock);
6852 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
6853 (hdd_list_node_t*) pAdapterNode );
6854 spin_unlock(&pHddCtx->hddAdapters.lock);
6855 return status;
6856}
6857
6858hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
6859 tSirMacAddr macAddr )
6860{
6861 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6862 hdd_adapter_t *pAdapter;
6863 VOS_STATUS status;
6864
6865 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6866
6867 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6868 {
6869 pAdapter = pAdapterNode->pAdapter;
6870
6871 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
6872 macAddr, sizeof(tSirMacAddr) ) )
6873 {
6874 return pAdapter;
6875 }
6876 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6877 pAdapterNode = pNext;
6878 }
6879
6880 return NULL;
6881
6882}
6883
6884hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
6885{
6886 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6887 hdd_adapter_t *pAdapter;
6888 VOS_STATUS status;
6889
6890 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6891
6892 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6893 {
6894 pAdapter = pAdapterNode->pAdapter;
6895
6896 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
6897 IFNAMSIZ ) )
6898 {
6899 return pAdapter;
6900 }
6901 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6902 pAdapterNode = pNext;
6903 }
6904
6905 return NULL;
6906
6907}
6908
6909hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
6910{
6911 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6912 hdd_adapter_t *pAdapter;
6913 VOS_STATUS status;
6914
6915 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6916
6917 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6918 {
6919 pAdapter = pAdapterNode->pAdapter;
6920
6921 if( pAdapter && (mode == pAdapter->device_mode) )
6922 {
6923 return pAdapter;
6924 }
6925 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6926 pAdapterNode = pNext;
6927 }
6928
6929 return NULL;
6930
6931}
6932
6933//Remove this function later
6934hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
6935{
6936 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6937 hdd_adapter_t *pAdapter;
6938 VOS_STATUS status;
6939
6940 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6941
6942 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6943 {
6944 pAdapter = pAdapterNode->pAdapter;
6945
6946 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
6947 {
6948 return pAdapter;
6949 }
6950
6951 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6952 pAdapterNode = pNext;
6953 }
6954
6955 return NULL;
6956
6957}
6958
Jeff Johnson295189b2012-06-20 16:38:30 -07006959/**---------------------------------------------------------------------------
6960
6961 \brief hdd_set_monitor_tx_adapter() -
6962
6963 This API initializes the adapter to be used while transmitting on monitor
6964 adapter.
6965
6966 \param - pHddCtx - Pointer to the HDD context.
6967 pAdapter - Adapter that will used for TX. This can be NULL.
6968 \return - None.
6969 --------------------------------------------------------------------------*/
6970void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6971{
6972 hdd_adapter_t *pMonAdapter;
6973
6974 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
6975
6976 if( NULL != pMonAdapter )
6977 {
6978 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
6979 }
6980}
Jeff Johnson295189b2012-06-20 16:38:30 -07006981/**---------------------------------------------------------------------------
6982
6983 \brief hdd_select_queue() -
6984
6985 This API returns the operating channel of the requested device mode
6986
6987 \param - pHddCtx - Pointer to the HDD context.
6988 - mode - Device mode for which operating channel is required
6989 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
6990 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
6991 \return - channel number. "0" id the requested device is not found OR it is not connected.
6992 --------------------------------------------------------------------------*/
6993v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
6994{
6995 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6996 VOS_STATUS status;
6997 hdd_adapter_t *pAdapter;
6998 v_U8_t operatingChannel = 0;
6999
7000 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7001
7002 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7003 {
7004 pAdapter = pAdapterNode->pAdapter;
7005
7006 if( mode == pAdapter->device_mode )
7007 {
7008 switch(pAdapter->device_mode)
7009 {
7010 case WLAN_HDD_INFRA_STATION:
7011 case WLAN_HDD_P2P_CLIENT:
7012 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7013 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7014 break;
7015 case WLAN_HDD_SOFTAP:
7016 case WLAN_HDD_P2P_GO:
7017 /*softap connection info */
7018 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7019 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7020 break;
7021 default:
7022 break;
7023 }
7024
7025 break; //Found the device of interest. break the loop
7026 }
7027
7028 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7029 pAdapterNode = pNext;
7030 }
7031 return operatingChannel;
7032}
7033
7034#ifdef WLAN_FEATURE_PACKET_FILTERING
7035/**---------------------------------------------------------------------------
7036
7037 \brief hdd_set_multicast_list() -
7038
7039 This used to set the multicast address list.
7040
7041 \param - dev - Pointer to the WLAN device.
7042 - skb - Pointer to OS packet (sk_buff).
7043 \return - success/fail
7044
7045 --------------------------------------------------------------------------*/
7046static void hdd_set_multicast_list(struct net_device *dev)
7047{
7048 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007049 int mc_count;
7050 int i = 0;
7051 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307052
7053 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007054 {
7055 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307056 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007057 return;
7058 }
7059
7060 if (dev->flags & IFF_ALLMULTI)
7061 {
7062 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007063 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307064 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007065 }
7066 else
7067 {
7068 mc_count = netdev_mc_count(dev);
7069 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007070 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007071 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7072 {
7073 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007074 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307075 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007076 return;
7077 }
7078
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307079 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007080
7081 netdev_for_each_mc_addr(ha, dev) {
7082 if (i == mc_count)
7083 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307084 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7085 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007086 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007087 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307088 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007089 i++;
7090 }
7091 }
7092 return;
7093}
7094#endif
7095
7096/**---------------------------------------------------------------------------
7097
7098 \brief hdd_select_queue() -
7099
7100 This function is registered with the Linux OS for network
7101 core to decide which queue to use first.
7102
7103 \param - dev - Pointer to the WLAN device.
7104 - skb - Pointer to OS packet (sk_buff).
7105 \return - ac, Queue Index/access category corresponding to UP in IP header
7106
7107 --------------------------------------------------------------------------*/
7108v_U16_t hdd_select_queue(struct net_device *dev,
7109 struct sk_buff *skb)
7110{
7111 return hdd_wmm_select_queue(dev, skb);
7112}
7113
7114
7115/**---------------------------------------------------------------------------
7116
7117 \brief hdd_wlan_initial_scan() -
7118
7119 This function triggers the initial scan
7120
7121 \param - pAdapter - Pointer to the HDD adapter.
7122
7123 --------------------------------------------------------------------------*/
7124void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
7125{
7126 tCsrScanRequest scanReq;
7127 tCsrChannelInfo channelInfo;
7128 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07007129 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007130 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7131
7132 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
7133 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
7134 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
7135
7136 if(sme_Is11dSupported(pHddCtx->hHal))
7137 {
7138 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
7139 if ( HAL_STATUS_SUCCESS( halStatus ) )
7140 {
7141 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
7142 if( !scanReq.ChannelInfo.ChannelList )
7143 {
7144 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
7145 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007146 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007147 return;
7148 }
7149 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
7150 channelInfo.numOfChannels);
7151 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
7152 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007153 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007154 }
7155
7156 scanReq.scanType = eSIR_PASSIVE_SCAN;
7157 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
7158 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
7159 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
7160 }
7161 else
7162 {
7163 scanReq.scanType = eSIR_ACTIVE_SCAN;
7164 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
7165 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
7166 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
7167 }
7168
7169 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
7170 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7171 {
7172 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
7173 __func__, halStatus );
7174 }
7175
7176 if(sme_Is11dSupported(pHddCtx->hHal))
7177 vos_mem_free(scanReq.ChannelInfo.ChannelList);
7178}
7179
Jeff Johnson295189b2012-06-20 16:38:30 -07007180/**---------------------------------------------------------------------------
7181
7182 \brief hdd_full_power_callback() - HDD full power callback function
7183
7184 This is the function invoked by SME to inform the result of a full power
7185 request issued by HDD
7186
7187 \param - callbackcontext - Pointer to cookie
7188 \param - status - result of request
7189
7190 \return - None
7191
7192 --------------------------------------------------------------------------*/
7193static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
7194{
Jeff Johnson72a40512013-12-19 10:14:15 -08007195 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007196
7197 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307198 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007199
7200 if (NULL == callbackContext)
7201 {
7202 hddLog(VOS_TRACE_LEVEL_ERROR,
7203 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007204 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07007205 return;
7206 }
7207
Jeff Johnson72a40512013-12-19 10:14:15 -08007208 /* there is a race condition that exists between this callback
7209 function and the caller since the caller could time out either
7210 before or while this code is executing. we use a spinlock to
7211 serialize these actions */
7212 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007213
7214 if (POWER_CONTEXT_MAGIC != pContext->magic)
7215 {
7216 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08007217 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007218 hddLog(VOS_TRACE_LEVEL_WARN,
7219 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007220 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07007221 return;
7222 }
7223
Jeff Johnson72a40512013-12-19 10:14:15 -08007224 /* context is valid so caller is still waiting */
7225
7226 /* paranoia: invalidate the magic */
7227 pContext->magic = 0;
7228
7229 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07007230 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08007231
7232 /* serialization is complete */
7233 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007234}
7235
7236/**---------------------------------------------------------------------------
7237
7238 \brief hdd_wlan_exit() - HDD WLAN exit function
7239
7240 This is the driver exit point (invoked during rmmod)
7241
7242 \param - pHddCtx - Pointer to the HDD Context
7243
7244 \return - None
7245
7246 --------------------------------------------------------------------------*/
7247void hdd_wlan_exit(hdd_context_t *pHddCtx)
7248{
7249 eHalStatus halStatus;
7250 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
7251 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05307252 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007253 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08007254 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007255 long lrc;
7256
7257 ENTER();
7258
Jeff Johnson88ba7742013-02-27 14:36:02 -08007259 if (VOS_FTM_MODE != hdd_get_conparam())
7260 {
7261 // Unloading, restart logic is no more required.
7262 wlan_hdd_restart_deinit(pHddCtx);
7263 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007264
Jeff Johnson295189b2012-06-20 16:38:30 -07007265 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007266 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007267 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007268 {
7269 hdd_adapter_t* pAdapter = hdd_get_adapter(pHddCtx,
7270 WLAN_HDD_INFRA_STATION);
7271 if (pAdapter == NULL)
7272 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
7273
7274 if (pAdapter != NULL)
7275 {
7276 wlan_hdd_cfg80211_pre_voss_stop(pAdapter);
7277 hdd_UnregisterWext(pAdapter->dev);
7278 }
7279 }
7280 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007281
Jeff Johnson295189b2012-06-20 16:38:30 -07007282 if (VOS_FTM_MODE == hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08007283 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307284 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Jeff Johnson88ba7742013-02-27 14:36:02 -08007285 wlan_hdd_ftm_close(pHddCtx);
7286 goto free_hdd_ctx;
7287 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007288 //Stop the Interface TX queue.
7289 //netif_tx_disable(pWlanDev);
7290 //netif_carrier_off(pWlanDev);
7291
Jeff Johnson295189b2012-06-20 16:38:30 -07007292 if (VOS_STA_SAP_MODE == hdd_get_conparam())
7293 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307294 hddLog(VOS_TRACE_LEVEL_INFO,"%s: SAP MODE",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007295 pAdapter = hdd_get_adapter(pHddCtx,
7296 WLAN_HDD_SOFTAP);
7297 }
7298 else
7299 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007300 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007301 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307302 hddLog(VOS_TRACE_LEVEL_INFO,"%s: STA MODE",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007303 pAdapter = hdd_get_adapter(pHddCtx,
7304 WLAN_HDD_INFRA_STATION);
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007305 if (pAdapter == NULL)
7306 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_IBSS);
Jeff Johnson295189b2012-06-20 16:38:30 -07007307 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007308 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307309
7310 if(NULL == pAdapter)
7311 {
7312 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: pAdapter is NULL",__func__);
7313 goto free_hdd_ctx;
7314 }
7315
Jeff Johnson295189b2012-06-20 16:38:30 -07007316 /* DeRegister with platform driver as client for Suspend/Resume */
7317 vosStatus = hddDeregisterPmOps(pHddCtx);
7318 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7319 {
7320 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
7321 VOS_ASSERT(0);
7322 }
7323
7324 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
7325 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7326 {
7327 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
7328 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007329
7330 // Cancel any outstanding scan requests. We are about to close all
7331 // of our adapters, but an adapter structure is what SME passes back
7332 // to our callback function. Hence if there are any outstanding scan
7333 // requests then there is a race condition between when the adapter
7334 // is closed and when the callback is invoked. We try to resolve that
7335 // race condition here by canceling any outstanding scans before we
7336 // close the adapters.
7337 // Note that the scans may be cancelled in an asynchronous manner, so
7338 // ideally there needs to be some kind of synchronization. Rather than
7339 // introduce a new synchronization here, we will utilize the fact that
7340 // we are about to Request Full Power, and since that is synchronized,
7341 // the expectation is that by the time Request Full Power has completed,
7342 // all scans will be cancelled.
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007343 if (NULL != pAdapter)
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307344 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId, eCSR_SCAN_ABORT_DEFAULT);
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007345 else
7346 hddLog(VOS_TRACE_LEVEL_ERROR,
7347 "%s: pAdapter is NULL, cannot Abort scan", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007348
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07007349 //Stop the traffic monitor timer
7350 if ( VOS_TIMER_STATE_RUNNING ==
7351 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
7352 {
7353 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
7354 }
7355
7356 // Destroy the traffic monitor timer
7357 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
7358 &pHddCtx->tx_rx_trafficTmr)))
7359 {
7360 hddLog(VOS_TRACE_LEVEL_ERROR,
7361 "%s: Cannot deallocate Traffic monitor timer", __func__);
7362 }
7363
Jeff Johnson295189b2012-06-20 16:38:30 -07007364 //Disable IMPS/BMPS as we do not want the device to enter any power
7365 //save mode during shutdown
7366 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
7367 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
7368 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
7369
7370 //Ensure that device is in full power as we will touch H/W during vos_Stop
7371 init_completion(&powerContext.completion);
7372 powerContext.magic = POWER_CONTEXT_MAGIC;
7373
7374 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
7375 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
7376
7377 if (eHAL_STATUS_SUCCESS != halStatus)
7378 {
7379 if (eHAL_STATUS_PMC_PENDING == halStatus)
7380 {
7381 /* request was sent -- wait for the response */
7382 lrc = wait_for_completion_interruptible_timeout(
7383 &powerContext.completion,
7384 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07007385 if (lrc <= 0)
7386 {
7387 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007388 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07007389 }
7390 }
7391 else
7392 {
7393 hddLog(VOS_TRACE_LEVEL_ERROR,
7394 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007395 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07007396 /* continue -- need to clean up as much as possible */
7397 }
7398 }
7399
Jeff Johnson72a40512013-12-19 10:14:15 -08007400 /* either we never sent a request, we sent a request and received a
7401 response or we sent a request and timed out. if we never sent a
7402 request or if we sent a request and got a response, we want to
7403 clear the magic out of paranoia. if we timed out there is a
7404 race condition such that the callback function could be
7405 executing at the same time we are. of primary concern is if the
7406 callback function had already verified the "magic" but had not
7407 yet set the completion variable when a timeout occurred. we
7408 serialize these activities by invalidating the magic while
7409 holding a shared spinlock which will cause us to block if the
7410 callback is currently executing */
7411 spin_lock(&hdd_context_lock);
7412 powerContext.magic = 0;
7413 spin_unlock(&hdd_context_lock);
7414
Yue Ma0d4891e2013-08-06 17:01:45 -07007415 hdd_debugfs_exit(pHddCtx);
7416
Jeff Johnson295189b2012-06-20 16:38:30 -07007417 // Unregister the Net Device Notifier
7418 unregister_netdevice_notifier(&hdd_netdev_notifier);
7419
Jeff Johnson295189b2012-06-20 16:38:30 -07007420 hdd_stop_all_adapters( pHddCtx );
7421
Jeff Johnson295189b2012-06-20 16:38:30 -07007422#ifdef WLAN_BTAMP_FEATURE
7423 vosStatus = WLANBAP_Stop(pVosContext);
7424 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7425 {
7426 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7427 "%s: Failed to stop BAP",__func__);
7428 }
7429#endif //WLAN_BTAMP_FEATURE
7430
7431 //Stop all the modules
7432 vosStatus = vos_stop( pVosContext );
7433 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7434 {
7435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7436 "%s: Failed to stop VOSS",__func__);
7437 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7438 }
7439
Jeff Johnson295189b2012-06-20 16:38:30 -07007440 //Assert Deep sleep signal now to put Libra HW in lowest power state
7441 vosStatus = vos_chipAssertDeepSleep( NULL, NULL, NULL );
7442 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7443
7444 //Vote off any PMIC voltage supplies
7445 vos_chipPowerDown(NULL, NULL, NULL);
7446
7447 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
7448
Leo Chang59cdc7e2013-07-10 10:08:21 -07007449
Jeff Johnson295189b2012-06-20 16:38:30 -07007450 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07007451 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007452
7453 //Close the scheduler before calling vos_close to make sure no thread is
7454 // scheduled after the each module close is called i.e after all the data
7455 // structures are freed.
7456 vosStatus = vos_sched_close( pVosContext );
7457 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
7458 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
7459 "%s: Failed to close VOSS Scheduler",__func__);
7460 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7461 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007462#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07007463#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
7464 /* Destroy the wake lock */
7465 wake_lock_destroy(&pHddCtx->rx_wake_lock);
7466#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08007467 /* Destroy the wake lock */
7468 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007469#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007470
Mihir Shete7a24b5f2013-12-21 12:18:31 +05307471#ifdef CONFIG_ENABLE_LINUX_REG
7472 vosStatus = vos_nv_close();
7473 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7474 {
7475 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7476 "%s: Failed to close NV", __func__);
7477 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7478 }
7479#endif
7480
Jeff Johnson295189b2012-06-20 16:38:30 -07007481 //Close VOSS
7482 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
7483 vos_close(pVosContext);
7484
Jeff Johnson295189b2012-06-20 16:38:30 -07007485 //Close Watchdog
7486 if(pHddCtx->cfg_ini->fIsLogpEnabled)
7487 vos_watchdog_close(pVosContext);
7488
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307489 //Clean up HDD Nlink Service
7490 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07007491#ifdef WLAN_KD_READY_NOTIFIER
7492 nl_srv_exit(pHddCtx->ptt_pid);
7493#else
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307494 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07007495#endif /* WLAN_KD_READY_NOTIFIER */
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307496
Jeff Johnson295189b2012-06-20 16:38:30 -07007497 /* Cancel the vote for XO Core ON.
7498 * This is done here to ensure there is no race condition since MC, TX and WD threads have
7499 * exited at this point
7500 */
7501 hddLog(VOS_TRACE_LEVEL_WARN, "In module exit: Cancel the vote for XO Core ON"
Arif Hussain6d2a3322013-11-17 19:50:10 -08007502 " when WLAN is turned OFF");
Jeff Johnson295189b2012-06-20 16:38:30 -07007503 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
7504 {
7505 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel the vote for XO Core ON."
7506 " Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08007507 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07007508 }
7509
7510 hdd_close_all_adapters( pHddCtx );
7511
7512
7513 //Free up dynamically allocated members inside HDD Adapter
7514 kfree(pHddCtx->cfg_ini);
7515 pHddCtx->cfg_ini= NULL;
7516
7517 /* free the power on lock from platform driver */
7518 if (free_riva_power_on_lock("wlan"))
7519 {
7520 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
7521 __func__);
7522 }
7523
Jeff Johnson88ba7742013-02-27 14:36:02 -08007524free_hdd_ctx:
Leo Changf04ddad2013-09-18 13:46:38 -07007525 /* FTM mode, WIPHY did not registered
7526 If un-register here, system crash will happen */
7527 if (VOS_FTM_MODE != hdd_get_conparam())
7528 {
7529 wiphy_unregister(wiphy) ;
7530 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007531 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007532 if (hdd_is_ssr_required())
7533 {
7534 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07007535 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07007536 msleep(5000);
7537 }
7538 hdd_set_ssr_required (VOS_FALSE);
7539}
7540
7541
7542/**---------------------------------------------------------------------------
7543
7544 \brief hdd_update_config_from_nv() - Function to update the contents of
7545 the running configuration with parameters taken from NV storage
7546
7547 \param - pHddCtx - Pointer to the HDD global context
7548
7549 \return - VOS_STATUS_SUCCESS if successful
7550
7551 --------------------------------------------------------------------------*/
7552static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
7553{
Jeff Johnson295189b2012-06-20 16:38:30 -07007554 v_BOOL_t itemIsValid = VOS_FALSE;
7555 VOS_STATUS status;
7556 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
7557 v_U8_t macLoop;
7558
7559 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
7560 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
7561 if(status != VOS_STATUS_SUCCESS)
7562 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007563 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007564 return VOS_STATUS_E_FAILURE;
7565 }
7566
7567 if (itemIsValid == VOS_TRUE)
7568 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007569 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07007570 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
7571 VOS_MAX_CONCURRENCY_PERSONA);
7572 if(status != VOS_STATUS_SUCCESS)
7573 {
7574 /* Get MAC from NV fail, not update CFG info
7575 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08007576 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007577 return VOS_STATUS_E_FAILURE;
7578 }
7579
7580 /* If first MAC is not valid, treat all others are not valid
7581 * Then all MACs will be got from ini file */
7582 if(vos_is_macaddr_zero(&macFromNV[0]))
7583 {
7584 /* MAC address in NV file is not configured yet */
7585 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
7586 return VOS_STATUS_E_INVAL;
7587 }
7588
7589 /* Get MAC address from NV, update CFG info */
7590 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
7591 {
7592 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
7593 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307594 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07007595 /* This MAC is not valid, skip it
7596 * This MAC will be got from ini file */
7597 }
7598 else
7599 {
7600 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
7601 (v_U8_t *)&macFromNV[macLoop].bytes[0],
7602 VOS_MAC_ADDR_SIZE);
7603 }
7604 }
7605 }
7606 else
7607 {
7608 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
7609 return VOS_STATUS_E_FAILURE;
7610 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007611
Jeff Johnson295189b2012-06-20 16:38:30 -07007612
7613 return VOS_STATUS_SUCCESS;
7614}
7615
7616/**---------------------------------------------------------------------------
7617
7618 \brief hdd_post_voss_start_config() - HDD post voss start config helper
7619
7620 \param - pAdapter - Pointer to the HDD
7621
7622 \return - None
7623
7624 --------------------------------------------------------------------------*/
7625VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
7626{
7627 eHalStatus halStatus;
7628 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307629 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07007630
Jeff Johnson295189b2012-06-20 16:38:30 -07007631
7632 // Send ready indication to the HDD. This will kick off the MAC
7633 // into a 'running' state and should kick off an initial scan.
7634 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
7635 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7636 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307637 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07007638 "code %08d [x%08x]",__func__, halStatus, halStatus );
7639 return VOS_STATUS_E_FAILURE;
7640 }
7641
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307642 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07007643 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
7644 // And RIVA will crash
7645 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
7646 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307647 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
7648 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
7649
7650
Jeff Johnson295189b2012-06-20 16:38:30 -07007651 return VOS_STATUS_SUCCESS;
7652}
7653
Jeff Johnson295189b2012-06-20 16:38:30 -07007654/* wake lock APIs for HDD */
7655void hdd_prevent_suspend(void)
7656{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007657#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007658 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007659#else
7660 wcnss_prevent_suspend();
7661#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007662}
7663
7664void hdd_allow_suspend(void)
7665{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007666#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007667 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007668#else
7669 wcnss_allow_suspend();
7670#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007671}
7672
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05307673void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07007674{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007675#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07007676 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07007677#else
7678 /* Do nothing as there is no API in wcnss for timeout*/
7679#endif
7680}
7681
Jeff Johnson295189b2012-06-20 16:38:30 -07007682/**---------------------------------------------------------------------------
7683
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007684 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
7685 information between Host and Riva
7686
7687 This function gets reported version of FW
7688 It also finds the version of Riva headers used to compile the host
7689 It compares the above two and prints a warning if they are different
7690 It gets the SW and HW version string
7691 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
7692 indicating the features they support through a bitmap
7693
7694 \param - pHddCtx - Pointer to HDD context
7695
7696 \return - void
7697
7698 --------------------------------------------------------------------------*/
7699
7700void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
7701{
7702
7703 tSirVersionType versionCompiled;
7704 tSirVersionType versionReported;
7705 tSirVersionString versionString;
7706 tANI_U8 fwFeatCapsMsgSupported = 0;
7707 VOS_STATUS vstatus;
7708
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007709 memset(&versionCompiled, 0, sizeof(versionCompiled));
7710 memset(&versionReported, 0, sizeof(versionReported));
7711
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007712 /* retrieve and display WCNSS version information */
7713 do {
7714
7715 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
7716 &versionCompiled);
7717 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7718 {
7719 hddLog(VOS_TRACE_LEVEL_FATAL,
7720 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007721 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007722 break;
7723 }
7724
7725 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
7726 &versionReported);
7727 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7728 {
7729 hddLog(VOS_TRACE_LEVEL_FATAL,
7730 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007731 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007732 break;
7733 }
7734
7735 if ((versionCompiled.major != versionReported.major) ||
7736 (versionCompiled.minor != versionReported.minor) ||
7737 (versionCompiled.version != versionReported.version) ||
7738 (versionCompiled.revision != versionReported.revision))
7739 {
7740 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
7741 "Host expected %u.%u.%u.%u\n",
7742 WLAN_MODULE_NAME,
7743 (int)versionReported.major,
7744 (int)versionReported.minor,
7745 (int)versionReported.version,
7746 (int)versionReported.revision,
7747 (int)versionCompiled.major,
7748 (int)versionCompiled.minor,
7749 (int)versionCompiled.version,
7750 (int)versionCompiled.revision);
7751 }
7752 else
7753 {
7754 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
7755 WLAN_MODULE_NAME,
7756 (int)versionReported.major,
7757 (int)versionReported.minor,
7758 (int)versionReported.version,
7759 (int)versionReported.revision);
7760 }
7761
7762 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
7763 versionString,
7764 sizeof(versionString));
7765 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7766 {
7767 hddLog(VOS_TRACE_LEVEL_FATAL,
7768 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007769 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007770 break;
7771 }
7772
7773 pr_info("%s: WCNSS software version %s\n",
7774 WLAN_MODULE_NAME, versionString);
7775
7776 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
7777 versionString,
7778 sizeof(versionString));
7779 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7780 {
7781 hddLog(VOS_TRACE_LEVEL_FATAL,
7782 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007783 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007784 break;
7785 }
7786
7787 pr_info("%s: WCNSS hardware version %s\n",
7788 WLAN_MODULE_NAME, versionString);
7789
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07007790 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
7791 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007792 send the message only if it the riva is 1.1
7793 minor numbers for different riva branches:
7794 0 -> (1.0)Mainline Build
7795 1 -> (1.1)Mainline Build
7796 2->(1.04) Stability Build
7797 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07007798 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007799 ((versionReported.minor>=1) && (versionReported.version>=1)))
7800 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
7801 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07007802
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007803 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08007804 {
7805#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
7806 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
7807 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
7808#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07007809 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
7810 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
7811 {
7812 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
7813 }
7814
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007815 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08007816 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007817
7818 } while (0);
7819
7820}
7821
7822/**---------------------------------------------------------------------------
7823
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307824 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
7825
7826 \param - pHddCtx - Pointer to the hdd context
7827
7828 \return - true if hardware supports 5GHz
7829
7830 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307831boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307832{
7833 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
7834 * then hardware support 5Ghz.
7835 */
7836 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
7837 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05307838 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307839 return true;
7840 }
7841 else
7842 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05307843 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307844 __func__);
7845 return false;
7846 }
7847}
7848
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05307849/**---------------------------------------------------------------------------
7850
7851 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
7852 generate function
7853
7854 This is generate the random mac address for WLAN interface
7855
7856 \param - pHddCtx - Pointer to HDD context
7857 idx - Start interface index to get auto
7858 generated mac addr.
7859 mac_addr - Mac address
7860
7861 \return - 0 for success, < 0 for failure
7862
7863 --------------------------------------------------------------------------*/
7864
7865static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
7866 int idx, v_MACADDR_t mac_addr)
7867{
7868 int i;
7869 unsigned int serialno;
7870 serialno = wcnss_get_serial_number();
7871
7872 if (0 != serialno)
7873 {
7874 /* MAC address has 3 bytes of OUI so we have a maximum of 3
7875 bytes of the serial number that can be used to generate
7876 the other 3 bytes of the MAC address. Mask off all but
7877 the lower 3 bytes (this will also make sure we don't
7878 overflow in the next step) */
7879 serialno &= 0x00FFFFFF;
7880
7881 /* we need a unique address for each session */
7882 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
7883
7884 /* autogen other Mac addresses */
7885 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
7886 {
7887 /* start with the entire default address */
7888 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
7889 /* then replace the lower 3 bytes */
7890 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
7891 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
7892 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
7893
7894 serialno++;
7895 hddLog(VOS_TRACE_LEVEL_ERROR,
7896 "%s: Derived Mac Addr: "
7897 MAC_ADDRESS_STR, __func__,
7898 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
7899 }
7900
7901 }
7902 else
7903 {
7904 hddLog(LOGE, FL("Failed to Get Serial NO"));
7905 return -1;
7906 }
7907 return 0;
7908}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307909
7910/**---------------------------------------------------------------------------
7911
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05307912 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
7913 completed to flush out the scan results
7914
7915 11d scan is done during driver load and is a passive scan on all
7916 channels supported by the device, 11d scans may find some APs on
7917 frequencies which are forbidden to be used in the regulatory domain
7918 the device is operating in. If these APs are notified to the supplicant
7919 it may try to connect to these APs, thus flush out all the scan results
7920 which are present in SME after 11d scan is done.
7921
7922 \return - eHalStatus
7923
7924 --------------------------------------------------------------------------*/
7925static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
7926 tANI_U32 scanId, eCsrScanStatus status)
7927{
7928 ENTER();
7929
7930 sme_ScanFlushResult(halHandle, 0);
7931
7932 EXIT();
7933
7934 return eHAL_STATUS_SUCCESS;
7935}
7936
7937/**---------------------------------------------------------------------------
7938
Jeff Johnson295189b2012-06-20 16:38:30 -07007939 \brief hdd_wlan_startup() - HDD init function
7940
7941 This is the driver startup code executed once a WLAN device has been detected
7942
7943 \param - dev - Pointer to the underlying device
7944
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08007945 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07007946
7947 --------------------------------------------------------------------------*/
7948
7949int hdd_wlan_startup(struct device *dev )
7950{
7951 VOS_STATUS status;
7952 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07007953 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007954 hdd_context_t *pHddCtx = NULL;
7955 v_CONTEXT_t pVosContext= NULL;
7956#ifdef WLAN_BTAMP_FEATURE
7957 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
7958 WLANBAP_ConfigType btAmpConfig;
7959 hdd_config_t *pConfig;
7960#endif
7961 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007962 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05307963 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07007964
7965 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007966 /*
7967 * cfg80211: wiphy allocation
7968 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307969 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007970
7971 if(wiphy == NULL)
7972 {
7973 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08007974 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007975 }
7976
7977 pHddCtx = wiphy_priv(wiphy);
7978
Jeff Johnson295189b2012-06-20 16:38:30 -07007979 //Initialize the adapter context to zeros.
7980 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
7981
Jeff Johnson295189b2012-06-20 16:38:30 -07007982 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07007983 hdd_prevent_suspend();
7984 pHddCtx->isLoadUnloadInProgress = TRUE;
7985
7986 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
7987
7988 /*Get vos context here bcoz vos_open requires it*/
7989 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
7990
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08007991 if(pVosContext == NULL)
7992 {
7993 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
7994 goto err_free_hdd_context;
7995 }
7996
Jeff Johnson295189b2012-06-20 16:38:30 -07007997 //Save the Global VOSS context in adapter context for future.
7998 pHddCtx->pvosContext = pVosContext;
7999
8000 //Save the adapter context in global context for future.
8001 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8002
Jeff Johnson295189b2012-06-20 16:38:30 -07008003 pHddCtx->parent_dev = dev;
8004
8005 init_completion(&pHddCtx->full_pwr_comp_var);
8006 init_completion(&pHddCtx->standby_comp_var);
8007 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008008 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008009 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308010 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308011 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008012
8013#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008014 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008015#else
8016 init_completion(&pHddCtx->driver_crda_req);
8017#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008018
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308019 spin_lock_init(&pHddCtx->schedScan_lock);
8020
Jeff Johnson295189b2012-06-20 16:38:30 -07008021 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8022
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308023#ifdef FEATURE_WLAN_TDLS
8024 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8025 * invoked by other instances also) to protect the concurrent
8026 * access for the Adapters by TDLS module.
8027 */
8028 mutex_init(&pHddCtx->tdls_lock);
8029#endif
8030
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308031 pHddCtx->nEnableStrictRegulatoryForFCC = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008032 // Load all config first as TL config is needed during vos_open
8033 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8034 if(pHddCtx->cfg_ini == NULL)
8035 {
8036 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8037 goto err_free_hdd_context;
8038 }
8039
8040 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8041
8042 // Read and parse the qcom_cfg.ini file
8043 status = hdd_parse_config_ini( pHddCtx );
8044 if ( VOS_STATUS_SUCCESS != status )
8045 {
8046 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
8047 __func__, WLAN_INI_FILE);
8048 goto err_config;
8049 }
Arif Hussaind5218912013-12-05 01:10:55 -08008050#ifdef MEMORY_DEBUG
8051 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
8052 vos_mem_init();
8053
8054 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
8055 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
8056#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008057
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05308058 /* INI has been read, initialise the configuredMcastBcastFilter with
8059 * INI value as this will serve as the default value
8060 */
8061 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
8062 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
8063 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308064
8065 if (false == hdd_is_5g_supported(pHddCtx))
8066 {
8067 //5Ghz is not supported.
8068 if (1 != pHddCtx->cfg_ini->nBandCapability)
8069 {
8070 hddLog(VOS_TRACE_LEVEL_INFO,
8071 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
8072 pHddCtx->cfg_ini->nBandCapability = 1;
8073 }
8074 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308075
8076 /* If SNR Monitoring is enabled, FW has to parse all beacons
8077 * for calcaluting and storing the average SNR, so set Nth beacon
8078 * filter to 1 to enable FW to parse all the beaocons
8079 */
8080 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
8081 {
8082 /* The log level is deliberately set to WARN as overriding
8083 * nthBeaconFilter to 1 will increase power cosumption and this
8084 * might just prove helpful to detect the power issue.
8085 */
8086 hddLog(VOS_TRACE_LEVEL_WARN,
8087 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
8088 pHddCtx->cfg_ini->nthBeaconFilter = 1;
8089 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008090 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308091 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07008092 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008093 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008094 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008095 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
8096 {
8097 hddLog(VOS_TRACE_LEVEL_FATAL,
8098 "%s: wlan_hdd_cfg80211_init return failure", __func__);
8099 goto err_config;
8100 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008101 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008102
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008103 // Update VOS trace levels based upon the cfg.ini
8104 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
8105 pHddCtx->cfg_ini->vosTraceEnableBAP);
8106 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
8107 pHddCtx->cfg_ini->vosTraceEnableTL);
8108 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
8109 pHddCtx->cfg_ini->vosTraceEnableWDI);
8110 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
8111 pHddCtx->cfg_ini->vosTraceEnableHDD);
8112 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
8113 pHddCtx->cfg_ini->vosTraceEnableSME);
8114 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
8115 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05308116 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
8117 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008118 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
8119 pHddCtx->cfg_ini->vosTraceEnableWDA);
8120 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
8121 pHddCtx->cfg_ini->vosTraceEnableSYS);
8122 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
8123 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008124 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
8125 pHddCtx->cfg_ini->vosTraceEnableSAP);
8126 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
8127 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008128
Jeff Johnson295189b2012-06-20 16:38:30 -07008129 // Update WDI trace levels based upon the cfg.ini
8130 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
8131 pHddCtx->cfg_ini->wdiTraceEnableDAL);
8132 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
8133 pHddCtx->cfg_ini->wdiTraceEnableCTL);
8134 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
8135 pHddCtx->cfg_ini->wdiTraceEnableDAT);
8136 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
8137 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008138
Jeff Johnson88ba7742013-02-27 14:36:02 -08008139 if (VOS_FTM_MODE == hdd_get_conparam())
8140 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008141 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
8142 {
8143 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
8144 goto err_free_hdd_context;
8145 }
8146 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
8147 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08008148 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008149
Jeff Johnson88ba7742013-02-27 14:36:02 -08008150 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07008151 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8152 {
8153 status = vos_watchdog_open(pVosContext,
8154 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
8155
8156 if(!VOS_IS_STATUS_SUCCESS( status ))
8157 {
8158 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308159 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008160 }
8161 }
8162
8163 pHddCtx->isLogpInProgress = FALSE;
8164 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8165
Jeff Johnson295189b2012-06-20 16:38:30 -07008166 status = vos_chipVoteOnXOBuffer(NULL, NULL, NULL);
8167 if(!VOS_IS_STATUS_SUCCESS(status))
8168 {
8169 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to configure 19.2 MHz Clock", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008170 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008171 }
8172
Amar Singhala49cbc52013-10-08 18:37:44 -07008173#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008174 /* initialize the NV module. This is required so that
8175 we can initialize the channel information in wiphy
8176 from the NV.bin data. The channel information in
8177 wiphy needs to be initialized before wiphy registration */
8178
8179 status = vos_nv_open();
8180 if (!VOS_IS_STATUS_SUCCESS(status))
8181 {
8182 /* NV module cannot be initialized */
8183 hddLog( VOS_TRACE_LEVEL_FATAL,
8184 "%s: vos_nv_open failed", __func__);
8185 goto err_clkvote;
8186 }
8187
8188 status = vos_init_wiphy_from_nv_bin();
8189 if (!VOS_IS_STATUS_SUCCESS(status))
8190 {
8191 /* NV module cannot be initialized */
8192 hddLog( VOS_TRACE_LEVEL_FATAL,
8193 "%s: vos_init_wiphy failed", __func__);
8194 goto err_vos_nv_close;
8195 }
8196
Amar Singhala49cbc52013-10-08 18:37:44 -07008197#endif
8198
Jeff Johnson295189b2012-06-20 16:38:30 -07008199 status = vos_open( &pVosContext, 0);
8200 if ( !VOS_IS_STATUS_SUCCESS( status ))
8201 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008202 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308203 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07008204 }
8205
Jeff Johnson295189b2012-06-20 16:38:30 -07008206 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
8207
8208 if ( NULL == pHddCtx->hHal )
8209 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008210 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008211 goto err_vosclose;
8212 }
8213
Mihir Shetee1093ba2014-01-21 20:13:32 +05308214#ifdef CONFIG_ENABLE_LINUX_REG
8215 /* registration of wiphy dev with cfg80211 */
8216 if (0 > wlan_hdd_cfg80211_register(wiphy))
8217 {
8218 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8219 goto err_vosclose;
8220 }
8221
8222 status = wlan_hdd_init_channels(pHddCtx);
8223 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8224 {
8225 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
8226 __func__);
8227 goto err_wiphy_unregister;
8228 }
8229#endif
8230
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008231 status = vos_preStart( pHddCtx->pvosContext );
8232 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8233 {
8234 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308235 goto err_wiphy_unregister;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008236 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008237
Arif Hussaineaf68602013-12-30 23:10:44 -08008238 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
8239 {
8240 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
8241 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
8242 __func__, enable_dfs_chan_scan);
8243 }
8244 if (0 == enable_11d || 1 == enable_11d)
8245 {
8246 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
8247 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
8248 __func__, enable_11d);
8249 }
8250
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008251 /* Note that the vos_preStart() sequence triggers the cfg download.
8252 The cfg download must occur before we update the SME config
8253 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07008254 status = hdd_set_sme_config( pHddCtx );
8255
8256 if ( VOS_STATUS_SUCCESS != status )
8257 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008258 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308259 goto err_wiphy_unregister;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008260 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008261
8262 //Initialize the WMM module
8263 status = hdd_wmm_init(pHddCtx);
8264 if (!VOS_IS_STATUS_SUCCESS(status))
8265 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008266 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308267 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008268 }
8269
Jeff Johnson295189b2012-06-20 16:38:30 -07008270 /* In the integrated architecture we update the configuration from
8271 the INI file and from NV before vOSS has been started so that
8272 the final contents are available to send down to the cCPU */
8273
8274 // Apply the cfg.ini to cfg.dat
8275 if (FALSE == hdd_update_config_dat(pHddCtx))
8276 {
8277 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mihir Shetee1093ba2014-01-21 20:13:32 +05308278 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008279 }
8280
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308281 // Get mac addr from platform driver
8282 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
8283
8284 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008285 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308286 /* Store the mac addr for first interface */
8287 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
8288
8289 hddLog(VOS_TRACE_LEVEL_ERROR,
8290 "%s: WLAN Mac Addr: "
8291 MAC_ADDRESS_STR, __func__,
8292 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8293
8294 /* Here, passing Arg2 as 1 because we do not want to change the
8295 last 3 bytes (means non OUI bytes) of first interface mac
8296 addr.
8297 */
8298 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
8299 {
8300 hddLog(VOS_TRACE_LEVEL_ERROR,
8301 "%s: Failed to generate wlan interface mac addr "
8302 "using MAC from ini file ", __func__);
8303 }
8304 }
8305 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
8306 {
8307 // Apply the NV to cfg.dat
8308 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07008309#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
8310 /* There was not a valid set of MAC Addresses in NV. See if the
8311 default addresses were modified by the cfg.ini settings. If so,
8312 we'll use them, but if not, we'll autogenerate a set of MAC
8313 addresses based upon the device serial number */
8314
8315 static const v_MACADDR_t default_address =
8316 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07008317
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308318 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
8319 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008320 {
8321 /* cfg.ini has the default address, invoke autogen logic */
8322
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308323 /* Here, passing Arg2 as 0 because we want to change the
8324 last 3 bytes (means non OUI bytes) of all the interfaces
8325 mac addr.
8326 */
8327 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
8328 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07008329 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308330 hddLog(VOS_TRACE_LEVEL_ERROR,
8331 "%s: Failed to generate wlan interface mac addr "
8332 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
8333 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07008334 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008335 }
8336 else
8337#endif //WLAN_AUTOGEN_MACADDR_FEATURE
8338 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008339 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008340 "%s: Invalid MAC address in NV, using MAC from ini file "
8341 MAC_ADDRESS_STR, __func__,
8342 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8343 }
8344 }
8345 {
8346 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308347
8348 /* Set the MAC Address Currently this is used by HAL to
8349 * add self sta. Remove this once self sta is added as
8350 * part of session open.
8351 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008352 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
8353 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
8354 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308355
Jeff Johnson295189b2012-06-20 16:38:30 -07008356 if (!HAL_STATUS_SUCCESS( halStatus ))
8357 {
8358 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
8359 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mihir Shetee1093ba2014-01-21 20:13:32 +05308360 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008361 }
8362 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008363
8364 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
8365 Note: Firmware image will be read and downloaded inside vos_start API */
8366 status = vos_start( pHddCtx->pvosContext );
8367 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8368 {
8369 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308370 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008371 }
8372
Leo Chang6cec3e22014-01-21 15:33:49 -08008373#ifdef FEATURE_WLAN_CH_AVOID
8374 /* Plug in avoid channel notification callback
8375 * This should happen before ADD_SELF_STA
8376 * FW will send first IND with ADD_SELF_STA REQ from host */
8377 sme_AddChAvoidCallback(pHddCtx->hHal,
8378 hdd_hostapd_ch_avoid_cb);
8379#endif /* FEATURE_WLAN_CH_AVOID */
8380
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008381 /* Exchange capability info between Host and FW and also get versioning info from FW */
8382 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008383
8384 status = hdd_post_voss_start_config( pHddCtx );
8385 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8386 {
8387 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
8388 __func__);
8389 goto err_vosstop;
8390 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008391
8392#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308393 wlan_hdd_cfg80211_update_reg_info( wiphy );
8394
8395 /* registration of wiphy dev with cfg80211 */
8396 if (0 > wlan_hdd_cfg80211_register(wiphy))
8397 {
8398 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8399 goto err_vosstop;
8400 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008401#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008402
Jeff Johnson295189b2012-06-20 16:38:30 -07008403 if (VOS_STA_SAP_MODE == hdd_get_conparam())
8404 {
8405 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
8406 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8407 }
8408 else
8409 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008410 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
8411 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8412 if (pAdapter != NULL)
8413 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308414 if ( pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated )
Jeff Johnson295189b2012-06-20 16:38:30 -07008415 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308416 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
8417 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
8418 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07008419
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308420 /* Generate the P2P Device Address. This consists of the device's
8421 * primary MAC address with the locally administered bit set.
8422 */
8423 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07008424 }
8425 else
8426 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308427 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
8428 if (p2p_dev_addr != NULL)
8429 {
8430 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
8431 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
8432 }
8433 else
8434 {
8435 hddLog(VOS_TRACE_LEVEL_FATAL,
8436 "%s: Failed to allocate mac_address for p2p_device",
8437 __func__);
8438 goto err_close_adapter;
8439 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008440 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008441
8442 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
8443 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
8444 if ( NULL == pP2pAdapter )
8445 {
8446 hddLog(VOS_TRACE_LEVEL_FATAL,
8447 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008448 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008449 goto err_close_adapter;
8450 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008451 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008452 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008453
8454 if( pAdapter == NULL )
8455 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008456 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
8457 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008458 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008459
Arif Hussain66559122013-11-21 10:11:40 -08008460 if (country_code)
8461 {
8462 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08008463 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08008464 hdd_checkandupdate_dfssetting(pAdapter, country_code);
8465#ifndef CONFIG_ENABLE_LINUX_REG
8466 hdd_checkandupdate_phymode(pAdapter, country_code);
8467#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08008468 ret = sme_ChangeCountryCode(pHddCtx->hHal,
8469 (void *)(tSmeChangeCountryCallback)
8470 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08008471 country_code,
8472 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308473 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08008474 if (eHAL_STATUS_SUCCESS == ret)
8475 {
Arif Hussaincb607082013-12-20 11:57:42 -08008476 ret = wait_for_completion_interruptible_timeout(
8477 &pAdapter->change_country_code,
8478 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
8479
8480 if (0 >= ret)
8481 {
8482 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8483 "%s: SME while setting country code timed out", __func__);
8484 }
Arif Hussain66559122013-11-21 10:11:40 -08008485 }
8486 else
8487 {
Arif Hussaincb607082013-12-20 11:57:42 -08008488 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8489 "%s: SME Change Country code from module param fail ret=%d",
8490 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08008491 }
8492 }
8493
Jeff Johnson295189b2012-06-20 16:38:30 -07008494#ifdef WLAN_BTAMP_FEATURE
8495 vStatus = WLANBAP_Open(pVosContext);
8496 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8497 {
8498 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8499 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008500 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008501 }
8502
8503 vStatus = BSL_Init(pVosContext);
8504 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8505 {
8506 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8507 "%s: Failed to Init BSL",__func__);
8508 goto err_bap_close;
8509 }
8510 vStatus = WLANBAP_Start(pVosContext);
8511 if (!VOS_IS_STATUS_SUCCESS(vStatus))
8512 {
8513 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8514 "%s: Failed to start TL",__func__);
8515 goto err_bap_close;
8516 }
8517
8518 pConfig = pHddCtx->cfg_ini;
8519 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
8520 status = WLANBAP_SetConfig(&btAmpConfig);
8521
8522#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07008523
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07008524#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
8525 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
8526 {
8527 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
8528 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
8529 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
8530 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
8531 }
8532#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008533#ifdef FEATURE_WLAN_SCAN_PNO
8534 /*SME must send channel update configuration to RIVA*/
8535 sme_UpdateChannelConfig(pHddCtx->hHal);
8536#endif
8537
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308538 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
8539
Jeff Johnson295189b2012-06-20 16:38:30 -07008540 /* Register with platform driver as client for Suspend/Resume */
8541 status = hddRegisterPmOps(pHddCtx);
8542 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8543 {
8544 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
8545#ifdef WLAN_BTAMP_FEATURE
8546 goto err_bap_stop;
8547#else
Jeff Johnsone7245742012-09-05 17:12:55 -07008548 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008549#endif //WLAN_BTAMP_FEATURE
8550 }
8551
Yue Ma0d4891e2013-08-06 17:01:45 -07008552 /* Open debugfs interface */
8553 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
8554 {
8555 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8556 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07008557 }
8558
Jeff Johnson295189b2012-06-20 16:38:30 -07008559 /* Register TM level change handler function to the platform */
8560 status = hddDevTmRegisterNotifyCallback(pHddCtx);
8561 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8562 {
8563 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
8564 goto err_unregister_pmops;
8565 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008566
8567 /* register for riva power on lock to platform driver */
8568 if (req_riva_power_on_lock("wlan"))
8569 {
8570 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
8571 __func__);
8572 goto err_unregister_pmops;
8573 }
8574
Jeff Johnson295189b2012-06-20 16:38:30 -07008575 // register net device notifier for device change notification
8576 ret = register_netdevice_notifier(&hdd_netdev_notifier);
8577
8578 if(ret < 0)
8579 {
8580 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
8581 goto err_free_power_on_lock;
8582 }
8583
8584 //Initialize the nlink service
8585 if(nl_srv_init() != 0)
8586 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308587 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008588 goto err_reg_netdev;
8589 }
8590
Leo Chang4ce1cc52013-10-21 18:27:15 -07008591#ifdef WLAN_KD_READY_NOTIFIER
8592 pHddCtx->kd_nl_init = 1;
8593#endif /* WLAN_KD_READY_NOTIFIER */
8594
Jeff Johnson295189b2012-06-20 16:38:30 -07008595 //Initialize the BTC service
8596 if(btc_activate_service(pHddCtx) != 0)
8597 {
8598 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
8599 goto err_nl_srv;
8600 }
8601
8602#ifdef PTT_SOCK_SVC_ENABLE
8603 //Initialize the PTT service
8604 if(ptt_sock_activate_svc(pHddCtx) != 0)
8605 {
8606 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
8607 goto err_nl_srv;
8608 }
8609#endif
8610
Jeff Johnson295189b2012-06-20 16:38:30 -07008611 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008612 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008613 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07008614 /* Action frame registered in one adapter which will
8615 * applicable to all interfaces
8616 */
Madan Mohan Koyyalamudie233e292012-09-18 17:38:02 -07008617 wlan_hdd_cfg80211_post_voss_start(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008618 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008619
8620 mutex_init(&pHddCtx->sap_lock);
8621
8622 pHddCtx->isLoadUnloadInProgress = FALSE;
8623
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008624#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008625#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8626 /* Initialize the wake lcok */
8627 wake_lock_init(&pHddCtx->rx_wake_lock,
8628 WAKE_LOCK_SUSPEND,
8629 "qcom_rx_wakelock");
8630#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008631 /* Initialize the wake lcok */
8632 wake_lock_init(&pHddCtx->sap_wake_lock,
8633 WAKE_LOCK_SUSPEND,
8634 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008635#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008636
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008637 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
8638 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07008639
8640 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8641 hdd_allow_suspend();
Abhishek Singha306a442013-11-07 18:39:01 +05308642#ifndef CONFIG_ENABLE_LINUX_REG
8643 /*updating wiphy so that regulatory user hints can be processed*/
8644 if (wiphy)
8645 {
8646 regulatory_hint(wiphy, "00");
8647 }
8648#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008649 // Initialize the restart logic
8650 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05308651
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008652 //Register the traffic monitor timer now
8653 if ( pHddCtx->cfg_ini->dynSplitscan)
8654 {
8655 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
8656 VOS_TIMER_TYPE_SW,
8657 hdd_tx_rx_pkt_cnt_stat_timer_handler,
8658 (void *)pHddCtx);
8659 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008660 goto success;
8661
8662err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07008663#ifdef WLAN_KD_READY_NOTIFIER
8664 nl_srv_exit(pHddCtx->ptt_pid);
8665#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008666 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07008667#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07008668err_reg_netdev:
8669 unregister_netdevice_notifier(&hdd_netdev_notifier);
8670
8671err_free_power_on_lock:
8672 free_riva_power_on_lock("wlan");
8673
8674err_unregister_pmops:
8675 hddDevTmUnregisterNotifyCallback(pHddCtx);
8676 hddDeregisterPmOps(pHddCtx);
8677
Yue Ma0d4891e2013-08-06 17:01:45 -07008678 hdd_debugfs_exit(pHddCtx);
8679
Jeff Johnson295189b2012-06-20 16:38:30 -07008680#ifdef WLAN_BTAMP_FEATURE
8681err_bap_stop:
8682 WLANBAP_Stop(pVosContext);
8683#endif
8684
8685#ifdef WLAN_BTAMP_FEATURE
8686err_bap_close:
8687 WLANBAP_Close(pVosContext);
8688#endif
8689
Jeff Johnson295189b2012-06-20 16:38:30 -07008690err_close_adapter:
8691 hdd_close_all_adapters( pHddCtx );
Amar Singhala49cbc52013-10-08 18:37:44 -07008692
8693#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308694 wiphy_unregister(wiphy) ;
Amar Singhala49cbc52013-10-08 18:37:44 -07008695#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008696
8697err_vosstop:
8698 vos_stop(pVosContext);
8699
Mihir Shetee1093ba2014-01-21 20:13:32 +05308700err_wiphy_unregister:
8701#ifdef CONFIG_ENABLE_LINUX_REG
8702 wiphy_unregister(wiphy);
8703#endif
8704
Amar Singhala49cbc52013-10-08 18:37:44 -07008705err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07008706 status = vos_sched_close( pVosContext );
8707 if (!VOS_IS_STATUS_SUCCESS(status)) {
8708 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8709 "%s: Failed to close VOSS Scheduler", __func__);
8710 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
8711 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008712 vos_close(pVosContext );
8713
Amar Singhala49cbc52013-10-08 18:37:44 -07008714#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008715err_vos_nv_close:
8716
8717 vos_nv_close();
8718
Jeff Johnson295189b2012-06-20 16:38:30 -07008719err_clkvote:
Amar Singhala49cbc52013-10-08 18:37:44 -07008720#endif
8721
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008722 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008723
8724err_wdclose:
8725 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8726 vos_watchdog_close(pVosContext);
8727
Jeff Johnson295189b2012-06-20 16:38:30 -07008728err_config:
8729 kfree(pHddCtx->cfg_ini);
8730 pHddCtx->cfg_ini= NULL;
8731
8732err_free_hdd_context:
8733 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07008734 wiphy_free(wiphy) ;
8735 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008736 VOS_BUG(1);
8737
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08008738 if (hdd_is_ssr_required())
8739 {
8740 /* WDI timeout had happened during load, so SSR is needed here */
8741 subsystem_restart("wcnss");
8742 msleep(5000);
8743 }
8744 hdd_set_ssr_required (VOS_FALSE);
8745
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008746 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008747
8748success:
8749 EXIT();
8750 return 0;
8751}
8752
8753/**---------------------------------------------------------------------------
8754
Jeff Johnson32d95a32012-09-10 13:15:23 -07008755 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07008756
Jeff Johnson32d95a32012-09-10 13:15:23 -07008757 This is the driver entry point - called in different timeline depending
8758 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07008759
8760 \param - None
8761
8762 \return - 0 for success, non zero for failure
8763
8764 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07008765static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07008766{
8767 VOS_STATUS status;
8768 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008769 struct device *dev = NULL;
8770 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07008771#ifdef HAVE_WCNSS_CAL_DOWNLOAD
8772 int max_retries = 0;
8773#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008774
Gopichand Nakkalad0774962013-05-24 11:32:21 +05308775#ifdef WCONN_TRACE_KMSG_LOG_BUFF
8776 vos_wconn_trace_init();
8777#endif
8778
Jeff Johnson295189b2012-06-20 16:38:30 -07008779 ENTER();
8780
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008781#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008782 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07008783#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008784
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308785 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07008786 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
8787 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
8788
8789 //Power Up Libra WLAN card first if not already powered up
8790 status = vos_chipPowerUp(NULL,NULL,NULL);
8791 if (!VOS_IS_STATUS_SUCCESS(status))
8792 {
8793 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
8794 "exiting", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05308795#ifdef WLAN_OPEN_SOURCE
8796 wake_lock_destroy(&wlan_wake_lock);
8797#endif
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008798 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008799 }
8800
Jeff Johnson295189b2012-06-20 16:38:30 -07008801#ifdef ANI_BUS_TYPE_PCI
8802
8803 dev = wcnss_wlan_get_device();
8804
8805#endif // ANI_BUS_TYPE_PCI
8806
8807#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07008808
8809#ifdef HAVE_WCNSS_CAL_DOWNLOAD
8810 /* wait until WCNSS driver downloads NV */
8811 while (!wcnss_device_ready() && 5 >= ++max_retries) {
8812 msleep(1000);
8813 }
8814 if (max_retries >= 5) {
8815 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05308816#ifdef WLAN_OPEN_SOURCE
8817 wake_lock_destroy(&wlan_wake_lock);
8818#endif
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07008819 return -ENODEV;
8820 }
8821#endif
8822
Jeff Johnson295189b2012-06-20 16:38:30 -07008823 dev = wcnss_wlan_get_device();
8824#endif // ANI_BUS_TYPE_PLATFORM
8825
8826
8827 do {
8828 if (NULL == dev) {
8829 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
8830 ret_status = -1;
8831 break;
8832 }
8833
Jeff Johnson295189b2012-06-20 16:38:30 -07008834#ifdef TIMER_MANAGER
8835 vos_timer_manager_init();
8836#endif
8837
8838 /* Preopen VOSS so that it is ready to start at least SAL */
8839 status = vos_preOpen(&pVosContext);
8840
8841 if (!VOS_IS_STATUS_SUCCESS(status))
8842 {
8843 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
8844 ret_status = -1;
8845 break;
8846 }
8847
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008848#ifndef MODULE
8849 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
8850 */
8851 hdd_set_conparam((v_UINT_t)con_mode);
8852#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008853
8854 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008855 if (hdd_wlan_startup(dev))
8856 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008857 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008858 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008859 vos_preClose( &pVosContext );
8860 ret_status = -1;
8861 break;
8862 }
8863
8864 /* Cancel the vote for XO Core ON
8865 * This is done here for safety purposes in case we re-initialize without turning
8866 * it OFF in any error scenario.
8867 */
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07008868 hddLog(VOS_TRACE_LEVEL_INFO, "In module init: Ensure Force XO Core is OFF"
Jeff Johnson295189b2012-06-20 16:38:30 -07008869 " when WLAN is turned ON so Core toggles"
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07008870 " unless we enter PSD");
Jeff Johnson295189b2012-06-20 16:38:30 -07008871 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
8872 {
8873 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel XO Core ON vote. Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08008874 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07008875 }
8876 } while (0);
8877
8878 if (0 != ret_status)
8879 {
8880 //Assert Deep sleep signal now to put Libra HW in lowest power state
8881 status = vos_chipAssertDeepSleep( NULL, NULL, NULL );
8882 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status) );
8883
8884 //Vote off any PMIC voltage supplies
8885 vos_chipPowerDown(NULL, NULL, NULL);
8886#ifdef TIMER_MANAGER
8887 vos_timer_exit();
8888#endif
8889#ifdef MEMORY_DEBUG
8890 vos_mem_exit();
8891#endif
8892
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008893#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008894 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008895#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008896 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
8897 }
8898 else
8899 {
8900 //Send WLAN UP indication to Nlink Service
8901 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
8902
8903 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07008904 }
8905
8906 EXIT();
8907
8908 return ret_status;
8909}
8910
Jeff Johnson32d95a32012-09-10 13:15:23 -07008911/**---------------------------------------------------------------------------
8912
8913 \brief hdd_module_init() - Init Function
8914
8915 This is the driver entry point (invoked when module is loaded using insmod)
8916
8917 \param - None
8918
8919 \return - 0 for success, non zero for failure
8920
8921 --------------------------------------------------------------------------*/
8922#ifdef MODULE
8923static int __init hdd_module_init ( void)
8924{
8925 return hdd_driver_init();
8926}
Jeff Johnson32d95a32012-09-10 13:15:23 -07008927#else /* #ifdef MODULE */
8928static int __init hdd_module_init ( void)
8929{
8930 /* Driver initialization is delayed to fwpath_changed_handler */
8931 return 0;
8932}
Jeff Johnson32d95a32012-09-10 13:15:23 -07008933#endif /* #ifdef MODULE */
8934
Jeff Johnson295189b2012-06-20 16:38:30 -07008935
8936/**---------------------------------------------------------------------------
8937
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008938 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07008939
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008940 This is the driver exit point (invoked when module is unloaded using rmmod
8941 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07008942
8943 \param - None
8944
8945 \return - None
8946
8947 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008948static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07008949{
8950 hdd_context_t *pHddCtx = NULL;
8951 v_CONTEXT_t pVosContext = NULL;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308952 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008953
8954 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
8955
8956 //Get the global vos context
8957 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8958
8959 if(!pVosContext)
8960 {
8961 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
8962 goto done;
8963 }
8964
8965 //Get the HDD context.
8966 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
8967
8968 if(!pHddCtx)
8969 {
8970 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
8971 }
8972 else
8973 {
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308974 INIT_COMPLETION(pHddCtx->ssr_comp_var);
8975
8976 if (pHddCtx->isLogpInProgress)
8977 {
Sameer Thalappil451ebb92013-06-28 15:49:58 -07008978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308979 "%s:SSR in Progress; block rmmod !!!", __func__);
8980 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
8981 msecs_to_jiffies(30000));
8982 if(!rc)
8983 {
8984 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8985 "%s:SSR timedout, fatal error", __func__);
8986 VOS_BUG(0);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07008987 }
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308988 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008989
8990 pHddCtx->isLoadUnloadInProgress = TRUE;
8991 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8992
8993 //Do all the cleanup before deregistering the driver
8994 hdd_wlan_exit(pHddCtx);
8995 }
8996
Jeff Johnson295189b2012-06-20 16:38:30 -07008997 vos_preClose( &pVosContext );
8998
8999#ifdef TIMER_MANAGER
9000 vos_timer_exit();
9001#endif
9002#ifdef MEMORY_DEBUG
9003 vos_mem_exit();
9004#endif
9005
Gopichand Nakkalad0774962013-05-24 11:32:21 +05309006#ifdef WCONN_TRACE_KMSG_LOG_BUFF
9007 vos_wconn_trace_exit();
9008#endif
9009
Jeff Johnson295189b2012-06-20 16:38:30 -07009010done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009011#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009012 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009013#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009014 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
9015}
9016
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009017/**---------------------------------------------------------------------------
9018
9019 \brief hdd_module_exit() - Exit function
9020
9021 This is the driver exit point (invoked when module is unloaded using rmmod)
9022
9023 \param - None
9024
9025 \return - None
9026
9027 --------------------------------------------------------------------------*/
9028static void __exit hdd_module_exit(void)
9029{
9030 hdd_driver_exit();
9031}
9032
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009033#ifdef MODULE
9034static int fwpath_changed_handler(const char *kmessage,
9035 struct kernel_param *kp)
9036{
Jeff Johnson76052702013-04-16 13:55:05 -07009037 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009038}
9039
9040static int con_mode_handler(const char *kmessage,
9041 struct kernel_param *kp)
9042{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07009043 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009044}
9045#else /* #ifdef MODULE */
9046/**---------------------------------------------------------------------------
9047
Jeff Johnson76052702013-04-16 13:55:05 -07009048 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009049
Jeff Johnson76052702013-04-16 13:55:05 -07009050 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009051 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07009052 - invoked when module parameter fwpath is modified from userspace to signal
9053 initializing the WLAN driver or when con_mode is modified from userspace
9054 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009055
9056 \return - 0 for success, non zero for failure
9057
9058 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009059static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009060{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009061 int ret_status;
9062
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009063 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009064 ret_status = hdd_driver_init();
9065 wlan_hdd_inited = ret_status ? 0 : 1;
9066 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009067 }
9068
9069 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07009070
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009071 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07009072
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009073 ret_status = hdd_driver_init();
9074 wlan_hdd_inited = ret_status ? 0 : 1;
9075 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009076}
9077
Jeff Johnson295189b2012-06-20 16:38:30 -07009078/**---------------------------------------------------------------------------
9079
Jeff Johnson76052702013-04-16 13:55:05 -07009080 \brief fwpath_changed_handler() - Handler Function
9081
9082 Handle changes to the fwpath parameter
9083
9084 \return - 0 for success, non zero for failure
9085
9086 --------------------------------------------------------------------------*/
9087static int fwpath_changed_handler(const char *kmessage,
9088 struct kernel_param *kp)
9089{
9090 int ret;
9091
9092 ret = param_set_copystring(kmessage, kp);
9093 if (0 == ret)
9094 ret = kickstart_driver();
9095 return ret;
9096}
9097
9098/**---------------------------------------------------------------------------
9099
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009100 \brief con_mode_handler() -
9101
9102 Handler function for module param con_mode when it is changed by userspace
9103 Dynamically linked - do nothing
9104 Statically linked - exit and init driver, as in rmmod and insmod
9105
Jeff Johnson76052702013-04-16 13:55:05 -07009106 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009107
Jeff Johnson76052702013-04-16 13:55:05 -07009108 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009109
9110 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009111static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009112{
Jeff Johnson76052702013-04-16 13:55:05 -07009113 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009114
Jeff Johnson76052702013-04-16 13:55:05 -07009115 ret = param_set_int(kmessage, kp);
9116 if (0 == ret)
9117 ret = kickstart_driver();
9118 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009119}
9120#endif /* #ifdef MODULE */
9121
9122/**---------------------------------------------------------------------------
9123
Jeff Johnson295189b2012-06-20 16:38:30 -07009124 \brief hdd_get_conparam() -
9125
9126 This is the driver exit point (invoked when module is unloaded using rmmod)
9127
9128 \param - None
9129
9130 \return - tVOS_CON_MODE
9131
9132 --------------------------------------------------------------------------*/
9133tVOS_CON_MODE hdd_get_conparam ( void )
9134{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009135#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -07009136 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009137#else
9138 return (tVOS_CON_MODE)curr_con_mode;
9139#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009140}
9141void hdd_set_conparam ( v_UINT_t newParam )
9142{
9143 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009144#ifndef MODULE
9145 curr_con_mode = con_mode;
9146#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009147}
9148/**---------------------------------------------------------------------------
9149
9150 \brief hdd_softap_sta_deauth() - function
9151
9152 This to take counter measure to handle deauth req from HDD
9153
9154 \param - pAdapter - Pointer to the HDD
9155
9156 \param - enable - boolean value
9157
9158 \return - None
9159
9160 --------------------------------------------------------------------------*/
9161
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009162VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009163{
Jeff Johnson295189b2012-06-20 16:38:30 -07009164 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009165 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07009166
9167 ENTER();
9168
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07009169 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
9170 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009171
9172 //Ignore request to deauth bcmc station
9173 if( pDestMacAddress[0] & 0x1 )
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009174 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009175
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009176 vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07009177
9178 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009179 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009180}
9181
9182/**---------------------------------------------------------------------------
9183
9184 \brief hdd_softap_sta_disassoc() - function
9185
9186 This to take counter measure to handle deauth req from HDD
9187
9188 \param - pAdapter - Pointer to the HDD
9189
9190 \param - enable - boolean value
9191
9192 \return - None
9193
9194 --------------------------------------------------------------------------*/
9195
9196void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
9197{
9198 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9199
9200 ENTER();
9201
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309202 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009203
9204 //Ignore request to disassoc bcmc station
9205 if( pDestMacAddress[0] & 0x1 )
9206 return;
9207
9208 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
9209}
9210
9211void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
9212{
9213 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9214
9215 ENTER();
9216
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309217 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009218
9219 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
9220}
9221
Jeff Johnson295189b2012-06-20 16:38:30 -07009222/**---------------------------------------------------------------------------
9223 *
9224 * \brief hdd_get__concurrency_mode() -
9225 *
9226 *
9227 * \param - None
9228 *
9229 * \return - CONCURRENCY MODE
9230 *
9231 * --------------------------------------------------------------------------*/
9232tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
9233{
9234 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
9235 hdd_context_t *pHddCtx;
9236
9237 if (NULL != pVosContext)
9238 {
9239 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
9240 if (NULL != pHddCtx)
9241 {
9242 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
9243 }
9244 }
9245
9246 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009247 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009248 return VOS_STA;
9249}
9250
9251/* Decide whether to allow/not the apps power collapse.
9252 * Allow apps power collapse if we are in connected state.
9253 * if not, allow only if we are in IMPS */
9254v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
9255{
9256 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -08009257 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009258 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009259 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9260 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9261 hdd_adapter_t *pAdapter = NULL;
9262 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -08009263 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009264
Jeff Johnson295189b2012-06-20 16:38:30 -07009265 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9266 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009267
Yathish9f22e662012-12-10 14:21:35 -08009268 concurrent_state = hdd_get_concurrency_mode();
9269
9270#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9271 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
9272 (concurrent_state == (VOS_STA | VOS_P2P_GO))) &&
9273 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
9274 return TRUE;
9275#endif
9276
Jeff Johnson295189b2012-06-20 16:38:30 -07009277 /*loop through all adapters. TBD fix for Concurrency */
9278 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9279 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9280 {
9281 pAdapter = pAdapterNode->pAdapter;
9282 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
9283 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9284 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009285 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
Jeff Johnson295189b2012-06-20 16:38:30 -07009286 && (pmcState != IMPS && pmcState != BMPS
Srikant Kuppafef66a72013-01-30 17:32:44 -08009287 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009288 (eANI_BOOLEAN_TRUE == scanRspPending) ||
9289 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -07009290 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009291 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009292 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
9293 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -07009294 return FALSE;
9295 }
9296 }
9297 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9298 pAdapterNode = pNext;
9299 }
9300 return TRUE;
9301}
9302
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -08009303/* Decides whether to send suspend notification to Riva
9304 * if any adapter is in BMPS; then it is required */
9305v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
9306{
9307 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
9308 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9309
9310 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
9311 {
9312 return TRUE;
9313 }
9314 return FALSE;
9315}
9316
Jeff Johnson295189b2012-06-20 16:38:30 -07009317void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9318{
9319 switch(mode)
9320 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009321 case VOS_STA_MODE:
9322 case VOS_P2P_CLIENT_MODE:
9323 case VOS_P2P_GO_MODE:
9324 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -07009325 pHddCtx->concurrency_mode |= (1 << mode);
9326 pHddCtx->no_of_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -07009327 break;
9328 default:
9329 break;
9330
9331 }
9332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9333 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9334}
9335
9336
9337void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9338{
9339 switch(mode)
9340 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009341 case VOS_STA_MODE:
9342 case VOS_P2P_CLIENT_MODE:
9343 case VOS_P2P_GO_MODE:
9344 case VOS_STA_SAP_MODE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009345 pHddCtx->no_of_sessions[mode]--;
9346 if (!(pHddCtx->no_of_sessions[mode]))
9347 pHddCtx->concurrency_mode &= (~(1 << mode));
9348 break;
9349 default:
9350 break;
9351 }
9352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9353 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9354}
9355
Jeff Johnsone7245742012-09-05 17:12:55 -07009356/**---------------------------------------------------------------------------
9357 *
9358 * \brief wlan_hdd_restart_init
9359 *
9360 * This function initalizes restart timer/flag. An internal function.
9361 *
9362 * \param - pHddCtx
9363 *
9364 * \return - None
9365 *
9366 * --------------------------------------------------------------------------*/
9367
9368static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
9369{
9370 /* Initialize */
9371 pHddCtx->hdd_restart_retries = 0;
9372 atomic_set(&pHddCtx->isRestartInProgress, 0);
9373 vos_timer_init(&pHddCtx->hdd_restart_timer,
9374 VOS_TIMER_TYPE_SW,
9375 wlan_hdd_restart_timer_cb,
9376 pHddCtx);
9377}
9378/**---------------------------------------------------------------------------
9379 *
9380 * \brief wlan_hdd_restart_deinit
9381 *
9382 * This function cleans up the resources used. An internal function.
9383 *
9384 * \param - pHddCtx
9385 *
9386 * \return - None
9387 *
9388 * --------------------------------------------------------------------------*/
9389
9390static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
9391{
9392
9393 VOS_STATUS vos_status;
9394 /* Block any further calls */
9395 atomic_set(&pHddCtx->isRestartInProgress, 1);
9396 /* Cleanup */
9397 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
9398 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309399 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009400 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
9401 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309402 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009403
9404}
9405
9406/**---------------------------------------------------------------------------
9407 *
9408 * \brief wlan_hdd_framework_restart
9409 *
9410 * This function uses a cfg80211 API to start a framework initiated WLAN
9411 * driver module unload/load.
9412 *
9413 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
9414 *
9415 *
9416 * \param - pHddCtx
9417 *
9418 * \return - VOS_STATUS_SUCCESS: Success
9419 * VOS_STATUS_E_EMPTY: Adapter is Empty
9420 * VOS_STATUS_E_NOMEM: No memory
9421
9422 * --------------------------------------------------------------------------*/
9423
9424static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
9425{
9426 VOS_STATUS status = VOS_STATUS_SUCCESS;
9427 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009428 int len = (sizeof (struct ieee80211_mgmt));
9429 struct ieee80211_mgmt *mgmt = NULL;
9430
9431 /* Prepare the DEAUTH managment frame with reason code */
9432 mgmt = kzalloc(len, GFP_KERNEL);
9433 if(mgmt == NULL)
9434 {
9435 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9436 "%s: memory allocation failed (%d bytes)", __func__, len);
9437 return VOS_STATUS_E_NOMEM;
9438 }
9439 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -07009440
9441 /* Iterate over all adapters/devices */
9442 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9443 do
9444 {
9445 if( (status == VOS_STATUS_SUCCESS) &&
9446 pAdapterNode &&
9447 pAdapterNode->pAdapter)
9448 {
9449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9450 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
9451 pAdapterNode->pAdapter->dev->name,
9452 pAdapterNode->pAdapter->device_mode,
9453 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009454 /*
9455 * CFG80211 event to restart the driver
9456 *
9457 * 'cfg80211_send_unprot_deauth' sends a
9458 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
9459 * of SME(Linux Kernel) state machine.
9460 *
9461 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
9462 * the driver.
9463 *
9464 */
9465
9466 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -07009467 }
9468 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9469 pAdapterNode = pNext;
9470 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
9471
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009472
9473 /* Free the allocated management frame */
9474 kfree(mgmt);
9475
Jeff Johnsone7245742012-09-05 17:12:55 -07009476 /* Retry until we unload or reach max count */
9477 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
9478 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
9479
9480 return status;
9481
9482}
9483/**---------------------------------------------------------------------------
9484 *
9485 * \brief wlan_hdd_restart_timer_cb
9486 *
9487 * Restart timer callback. An internal function.
9488 *
9489 * \param - User data:
9490 *
9491 * \return - None
9492 *
9493 * --------------------------------------------------------------------------*/
9494
9495void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
9496{
9497 hdd_context_t *pHddCtx = usrDataForCallback;
9498 wlan_hdd_framework_restart(pHddCtx);
9499 return;
9500
9501}
9502
9503
9504/**---------------------------------------------------------------------------
9505 *
9506 * \brief wlan_hdd_restart_driver
9507 *
9508 * This function sends an event to supplicant to restart the WLAN driver.
9509 *
9510 * This function is called from vos_wlanRestart.
9511 *
9512 * \param - pHddCtx
9513 *
9514 * \return - VOS_STATUS_SUCCESS: Success
9515 * VOS_STATUS_E_EMPTY: Adapter is Empty
9516 * VOS_STATUS_E_ALREADY: Request already in progress
9517
9518 * --------------------------------------------------------------------------*/
9519VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
9520{
9521 VOS_STATUS status = VOS_STATUS_SUCCESS;
9522
9523 /* A tight check to make sure reentrancy */
9524 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
9525 {
9526 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9527 "%s: WLAN restart is already in progress", __func__);
9528
9529 return VOS_STATUS_E_ALREADY;
9530 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -07009531 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -08009532#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -07009533 wcnss_reset_intr();
9534#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009535
Jeff Johnsone7245742012-09-05 17:12:55 -07009536 return status;
9537}
9538
Mihir Shetee1093ba2014-01-21 20:13:32 +05309539/**---------------------------------------------------------------------------
9540 *
9541 * \brief wlan_hdd_init_channels
9542 *
9543 * This function is used to initialize the channel list in CSR
9544 *
9545 * This function is called from hdd_wlan_startup
9546 *
9547 * \param - pHddCtx: HDD context
9548 *
9549 * \return - VOS_STATUS_SUCCESS: Success
9550 * VOS_STATUS_E_FAULT: Failure reported by SME
9551
9552 * --------------------------------------------------------------------------*/
9553static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
9554{
9555 eHalStatus status;
9556
9557 status = sme_InitChannels(pHddCtx->hHal);
9558 if (HAL_STATUS_SUCCESS(status))
9559 {
9560 return VOS_STATUS_SUCCESS;
9561 }
9562 else
9563 {
9564 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
9565 __func__, status);
9566 return VOS_STATUS_E_FAULT;
9567 }
9568}
9569
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -07009570/*
9571 * API to find if there is any STA or P2P-Client is connected
9572 */
9573VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
9574{
9575 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
9576}
Jeff Johnsone7245742012-09-05 17:12:55 -07009577
Jeff Johnson295189b2012-06-20 16:38:30 -07009578//Register the module init/exit functions
9579module_init(hdd_module_init);
9580module_exit(hdd_module_exit);
9581
9582MODULE_LICENSE("Dual BSD/GPL");
9583MODULE_AUTHOR("Qualcomm Atheros, Inc.");
9584MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
9585
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009586module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
9587 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009588
Jeff Johnson76052702013-04-16 13:55:05 -07009589module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009590 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -08009591
9592module_param(enable_dfs_chan_scan, int,
9593 S_IRUSR | S_IRGRP | S_IROTH);
9594
9595module_param(enable_11d, int,
9596 S_IRUSR | S_IRGRP | S_IROTH);
9597
9598module_param(country_code, charp,
9599 S_IRUSR | S_IRGRP | S_IROTH);