blob: 4b9f516bf51bc43243249ef4dca52911a9313fca [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080026 */
Kiet Lam842dad02014-02-18 18:44:02 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/*========================================================================
32
33 \file wlan_hdd_main.c
34
35 \brief WLAN Host Device Driver implementation
36
Jeff Johnson295189b2012-06-20 16:38:30 -070037
38 ========================================================================*/
39
40/**=========================================================================
41
42 EDIT HISTORY FOR FILE
43
44
45 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
47
48
49 $Header:$ $DateTime: $ $Author: $
50
51
52 when who what, where, why
53 -------- --- --------------------------------------------------------
54 04/5/09 Shailender Created module.
55 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
56 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
57 ==========================================================================*/
58
59/*--------------------------------------------------------------------------
60 Include Files
61 ------------------------------------------------------------------------*/
62//#include <wlan_qct_driver.h>
63#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070064#include <vos_api.h>
65#include <vos_sched.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <linux/etherdevice.h>
67#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070068#ifdef ANI_BUS_TYPE_PLATFORM
69#include <linux/wcnss_wlan.h>
70#endif //ANI_BUS_TYPE_PLATFORM
71#ifdef ANI_BUS_TYPE_PCI
72#include "wcnss_wlan.h"
73#endif /* ANI_BUS_TYPE_PCI */
74#include <wlan_hdd_tx_rx.h>
75#include <palTimer.h>
76#include <wniApi.h>
77#include <wlan_nlink_srv.h>
78#include <wlan_btc_svc.h>
79#include <wlan_hdd_cfg.h>
80#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053081#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070082#include <wlan_hdd_wowl.h>
83#include <wlan_hdd_misc.h>
84#include <wlan_hdd_wext.h>
85#ifdef WLAN_BTAMP_FEATURE
86#include <bap_hdd_main.h>
87#include <bapInternal.h>
88#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053089#include "wlan_hdd_trace.h"
90#include "vos_types.h"
91#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070092#include <linux/wireless.h>
93#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053094#include <linux/inetdevice.h>
95#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070096#include "wlan_hdd_cfg80211.h"
97#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070099int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700100#include "sapApi.h"
101#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700102#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530103#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
104#include <soc/qcom/subsystem_restart.h>
105#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700106#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530107#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#include <wlan_hdd_hostapd.h>
109#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700111#include "wlan_hdd_dev_pwr.h"
112#ifdef WLAN_BTAMP_FEATURE
113#include "bap_hdd_misc.h"
114#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700115#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700116#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800117#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530118#ifdef FEATURE_WLAN_TDLS
119#include "wlan_hdd_tdls.h"
120#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700121#include "wlan_hdd_debugfs.h"
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530122#include "sapInternal.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700123
124#ifdef MODULE
125#define WLAN_MODULE_NAME module_name(THIS_MODULE)
126#else
127#define WLAN_MODULE_NAME "wlan"
128#endif
129
130#ifdef TIMER_MANAGER
131#define TIMER_MANAGER_STR " +TIMER_MANAGER"
132#else
133#define TIMER_MANAGER_STR ""
134#endif
135
136#ifdef MEMORY_DEBUG
137#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
138#else
139#define MEMORY_DEBUG_STR ""
140#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530141#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700142/* the Android framework expects this param even though we don't use it */
143#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700144static char fwpath_buffer[BUF_LEN];
145static struct kparam_string fwpath = {
146 .string = fwpath_buffer,
147 .maxlen = BUF_LEN,
148};
Arif Hussain66559122013-11-21 10:11:40 -0800149
150static char *country_code;
151static int enable_11d = -1;
152static int enable_dfs_chan_scan = -1;
c_hpothu92367912014-05-01 15:18:17 +0530153static int gbcnMissRate = -1;
Arif Hussain66559122013-11-21 10:11:40 -0800154
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700155#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700156static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700157#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700158
Jeff Johnsone7245742012-09-05 17:12:55 -0700159/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800160 * spinlock for synchronizing asynchronous request/response
161 * (full description of use in wlan_hdd_main.h)
162 */
163DEFINE_SPINLOCK(hdd_context_lock);
164
165/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700166 * The rate at which the driver sends RESTART event to supplicant
167 * once the function 'vos_wlanRestart()' is called
168 *
169 */
170#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
171#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700172
173/*
174 * Size of Driver command strings from upper layer
175 */
176#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
177#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
178
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800179#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700180#define TID_MIN_VALUE 0
181#define TID_MAX_VALUE 15
182static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
183 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800184static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
185 tCsrEseBeaconReq *pEseBcnReq);
186#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700187
Atul Mittal1d722422014-03-19 11:15:07 +0530188/*
189 * Maximum buffer size used for returning the data back to user space
190 */
191#define WLAN_MAX_BUF_SIZE 1024
192#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700193
c_hpothu92367912014-05-01 15:18:17 +0530194//wait time for beacon miss rate.
195#define BCN_MISS_RATE_TIME 500
196
Sushant Kaushikd8a351d2015-05-05 17:44:40 +0530197static vos_wake_lock_t wlan_wake_lock;
198
Jeff Johnson295189b2012-06-20 16:38:30 -0700199/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700200static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700201
202//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700203static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
204static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
205static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
206void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800207void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700208
Jeff Johnson295189b2012-06-20 16:38:30 -0700209v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkad3e9fe782015-07-29 09:56:45 +0530210 struct sk_buff *skb
211#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
212 , void *accel_priv
213#endif
214#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
215 , select_queue_fallback_t fallback
216#endif
217);
Jeff Johnson295189b2012-06-20 16:38:30 -0700218
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
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800225#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800226void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
227static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700228static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
229 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
230 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700231static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
232 tANI_U8 *pTargetApBssid,
233 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800234#endif
Ratheesh S P21280412015-05-19 14:21:52 +0530235
236/* Store WLAN driver info in a global variable such that crash debugger
237 can extract it from driver debug symbol and crashdump for post processing */
238tANI_U8 g_wlan_driver[ ] = "pronto_driver";
239
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800240#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700241VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800242#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700243
Mihir Shetee1093ba2014-01-21 20:13:32 +0530244static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530245const char * hdd_device_modetoString(v_U8_t device_mode)
246{
247 switch(device_mode)
248 {
249 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
250 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
251 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
252 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
253 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
254 CASE_RETURN_STRING( WLAN_HDD_FTM );
255 CASE_RETURN_STRING( WLAN_HDD_IBSS );
256 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
257 default:
258 return "device_mode Unknown";
259 }
260}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530261
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530262static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700263 unsigned long state,
264 void *ndev)
265{
266 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700267 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700268 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700269#ifdef WLAN_BTAMP_FEATURE
270 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700271#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530272 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700273
274 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700275 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700276 (strncmp(dev->name, "p2p", 3)))
277 return NOTIFY_DONE;
278
Jeff Johnson295189b2012-06-20 16:38:30 -0700279 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700280 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700281
Jeff Johnson27cee452013-03-27 11:10:24 -0700282 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700283 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800284 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700285 VOS_ASSERT(0);
286 return NOTIFY_DONE;
287 }
288
Jeff Johnson27cee452013-03-27 11:10:24 -0700289 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
290 if (NULL == pHddCtx)
291 {
292 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
293 VOS_ASSERT(0);
294 return NOTIFY_DONE;
295 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800296 if (pHddCtx->isLogpInProgress)
297 return NOTIFY_DONE;
298
Jeff Johnson27cee452013-03-27 11:10:24 -0700299
300 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
301 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700302
303 switch (state) {
304 case NETDEV_REGISTER:
305 break;
306
307 case NETDEV_UNREGISTER:
308 break;
309
310 case NETDEV_UP:
311 break;
312
313 case NETDEV_DOWN:
314 break;
315
316 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700317 if(TRUE == pAdapter->isLinkUpSvcNeeded)
318 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700319 break;
320
321 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530322 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530323 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530324 {
325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
326 "%s: Timeout occurred while waiting for abortscan %ld",
327 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700328 }
329 else
330 {
331 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530332 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700333 }
334#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700336 status = WLANBAP_StopAmp();
337 if(VOS_STATUS_SUCCESS != status )
338 {
339 pHddCtx->isAmpAllowed = VOS_TRUE;
340 hddLog(VOS_TRACE_LEVEL_FATAL,
341 "%s: Failed to stop AMP", __func__);
342 }
343 else
344 {
345 //a state m/c implementation in PAL is TBD to avoid this delay
346 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700347 if ( pHddCtx->isAmpAllowed )
348 {
349 WLANBAP_DeregisterFromHCI();
350 pHddCtx->isAmpAllowed = VOS_FALSE;
351 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700352 }
353#endif //WLAN_BTAMP_FEATURE
354 break;
355
356 default:
357 break;
358 }
359
360 return NOTIFY_DONE;
361}
362
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530363static int hdd_netdev_notifier_call(struct notifier_block * nb,
364 unsigned long state,
365 void *ndev)
366{
367 int ret;
368 vos_ssr_protect(__func__);
369 ret = __hdd_netdev_notifier_call( nb, state, ndev);
370 vos_ssr_unprotect(__func__);
371 return ret;
372}
373
Jeff Johnson295189b2012-06-20 16:38:30 -0700374struct notifier_block hdd_netdev_notifier = {
375 .notifier_call = hdd_netdev_notifier_call,
376};
377
378/*---------------------------------------------------------------------------
379 * Function definitions
380 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700381void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
382void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700383//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700384static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700385#ifndef MODULE
386/* current con_mode - used only for statically linked driver
387 * con_mode is changed by userspace to indicate a mode change which will
388 * result in calling the module exit and init functions. The module
389 * exit function will clean up based on the value of con_mode prior to it
390 * being changed by userspace. So curr_con_mode records the current con_mode
391 * for exit when con_mode becomes the next mode for init
392 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700393static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700394#endif
395
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800396/**---------------------------------------------------------------------------
397
398 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
399
400 Called immediately after the cfg.ini is read in order to configure
401 the desired trace levels.
402
403 \param - moduleId - module whose trace level is being configured
404 \param - bitmask - bitmask of log levels to be enabled
405
406 \return - void
407
408 --------------------------------------------------------------------------*/
409static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
410{
411 wpt_tracelevel level;
412
413 /* if the bitmask is the default value, then a bitmask was not
414 specified in cfg.ini, so leave the logging level alone (it
415 will remain at the "compiled in" default value) */
416 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
417 {
418 return;
419 }
420
421 /* a mask was specified. start by disabling all logging */
422 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
423
424 /* now cycle through the bitmask until all "set" bits are serviced */
425 level = VOS_TRACE_LEVEL_FATAL;
426 while (0 != bitmask)
427 {
428 if (bitmask & 1)
429 {
430 vos_trace_setValue(moduleId, level, 1);
431 }
432 level++;
433 bitmask >>= 1;
434 }
435}
436
437
Jeff Johnson295189b2012-06-20 16:38:30 -0700438/**---------------------------------------------------------------------------
439
440 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
441
442 Called immediately after the cfg.ini is read in order to configure
443 the desired trace levels in the WDI.
444
445 \param - moduleId - module whose trace level is being configured
446 \param - bitmask - bitmask of log levels to be enabled
447
448 \return - void
449
450 --------------------------------------------------------------------------*/
451static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
452{
453 wpt_tracelevel level;
454
455 /* if the bitmask is the default value, then a bitmask was not
456 specified in cfg.ini, so leave the logging level alone (it
457 will remain at the "compiled in" default value) */
458 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
459 {
460 return;
461 }
462
463 /* a mask was specified. start by disabling all logging */
464 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
465
466 /* now cycle through the bitmask until all "set" bits are serviced */
467 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
468 while (0 != bitmask)
469 {
470 if (bitmask & 1)
471 {
472 wpalTraceSetLevel(moduleId, level, 1);
473 }
474 level++;
475 bitmask >>= 1;
476 }
477}
Jeff Johnson295189b2012-06-20 16:38:30 -0700478
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530479/*
480 * FUNCTION: wlan_hdd_validate_context
481 * This function is used to check the HDD context
482 */
483int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
484{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530485
486 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
487 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530488 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530489 "%s: HDD context is Null", __func__);
490 return -ENODEV;
491 }
492
493 if (pHddCtx->isLogpInProgress)
494 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530495 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530496 "%s: LOGP %s. Ignore!!", __func__,
497 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
498 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530499 return -EAGAIN;
500 }
501
Mihir Shete18156292014-03-11 15:38:30 +0530502 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530503 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530504 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530505 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
506 return -EAGAIN;
507 }
508 return 0;
509}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700510#ifdef CONFIG_ENABLE_LINUX_REG
511void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
512{
513 hdd_adapter_t *pAdapter = NULL;
514 hdd_station_ctx_t *pHddStaCtx = NULL;
515 eCsrPhyMode phyMode;
516 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530517
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700518 if (NULL == pHddCtx)
519 {
520 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
521 "HDD Context is null !!");
522 return ;
523 }
524
525 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
526 if (NULL == pAdapter)
527 {
528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
529 "pAdapter is null !!");
530 return ;
531 }
532
533 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
534 if (NULL == pHddStaCtx)
535 {
536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
537 "pHddStaCtx is null !!");
538 return ;
539 }
540
541 cfg_param = pHddCtx->cfg_ini;
542 if (NULL == cfg_param)
543 {
544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
545 "cfg_params not available !!");
546 return ;
547 }
548
549 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
550
551 if (!pHddCtx->isVHT80Allowed)
552 {
553 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
554 (eCSR_DOT11_MODE_11ac == phyMode) ||
555 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
556 {
557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
558 "Setting phymode to 11n!!");
559 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
560 }
561 }
562 else
563 {
564 /*New country Supports 11ac as well resetting value back from .ini*/
565 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
566 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
567 return ;
568 }
569
570 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
571 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
572 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
573 {
574 VOS_STATUS vosStatus;
575
576 // need to issue a disconnect to CSR.
577 INIT_COMPLETION(pAdapter->disconnect_comp_var);
578 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
579 pAdapter->sessionId,
580 eCSR_DISCONNECT_REASON_UNSPECIFIED );
581
582 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530583 {
584 long ret;
585
586 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700587 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530588 if (0 >= ret)
589 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
590 ret);
591 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700592
593 }
594}
595#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530596void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
597{
598 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
599 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
600 hdd_config_t *cfg_param;
601 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530602 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530603
604 if (NULL == pHddCtx)
605 {
606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
607 "HDD Context is null !!");
608 return ;
609 }
610
611 cfg_param = pHddCtx->cfg_ini;
612
613 if (NULL == cfg_param)
614 {
615 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
616 "cfg_params not available !!");
617 return ;
618 }
619
620 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
621
622 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
623 {
624 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
625 (eCSR_DOT11_MODE_11ac == phyMode) ||
626 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
627 {
628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
629 "Setting phymode to 11n!!");
630 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
631 }
632 }
633 else
634 {
635 /*New country Supports 11ac as well resetting value back from .ini*/
636 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
637 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
638 return ;
639 }
640
641 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
642 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
643 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
644 {
645 VOS_STATUS vosStatus;
646
647 // need to issue a disconnect to CSR.
648 INIT_COMPLETION(pAdapter->disconnect_comp_var);
649 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
650 pAdapter->sessionId,
651 eCSR_DISCONNECT_REASON_UNSPECIFIED );
652
653 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530654 {
655 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530656 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530657 if (ret <= 0)
658 {
659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
660 "wait on disconnect_comp_var is failed %ld", ret);
661 }
662 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530663
664 }
665}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700666#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530667
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700668void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
669{
670 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
671 hdd_config_t *cfg_param;
672
673 if (NULL == pHddCtx)
674 {
675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
676 "HDD Context is null !!");
677 return ;
678 }
679
680 cfg_param = pHddCtx->cfg_ini;
681
682 if (NULL == cfg_param)
683 {
684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
685 "cfg_params not available !!");
686 return ;
687 }
688
Agarwal Ashish738843c2014-09-25 12:27:56 +0530689 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
690 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700691 {
692 /*New country doesn't support DFS */
693 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
694 }
695 else
696 {
697 /*New country Supports DFS as well resetting value back from .ini*/
698 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
699 }
700
701}
702
Rajeev79dbe4c2013-10-05 11:03:42 +0530703#ifdef FEATURE_WLAN_BATCH_SCAN
704
705/**---------------------------------------------------------------------------
706
707 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
708 input string
709
710 This function extracts assigned integer from string in below format:
711 "STRING=10" : extracts integer 10 from this string
712
713 \param - pInPtr Pointer to input string
714 \param - base Base for string to int conversion(10 for decimal 16 for hex)
715 \param - pOutPtr Pointer to variable in which extracted integer needs to be
716 assigned
717 \param - pLastArg to tell whether it is last arguement in input string or
718 not
719
720 \return - NULL for failure cases
721 pointer to next arguement in input string for success cases
722 --------------------------------------------------------------------------*/
723static tANI_U8 *
724hdd_extract_assigned_int_from_str
725(
726 tANI_U8 *pInPtr,
727 tANI_U8 base,
728 tANI_U32 *pOutPtr,
729 tANI_U8 *pLastArg
730)
731{
732 int tempInt;
733 int v = 0;
734 char buf[32];
735 int val = 0;
736 *pLastArg = FALSE;
737
738 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
739 if (NULL == pInPtr)
740 {
741 return NULL;
742 }
743
744 pInPtr++;
745
746 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
747
748 val = sscanf(pInPtr, "%32s ", buf);
749 if (val < 0 && val > strlen(pInPtr))
750 {
751 return NULL;
752 }
753 pInPtr += val;
754 v = kstrtos32(buf, base, &tempInt);
755 if (v < 0)
756 {
757 return NULL;
758 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800759 if (tempInt < 0)
760 {
761 tempInt = 0;
762 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530763 *pOutPtr = tempInt;
764
765 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
766 if (NULL == pInPtr)
767 {
768 *pLastArg = TRUE;
769 return NULL;
770 }
771 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
772
773 return pInPtr;
774}
775
776/**---------------------------------------------------------------------------
777
778 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
779 input string
780
781 This function extracts assigned character from string in below format:
782 "STRING=A" : extracts char 'A' from this string
783
784 \param - pInPtr Pointer to input string
785 \param - pOutPtr Pointer to variable in which extracted char needs to be
786 assigned
787 \param - pLastArg to tell whether it is last arguement in input string or
788 not
789
790 \return - NULL for failure cases
791 pointer to next arguement in input string for success cases
792 --------------------------------------------------------------------------*/
793static tANI_U8 *
794hdd_extract_assigned_char_from_str
795(
796 tANI_U8 *pInPtr,
797 tANI_U8 *pOutPtr,
798 tANI_U8 *pLastArg
799)
800{
801 *pLastArg = FALSE;
802
803 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
804 if (NULL == pInPtr)
805 {
806 return NULL;
807 }
808
809 pInPtr++;
810
811 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
812
813 *pOutPtr = *pInPtr;
814
815 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
816 if (NULL == pInPtr)
817 {
818 *pLastArg = TRUE;
819 return NULL;
820 }
821 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
822
823 return pInPtr;
824}
825
826
827/**---------------------------------------------------------------------------
828
829 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
830
831 This function parses set batch scan command in below format:
832 WLS_BATCHING_SET <space> followed by below arguements
833 "SCANFREQ=XX" : Optional defaults to 30 sec
834 "MSCAN=XX" : Required number of scans to attempt to batch
835 "BESTN=XX" : Best Network (RSSI) defaults to 16
836 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
837 A. implies only 5 GHz , B. implies only 2.4GHz
838 "RTT=X" : optional defaults to 0
839 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
840 error
841
842 For example input commands:
843 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
844 translated into set batch scan with following parameters:
845 a) Frequence 60 seconds
846 b) Batch 10 scans together
847 c) Best RSSI to be 20
848 d) 5GHz band only
849 e) RTT is equal to 0
850
851 \param - pValue Pointer to input channel list
852 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
853
854 \return - 0 for success non-zero for failure
855
856 --------------------------------------------------------------------------*/
857static int
858hdd_parse_set_batchscan_command
859(
860 tANI_U8 *pValue,
861 tSirSetBatchScanReq *pHddSetBatchScanReq
862)
863{
864 tANI_U8 *inPtr = pValue;
865 tANI_U8 val = 0;
866 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800867 tANI_U32 nScanFreq;
868 tANI_U32 nMscan;
869 tANI_U32 nBestN;
870 tANI_U8 ucRfBand;
871 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800872 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530873
874 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800875 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
876 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
877 nRtt = 0;
878 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530879
880 /*go to space after WLS_BATCHING_SET command*/
881 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
882 /*no argument after the command*/
883 if (NULL == inPtr)
884 {
885 return -EINVAL;
886 }
887
888 /*no space after the command*/
889 else if (SPACE_ASCII_VALUE != *inPtr)
890 {
891 return -EINVAL;
892 }
893
894 /*removing empty spaces*/
895 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
896
897 /*no argument followed by spaces*/
898 if ('\0' == *inPtr)
899 {
900 return -EINVAL;
901 }
902
903 /*check and parse SCANFREQ*/
904 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
905 {
906 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800907 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800908
Rajeev Kumarc933d982013-11-18 20:04:20 -0800909 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800910 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800911 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800912 }
913
Rajeev79dbe4c2013-10-05 11:03:42 +0530914 if ( (NULL == inPtr) || (TRUE == lastArg))
915 {
916 return -EINVAL;
917 }
918 }
919
920 /*check and parse MSCAN*/
921 if ((strncmp(inPtr, "MSCAN", 5) == 0))
922 {
923 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800924 &nMscan, &lastArg);
925
926 if (0 == nMscan)
927 {
928 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
929 "invalid MSCAN=%d", nMscan);
930 return -EINVAL;
931 }
932
Rajeev79dbe4c2013-10-05 11:03:42 +0530933 if (TRUE == lastArg)
934 {
935 goto done;
936 }
937 else if (NULL == inPtr)
938 {
939 return -EINVAL;
940 }
941 }
942 else
943 {
944 return -EINVAL;
945 }
946
947 /*check and parse BESTN*/
948 if ((strncmp(inPtr, "BESTN", 5) == 0))
949 {
950 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800951 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800952
Rajeev Kumarc933d982013-11-18 20:04:20 -0800953 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800954 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800955 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800956 }
957
Rajeev79dbe4c2013-10-05 11:03:42 +0530958 if (TRUE == lastArg)
959 {
960 goto done;
961 }
962 else if (NULL == inPtr)
963 {
964 return -EINVAL;
965 }
966 }
967
968 /*check and parse CHANNEL*/
969 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
970 {
971 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800972
Rajeev79dbe4c2013-10-05 11:03:42 +0530973 if (('A' == val) || ('a' == val))
974 {
c_hpothuebf89732014-02-25 13:00:24 +0530975 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530976 }
977 else if (('B' == val) || ('b' == val))
978 {
c_hpothuebf89732014-02-25 13:00:24 +0530979 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530980 }
981 else
982 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800983 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
984 }
985
986 if (TRUE == lastArg)
987 {
988 goto done;
989 }
990 else if (NULL == inPtr)
991 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530992 return -EINVAL;
993 }
994 }
995
996 /*check and parse RTT*/
997 if ((strncmp(inPtr, "RTT", 3) == 0))
998 {
999 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001000 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +05301001 if (TRUE == lastArg)
1002 {
1003 goto done;
1004 }
1005 if (NULL == inPtr)
1006 {
1007 return -EINVAL;
1008 }
1009 }
1010
1011
1012done:
1013
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001014 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1015 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1016 pHddSetBatchScanReq->bestNetwork = nBestN;
1017 pHddSetBatchScanReq->rfBand = ucRfBand;
1018 pHddSetBatchScanReq->rtt = nRtt;
1019
Rajeev79dbe4c2013-10-05 11:03:42 +05301020 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1021 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1022 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1023 pHddSetBatchScanReq->scanFrequency,
1024 pHddSetBatchScanReq->numberOfScansToBatch,
1025 pHddSetBatchScanReq->bestNetwork,
1026 pHddSetBatchScanReq->rfBand,
1027 pHddSetBatchScanReq->rtt);
1028
1029 return 0;
1030}/*End of hdd_parse_set_batchscan_command*/
1031
1032/**---------------------------------------------------------------------------
1033
1034 \brief hdd_set_batch_scan_req_callback () - This function is called after
1035 receiving set batch scan response from FW and it saves set batch scan
1036 response data FW to HDD context and sets the completion event on
1037 which hdd_ioctl is waiting
1038
1039 \param - callbackContext Pointer to HDD adapter
1040 \param - pRsp Pointer to set batch scan response data received from FW
1041
1042 \return - nothing
1043
1044 --------------------------------------------------------------------------*/
1045static void hdd_set_batch_scan_req_callback
1046(
1047 void *callbackContext,
1048 tSirSetBatchScanRsp *pRsp
1049)
1050{
1051 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1052 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1053
1054 /*sanity check*/
1055 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1056 {
1057 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1058 "%s: Invalid pAdapter magic", __func__);
1059 VOS_ASSERT(0);
1060 return;
1061 }
1062 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1063
1064 /*save set batch scan response*/
1065 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1066
1067 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1068 "Received set batch scan rsp from FW with nScansToBatch=%d",
1069 pHddSetBatchScanRsp->nScansToBatch);
1070
1071 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1072 complete(&pAdapter->hdd_set_batch_scan_req_var);
1073
1074 return;
1075}/*End of hdd_set_batch_scan_req_callback*/
1076
1077
1078/**---------------------------------------------------------------------------
1079
1080 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1081 info in hdd batch scan response queue
1082
1083 \param - pAdapter Pointer to hdd adapter
1084 \param - pAPMetaInfo Pointer to access point meta info
1085 \param - scanId scan ID of batch scan response
1086 \param - isLastAp tells whether AP is last AP in batch scan response or not
1087
1088 \return - nothing
1089
1090 --------------------------------------------------------------------------*/
1091static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1092 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1093{
1094 tHddBatchScanRsp *pHead;
1095 tHddBatchScanRsp *pNode;
1096 tHddBatchScanRsp *pPrev;
1097 tHddBatchScanRsp *pTemp;
1098 tANI_U8 ssidLen;
1099
1100 /*head of hdd batch scan response queue*/
1101 pHead = pAdapter->pBatchScanRsp;
1102
1103 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1104 if (NULL == pNode)
1105 {
1106 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1107 "%s: Could not allocate memory", __func__);
1108 VOS_ASSERT(0);
1109 return;
1110 }
1111
1112 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1113 sizeof(pNode->ApInfo.bssid));
1114 ssidLen = strlen(pApMetaInfo->ssid);
1115 if (SIR_MAX_SSID_SIZE < ssidLen)
1116 {
1117 /*invalid scan result*/
1118 vos_mem_free(pNode);
1119 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1120 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1121 return;
1122 }
1123 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1124 /*null terminate ssid*/
1125 pNode->ApInfo.ssid[ssidLen] = '\0';
1126 pNode->ApInfo.ch = pApMetaInfo->ch;
1127 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1128 pNode->ApInfo.age = pApMetaInfo->timestamp;
1129 pNode->ApInfo.batchId = scanId;
1130 pNode->ApInfo.isLastAp = isLastAp;
1131
1132 pNode->pNext = NULL;
1133 if (NULL == pHead)
1134 {
1135 pAdapter->pBatchScanRsp = pNode;
1136 }
1137 else
1138 {
1139 pTemp = pHead;
1140 while (NULL != pTemp)
1141 {
1142 pPrev = pTemp;
1143 pTemp = pTemp->pNext;
1144 }
1145 pPrev->pNext = pNode;
1146 }
1147
1148 return;
1149}/*End of hdd_populate_batch_scan_rsp_queue*/
1150
1151/**---------------------------------------------------------------------------
1152
1153 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1154 receiving batch scan response indication from FW. It saves get batch scan
1155 response data in HDD batch scan response queue. This callback sets the
1156 completion event on which hdd_ioctl is waiting only after getting complete
1157 batch scan response data from FW
1158
1159 \param - callbackContext Pointer to HDD adapter
1160 \param - pRsp Pointer to get batch scan response data received from FW
1161
1162 \return - nothing
1163
1164 --------------------------------------------------------------------------*/
1165static void hdd_batch_scan_result_ind_callback
1166(
1167 void *callbackContext,
1168 void *pRsp
1169)
1170{
1171 v_BOOL_t isLastAp;
1172 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001173 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301174 tANI_U32 numberScanList;
1175 tANI_U32 nextScanListOffset;
1176 tANI_U32 nextApMetaInfoOffset;
1177 hdd_adapter_t* pAdapter;
1178 tpSirBatchScanList pScanList;
1179 tpSirBatchScanNetworkInfo pApMetaInfo;
1180 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1181 tSirSetBatchScanReq *pReq;
1182
1183 pAdapter = (hdd_adapter_t *)callbackContext;
1184 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001185 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301186 {
1187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1188 "%s: Invalid pAdapter magic", __func__);
1189 VOS_ASSERT(0);
1190 return;
1191 }
1192
1193 /*initialize locals*/
1194 pReq = &pAdapter->hddSetBatchScanReq;
1195 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1196 isLastAp = FALSE;
1197 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001198 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301199 numberScanList = 0;
1200 nextScanListOffset = 0;
1201 nextApMetaInfoOffset = 0;
1202 pScanList = NULL;
1203 pApMetaInfo = NULL;
1204
1205 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1206 {
1207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1208 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1209 isLastAp = TRUE;
1210 goto done;
1211 }
1212
1213 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1215 "Batch scan rsp: numberScalList %d", numberScanList);
1216
1217 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1218 {
1219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1220 "%s: numberScanList %d", __func__, numberScanList);
1221 isLastAp = TRUE;
1222 goto done;
1223 }
1224
1225 while (numberScanList)
1226 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001227 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301228 nextScanListOffset);
1229 if (NULL == pScanList)
1230 {
1231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1232 "%s: pScanList is %p", __func__, pScanList);
1233 isLastAp = TRUE;
1234 goto done;
1235 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001236 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001238 "Batch scan rsp: numApMetaInfo %d scanId %d",
1239 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301240
1241 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1242 {
1243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1244 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1245 isLastAp = TRUE;
1246 goto done;
1247 }
1248
Rajeev Kumarce651e42013-10-21 18:57:15 -07001249 /*Initialize next AP meta info offset for next scan list*/
1250 nextApMetaInfoOffset = 0;
1251
Rajeev79dbe4c2013-10-05 11:03:42 +05301252 while (numApMetaInfo)
1253 {
1254 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1255 nextApMetaInfoOffset);
1256 if (NULL == pApMetaInfo)
1257 {
1258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1259 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1260 isLastAp = TRUE;
1261 goto done;
1262 }
1263 /*calculate AP age*/
1264 pApMetaInfo->timestamp =
1265 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1266
1267 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001268 "%s: bssId "MAC_ADDRESS_STR
1269 " ch %d rssi %d timestamp %d", __func__,
1270 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1271 pApMetaInfo->ch, pApMetaInfo->rssi,
1272 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301273
1274 /*mark last AP in batch scan response*/
1275 if ((TRUE == pBatchScanRsp->isLastResult) &&
1276 (1 == numberScanList) && (1 == numApMetaInfo))
1277 {
1278 isLastAp = TRUE;
1279 }
1280
1281 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1282 /*store batch scan repsonse in hdd queue*/
1283 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1284 pScanList->scanId, isLastAp);
1285 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1286
1287 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1288 numApMetaInfo--;
1289 }
1290
Rajeev Kumarce651e42013-10-21 18:57:15 -07001291 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1292 + (sizeof(tSirBatchScanNetworkInfo)
1293 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301294 numberScanList--;
1295 }
1296
1297done:
1298
1299 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1300 requested from hdd_ioctl*/
1301 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1302 (TRUE == isLastAp))
1303 {
1304 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1305 complete(&pAdapter->hdd_get_batch_scan_req_var);
1306 }
1307
1308 return;
1309}/*End of hdd_batch_scan_result_ind_callback*/
1310
1311/**---------------------------------------------------------------------------
1312
1313 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1314 response as per batch scan FR request format by putting proper markers
1315
1316 \param - pDest pointer to destination buffer
1317 \param - cur_len current length
1318 \param - tot_len total remaining size which can be written to user space
1319 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1320 \param - pAdapter Pointer to HDD adapter
1321
1322 \return - ret no of characters written
1323
1324 --------------------------------------------------------------------------*/
1325static tANI_U32
1326hdd_format_batch_scan_rsp
1327(
1328 tANI_U8 *pDest,
1329 tANI_U32 cur_len,
1330 tANI_U32 tot_len,
1331 tHddBatchScanRsp *pApMetaInfo,
1332 hdd_adapter_t* pAdapter
1333)
1334{
1335 tANI_U32 ret = 0;
1336 tANI_U32 rem_len = 0;
1337 tANI_U8 temp_len = 0;
1338 tANI_U8 temp_total_len = 0;
1339 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1340 tANI_U8 *pTemp = temp;
1341
1342 /*Batch scan reponse needs to be returned to user space in
1343 following format:
1344 "scancount=X\n" where X is the number of scans in current batch
1345 batch
1346 "trunc\n" optional present if current scan truncated
1347 "bssid=XX:XX:XX:XX:XX:XX\n"
1348 "ssid=XXXX\n"
1349 "freq=X\n" frequency in Mhz
1350 "level=XX\n"
1351 "age=X\n" ms
1352 "dist=X\n" cm (-1 if not available)
1353 "errror=X\n" (-1if not available)
1354 "====\n" (end of ap marker)
1355 "####\n" (end of scan marker)
1356 "----\n" (end of results)*/
1357 /*send scan result in above format to user space based on
1358 available length*/
1359 /*The GET response may have more data than the driver can return in its
1360 buffer. In that case the buffer should be filled to the nearest complete
1361 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1362 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1363 The final buffer should end with "----\n"*/
1364
1365 /*sanity*/
1366 if (cur_len > tot_len)
1367 {
1368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1369 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1370 return 0;
1371 }
1372 else
1373 {
1374 rem_len = (tot_len - cur_len);
1375 }
1376
1377 /*end scan marker*/
1378 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1379 {
1380 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1381 pTemp += temp_len;
1382 temp_total_len += temp_len;
1383 }
1384
1385 /*bssid*/
1386 temp_len = snprintf(pTemp, sizeof(temp),
1387 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1388 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1389 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1390 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1391 pTemp += temp_len;
1392 temp_total_len += temp_len;
1393
1394 /*ssid*/
1395 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1396 pApMetaInfo->ApInfo.ssid);
1397 pTemp += temp_len;
1398 temp_total_len += temp_len;
1399
1400 /*freq*/
1401 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001402 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301403 pTemp += temp_len;
1404 temp_total_len += temp_len;
1405
1406 /*level*/
1407 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1408 pApMetaInfo->ApInfo.rssi);
1409 pTemp += temp_len;
1410 temp_total_len += temp_len;
1411
1412 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001413 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301414 pApMetaInfo->ApInfo.age);
1415 pTemp += temp_len;
1416 temp_total_len += temp_len;
1417
1418 /*dist*/
1419 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1420 pTemp += temp_len;
1421 temp_total_len += temp_len;
1422
1423 /*error*/
1424 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1425 pTemp += temp_len;
1426 temp_total_len += temp_len;
1427
1428 /*end AP marker*/
1429 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1430 pTemp += temp_len;
1431 temp_total_len += temp_len;
1432
1433 /*last AP in batch scan response*/
1434 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1435 {
1436 /*end scan marker*/
1437 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1438 pTemp += temp_len;
1439 temp_total_len += temp_len;
1440
1441 /*end batch scan result marker*/
1442 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1443 pTemp += temp_len;
1444 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001445
Rajeev79dbe4c2013-10-05 11:03:42 +05301446 }
1447
1448 if (temp_total_len < rem_len)
1449 {
1450 ret = temp_total_len + 1;
1451 strlcpy(pDest, temp, ret);
1452 pAdapter->isTruncated = FALSE;
1453 }
1454 else
1455 {
1456 pAdapter->isTruncated = TRUE;
1457 if (rem_len >= strlen("%%%%"))
1458 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001459 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301460 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001461 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301462 {
1463 ret = 0;
1464 }
1465 }
1466
1467 return ret;
1468
1469}/*End of hdd_format_batch_scan_rsp*/
1470
1471/**---------------------------------------------------------------------------
1472
1473 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1474 buffer starting with head of hdd batch scan response queue
1475
1476 \param - pAdapter Pointer to HDD adapter
1477 \param - pDest Pointer to user data buffer
1478 \param - cur_len current offset in user buffer
1479 \param - rem_len remaining no of bytes in user buffer
1480
1481 \return - number of bytes written in user buffer
1482
1483 --------------------------------------------------------------------------*/
1484
1485tANI_U32 hdd_populate_user_batch_scan_rsp
1486(
1487 hdd_adapter_t* pAdapter,
1488 tANI_U8 *pDest,
1489 tANI_U32 cur_len,
1490 tANI_U32 rem_len
1491)
1492{
1493 tHddBatchScanRsp *pHead;
1494 tHddBatchScanRsp *pPrev;
1495 tANI_U32 len;
1496
Rajeev79dbe4c2013-10-05 11:03:42 +05301497 pAdapter->isTruncated = FALSE;
1498
1499 /*head of hdd batch scan response queue*/
1500 pHead = pAdapter->pBatchScanRsp;
1501 while (pHead)
1502 {
1503 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1504 pAdapter);
1505 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001506 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301507 cur_len += len;
1508 if(TRUE == pAdapter->isTruncated)
1509 {
1510 /*result is truncated return rest of scan rsp in next req*/
1511 cur_len = rem_len;
1512 break;
1513 }
1514 pPrev = pHead;
1515 pHead = pHead->pNext;
1516 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001517 if (TRUE == pPrev->ApInfo.isLastAp)
1518 {
1519 pAdapter->prev_batch_id = 0;
1520 }
1521 else
1522 {
1523 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1524 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301525 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001526 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301527 }
1528
1529 return cur_len;
1530}/*End of hdd_populate_user_batch_scan_rsp*/
1531
1532/**---------------------------------------------------------------------------
1533
1534 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1535 scan response data from HDD queue to user space
1536 It does following in detail:
1537 a) if HDD has enough data in its queue then it 1st copies data to user
1538 space and then send get batch scan indication message to FW. In this
1539 case it does not wait on any event and batch scan response data will
1540 be populated in HDD response queue in MC thread context after receiving
1541 indication from FW
1542 b) else send get batch scan indication message to FW and wait on an event
1543 which will be set once HDD receives complete batch scan response from
1544 FW and then this function returns batch scan response to user space
1545
1546 \param - pAdapter Pointer to HDD adapter
1547 \param - pPrivData Pointer to priv_data
1548
1549 \return - 0 for success -EFAULT for failure
1550
1551 --------------------------------------------------------------------------*/
1552
1553int hdd_return_batch_scan_rsp_to_user
1554(
1555 hdd_adapter_t* pAdapter,
1556 hdd_priv_data_t *pPrivData,
1557 tANI_U8 *command
1558)
1559{
1560 tANI_U8 *pDest;
1561 tANI_U32 count = 0;
1562 tANI_U32 len = 0;
1563 tANI_U32 cur_len = 0;
1564 tANI_U32 rem_len = 0;
1565 eHalStatus halStatus;
1566 unsigned long rc;
1567 tSirTriggerBatchScanResultInd *pReq;
1568
1569 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1570 pReq->param = 0;/*batch scan client*/
1571 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1572 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1573
1574 cur_len = pPrivData->used_len;
1575 if (pPrivData->total_len > pPrivData->used_len)
1576 {
1577 rem_len = pPrivData->total_len - pPrivData->used_len;
1578 }
1579 else
1580 {
1581 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1582 "%s: Invalid user data buffer total_len %d used_len %d",
1583 __func__, pPrivData->total_len, pPrivData->used_len);
1584 return -EFAULT;
1585 }
1586
1587 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1588 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1589 cur_len, rem_len);
1590 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1591
1592 /*enough scan result available in cache to return to user space or
1593 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001594 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301595 {
1596 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1597 halStatus = sme_TriggerBatchScanResultInd(
1598 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1599 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1600 pAdapter);
1601 if ( eHAL_STATUS_SUCCESS == halStatus )
1602 {
1603 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1604 {
1605 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1606 rc = wait_for_completion_timeout(
1607 &pAdapter->hdd_get_batch_scan_req_var,
1608 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1609 if (0 == rc)
1610 {
1611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1612 "%s: Timeout waiting to fetch batch scan rsp from fw",
1613 __func__);
1614 return -EFAULT;
1615 }
1616 }
1617
1618 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001619 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301620 pDest += len;
1621 cur_len += len;
1622
1623 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1624 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1625 cur_len, rem_len);
1626 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1627
1628 count = 0;
1629 len = (len - pPrivData->used_len);
1630 pDest = (command + pPrivData->used_len);
1631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001632 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301633 while(count < len)
1634 {
1635 printk("%c", *(pDest + count));
1636 count++;
1637 }
1638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1639 "%s: copy %d data to user buffer", __func__, len);
1640 if (copy_to_user(pPrivData->buf, pDest, len))
1641 {
1642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1643 "%s: failed to copy data to user buffer", __func__);
1644 return -EFAULT;
1645 }
1646 }
1647 else
1648 {
1649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1650 "sme_GetBatchScanScan returned failure halStatus %d",
1651 halStatus);
1652 return -EINVAL;
1653 }
1654 }
1655 else
1656 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301657 count = 0;
1658 len = (len - pPrivData->used_len);
1659 pDest = (command + pPrivData->used_len);
1660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001661 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301662 while(count < len)
1663 {
1664 printk("%c", *(pDest + count));
1665 count++;
1666 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001667 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1668 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301669 if (copy_to_user(pPrivData->buf, pDest, len))
1670 {
1671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1672 "%s: failed to copy data to user buffer", __func__);
1673 return -EFAULT;
1674 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301675 }
1676
1677 return 0;
1678} /*End of hdd_return_batch_scan_rsp_to_user*/
1679
Rajeev Kumar8b373292014-01-08 20:36:55 -08001680
1681/**---------------------------------------------------------------------------
1682
1683 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1684 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1685 WLS_BATCHING VERSION
1686 WLS_BATCHING SET
1687 WLS_BATCHING GET
1688 WLS_BATCHING STOP
1689
1690 \param - pAdapter Pointer to HDD adapter
1691 \param - pPrivdata Pointer to priv_data
1692 \param - command Pointer to command
1693
1694 \return - 0 for success -EFAULT for failure
1695
1696 --------------------------------------------------------------------------*/
1697
1698int hdd_handle_batch_scan_ioctl
1699(
1700 hdd_adapter_t *pAdapter,
1701 hdd_priv_data_t *pPrivdata,
1702 tANI_U8 *command
1703)
1704{
1705 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001706 hdd_context_t *pHddCtx;
1707
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301708 ENTER();
1709
Yue Mae36e3552014-03-05 17:06:20 -08001710 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1711 ret = wlan_hdd_validate_context(pHddCtx);
1712 if (ret)
1713 {
Yue Mae36e3552014-03-05 17:06:20 -08001714 goto exit;
1715 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001716
1717 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1718 {
1719 char extra[32];
1720 tANI_U8 len = 0;
1721 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1722
1723 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1724 {
1725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1726 "%s: Batch scan feature is not supported by FW", __func__);
1727 ret = -EINVAL;
1728 goto exit;
1729 }
1730
1731 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1732 version);
1733 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1734 {
1735 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1736 "%s: failed to copy data to user buffer", __func__);
1737 ret = -EFAULT;
1738 goto exit;
1739 }
1740 ret = HDD_BATCH_SCAN_VERSION;
1741 }
1742 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1743 {
1744 int status;
1745 tANI_U8 *value = (command + 16);
1746 eHalStatus halStatus;
1747 unsigned long rc;
1748 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1749 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1750
1751 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1752 {
1753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1754 "%s: Batch scan feature is not supported by FW", __func__);
1755 ret = -EINVAL;
1756 goto exit;
1757 }
1758
1759 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1760 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1761 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1762 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1763 {
1764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301765 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001766 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301767 hdd_device_modetoString(pAdapter->device_mode),
1768 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001769 ret = -EINVAL;
1770 goto exit;
1771 }
1772
1773 status = hdd_parse_set_batchscan_command(value, pReq);
1774 if (status)
1775 {
1776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1777 "Invalid WLS_BATCHING SET command");
1778 ret = -EINVAL;
1779 goto exit;
1780 }
1781
1782
1783 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1784 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1785 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1786 pAdapter);
1787
1788 if ( eHAL_STATUS_SUCCESS == halStatus )
1789 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301790 char extra[32];
1791 tANI_U8 len = 0;
1792 tANI_U8 mScan = 0;
1793
Rajeev Kumar8b373292014-01-08 20:36:55 -08001794 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1795 "sme_SetBatchScanReq returned success halStatus %d",
1796 halStatus);
1797 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1798 {
1799 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1800 rc = wait_for_completion_timeout(
1801 &pAdapter->hdd_set_batch_scan_req_var,
1802 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1803 if (0 == rc)
1804 {
1805 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1806 "%s: Timeout waiting for set batch scan to complete",
1807 __func__);
1808 ret = -EINVAL;
1809 goto exit;
1810 }
1811 }
1812 if ( !pRsp->nScansToBatch )
1813 {
1814 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1815 "%s: Received set batch scan failure response from FW",
1816 __func__);
1817 ret = -EINVAL;
1818 goto exit;
1819 }
1820 /*As per the Batch Scan Framework API we should return the MIN of
1821 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301822 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001823
1824 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1825
1826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1827 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301828 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1829 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1830 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1831 {
1832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1833 "%s: failed to copy MSCAN value to user buffer", __func__);
1834 ret = -EFAULT;
1835 goto exit;
1836 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001837 }
1838 else
1839 {
1840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1841 "sme_SetBatchScanReq returned failure halStatus %d",
1842 halStatus);
1843 ret = -EINVAL;
1844 goto exit;
1845 }
1846 }
1847 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1848 {
1849 eHalStatus halStatus;
1850 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1851 pInd->param = 0;
1852
1853 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1854 {
1855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1856 "%s: Batch scan feature is not supported by FW", __func__);
1857 ret = -EINVAL;
1858 goto exit;
1859 }
1860
1861 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1862 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001864 "Batch scan is not yet enabled batch scan state %d",
1865 pAdapter->batchScanState);
1866 ret = -EINVAL;
1867 goto exit;
1868 }
1869
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001870 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1871 hdd_deinit_batch_scan(pAdapter);
1872 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1873
Rajeev Kumar8b373292014-01-08 20:36:55 -08001874 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1875
1876 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1877 pAdapter->sessionId);
1878 if ( eHAL_STATUS_SUCCESS == halStatus )
1879 {
1880 ret = 0;
1881 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1882 "sme_StopBatchScanInd returned success halStatus %d",
1883 halStatus);
1884 }
1885 else
1886 {
1887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1888 "sme_StopBatchScanInd returned failure halStatus %d",
1889 halStatus);
1890 ret = -EINVAL;
1891 goto exit;
1892 }
1893 }
1894 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1895 {
1896 tANI_U32 remain_len;
1897
1898 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1899 {
1900 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1901 "%s: Batch scan feature is not supported by FW", __func__);
1902 ret = -EINVAL;
1903 goto exit;
1904 }
1905
1906 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1907 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301908 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001909 "Batch scan is not yet enabled could not return results"
1910 "Batch Scan state %d",
1911 pAdapter->batchScanState);
1912 ret = -EINVAL;
1913 goto exit;
1914 }
1915
1916 pPrivdata->used_len = 16;
1917 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1918 if (remain_len < pPrivdata->total_len)
1919 {
1920 /*Clear previous batch scan response data if any*/
1921 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1922 }
1923 else
1924 {
1925 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1926 "Invalid total length from user space can't fetch batch"
1927 " scan response total_len %d used_len %d remain len %d",
1928 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1929 ret = -EINVAL;
1930 goto exit;
1931 }
1932 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1933 }
1934
1935exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301936 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08001937 return ret;
1938}
1939
1940
Rajeev79dbe4c2013-10-05 11:03:42 +05301941#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1942
c_hpothu92367912014-05-01 15:18:17 +05301943static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1944{
c_hpothu39eb1e32014-06-26 16:31:50 +05301945 bcnMissRateContext_t *pCBCtx;
1946
1947 if (NULL == data)
1948 {
1949 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1950 return;
1951 }
c_hpothu92367912014-05-01 15:18:17 +05301952
1953 /* there is a race condition that exists between this callback
1954 function and the caller since the caller could time out either
1955 before or while this code is executing. we use a spinlock to
1956 serialize these actions */
1957 spin_lock(&hdd_context_lock);
1958
c_hpothu39eb1e32014-06-26 16:31:50 +05301959 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301960 gbcnMissRate = -1;
1961
c_hpothu39eb1e32014-06-26 16:31:50 +05301962 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301963 {
1964 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301965 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301966 spin_unlock(&hdd_context_lock);
1967 return ;
1968 }
1969
1970 if (VOS_STATUS_SUCCESS == status)
1971 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301972 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301973 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301974 else
1975 {
1976 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
1977 }
1978
c_hpothu92367912014-05-01 15:18:17 +05301979 complete(&(pCBCtx->completion));
1980 spin_unlock(&hdd_context_lock);
1981
1982 return;
1983}
1984
Abhishek Singh08aa7762014-12-16 13:59:03 +05301985void hdd_FWStatisCB( VOS_STATUS status,
1986 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05301987{
1988 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301989 hdd_adapter_t *pAdapter;
1990
1991 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
1992
Abhishek Singh08aa7762014-12-16 13:59:03 +05301993 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05301994 {
1995 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1996 return;
1997 }
1998 /* there is a race condition that exists between this callback
1999 function and the caller since the caller could time out either
2000 before or while this code is executing. we use a spinlock to
2001 serialize these actions */
2002 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05302003 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302004 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
2005 {
2006 hddLog(VOS_TRACE_LEVEL_ERROR,
2007 FL("invalid context magic: %08x"), fwStatsCtx->magic);
2008 spin_unlock(&hdd_context_lock);
2009 return;
2010 }
2011 pAdapter = fwStatsCtx->pAdapter;
2012 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
2013 {
2014 hddLog(VOS_TRACE_LEVEL_ERROR,
2015 FL("pAdapter returned is NULL or invalid"));
2016 spin_unlock(&hdd_context_lock);
2017 return;
2018 }
2019 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05302020 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05302021 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302022 switch( fwStatsResult->type )
2023 {
2024 case FW_UBSP_STATS:
2025 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302026 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302027 hddLog(VOS_TRACE_LEVEL_INFO,
2028 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302029 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2030 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302031 }
2032 break;
2033 default:
2034 {
2035 hddLog(VOS_TRACE_LEVEL_ERROR,
2036 FL(" No handling for stats type %d"),fwStatsResult->type);
2037 }
2038 }
2039 }
2040 complete(&(fwStatsCtx->completion));
2041 spin_unlock(&hdd_context_lock);
2042 return;
2043}
2044
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302045static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2046{
2047 int ret = 0;
2048
2049 if (!pCfg || !command || !extra || !len)
2050 {
2051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2052 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2053 ret = -EINVAL;
2054 return ret;
2055 }
2056
2057 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2058 {
2059 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2060 (int)pCfg->nActiveMaxChnTime);
2061 return ret;
2062 }
2063 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2064 {
2065 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2066 (int)pCfg->nActiveMinChnTime);
2067 return ret;
2068 }
2069 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2070 {
2071 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2072 (int)pCfg->nPassiveMaxChnTime);
2073 return ret;
2074 }
2075 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2076 {
2077 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2078 (int)pCfg->nPassiveMinChnTime);
2079 return ret;
2080 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302081 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2082 {
2083 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2084 (int)pCfg->nActiveMaxChnTime);
2085 return ret;
2086 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302087 else
2088 {
2089 ret = -EINVAL;
2090 }
2091
2092 return ret;
2093}
2094
2095static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2096{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302097 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302098 hdd_config_t *pCfg;
2099 tANI_U8 *value = command;
2100 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302101 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302102
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302103 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2104 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302105 {
2106 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2107 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2108 ret = -EINVAL;
2109 return ret;
2110 }
2111
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302112 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2113 sme_GetConfigParam(hHal, &smeConfig);
2114
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302115 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2116 {
2117 value = value + 24;
2118 temp = kstrtou32(value, 10, &val);
2119 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2120 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2121 {
2122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2123 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2124 ret = -EFAULT;
2125 return ret;
2126 }
2127 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302128 smeConfig.csrConfig.nActiveMaxChnTime = val;
2129 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302130 }
2131 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2132 {
2133 value = value + 24;
2134 temp = kstrtou32(value, 10, &val);
2135 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2136 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2137 {
2138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2139 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2140 ret = -EFAULT;
2141 return ret;
2142 }
2143 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302144 smeConfig.csrConfig.nActiveMinChnTime = val;
2145 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302146 }
2147 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2148 {
2149 value = value + 25;
2150 temp = kstrtou32(value, 10, &val);
2151 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2152 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2153 {
2154 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2155 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2156 ret = -EFAULT;
2157 return ret;
2158 }
2159 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302160 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2161 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302162 }
2163 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2164 {
2165 value = value + 25;
2166 temp = kstrtou32(value, 10, &val);
2167 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2168 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2169 {
2170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2171 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2172 ret = -EFAULT;
2173 return ret;
2174 }
2175 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302176 smeConfig.csrConfig.nPassiveMinChnTime = val;
2177 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302178 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302179 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2180 {
2181 value = value + 13;
2182 temp = kstrtou32(value, 10, &val);
2183 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2184 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2185 {
2186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2187 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2188 ret = -EFAULT;
2189 return ret;
2190 }
2191 pCfg->nActiveMaxChnTime = val;
2192 smeConfig.csrConfig.nActiveMaxChnTime = val;
2193 sme_UpdateConfig(hHal, &smeConfig);
2194 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302195 else
2196 {
2197 ret = -EINVAL;
2198 }
2199
2200 return ret;
2201}
Agarwal Ashishea0af292015-06-12 18:03:45 +05302202static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
2203 tANI_U8 cmd_len)
2204{
2205 tANI_U8 *value;
2206 tANI_U8 fcc_constraint;
2207
2208 eHalStatus status;
2209 int ret = 0;
2210 value = cmd + cmd_len + 1;
2211
2212 ret = kstrtou8(value, 10, &fcc_constraint);
2213 if ((ret < 0) || (fcc_constraint > 1)) {
2214 /*
2215 * If the input value is greater than max value of datatype,
2216 * then also it is a failure
2217 */
2218 hddLog(VOS_TRACE_LEVEL_ERROR,
2219 "%s: value out of range", __func__);
2220 return -EINVAL;
2221 }
2222
2223 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint);
2224 if (status != eHAL_STATUS_SUCCESS)
2225 ret = -EPERM;
2226
2227 return ret;
2228}
2229
Mahesh A Saptasagar19675b02015-09-07 16:21:06 +05302230/**---------------------------------------------------------------------------
Agarwal Ashishea0af292015-06-12 18:03:45 +05302231
Mahesh A Saptasagar19675b02015-09-07 16:21:06 +05302232 \brief hdd_enable_disable_ca_event() - When Host sends IOCTL (enabled),
2233 FW will send *ONE* CA ind to Host(even though it is duplicate).
2234 When Host send IOCTL (disable), FW doesn't perform any action.
2235 Whenever any change in CA *and* WLAN is in SAP/P2P-GO mode, FW
2236 sends CA ind to host. (regard less of IOCTL status)
2237 \param - pHddCtx - HDD context
2238 \param - command - command received from framework
2239 \param - cmd_len - len of the command
2240
2241 \return - 0 on success, appropriate error values on failure.
2242
2243 --------------------------------------------------------------------------*/
2244int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, tANI_U8* command, tANI_U8 cmd_len)
2245{
2246 tANI_U8 set_value;
2247 int ret = 0;
2248 eHalStatus status;
2249
2250 ret = wlan_hdd_validate_context(pHddCtx);
2251 if (0 != ret)
2252 {
2253 ret = -EINVAL;
2254 goto exit;
2255 }
2256
2257 if (pHddCtx->cfg_ini->gOptimizeCAevent == 0)
2258 {
2259 hddLog(VOS_TRACE_LEVEL_ERROR, "Enable gOptimizeCAevent"
2260 " ini param to control channel avooidance indication");
2261 ret = 0;
2262 goto exit;
2263 }
2264
2265 set_value = command[cmd_len + 1] - '0';
2266 status = sme_enableDisableChanAvoidIndEvent(pHddCtx->hHal, set_value);
2267 if (status != eHAL_STATUS_SUCCESS)
2268 {
2269 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to send"
2270 " enableDisableChanAoidance command to SME\n", __func__);
2271 ret = -EINVAL;
2272 }
2273
2274exit:
2275 return ret;
2276}
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302277
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002278static int hdd_driver_command(hdd_adapter_t *pAdapter,
2279 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002280{
Jeff Johnson295189b2012-06-20 16:38:30 -07002281 hdd_priv_data_t priv_data;
2282 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302283 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2284 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002285 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302286 int status;
Anand N Sunkad3e9fe782015-07-29 09:56:45 +05302287#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
2288 struct cfg80211_mgmt_tx_params params;
2289#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302290
2291 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002292 /*
2293 * Note that valid pointers are provided by caller
2294 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002295
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002296 /* copy to local struct to avoid numerous changes to legacy code */
2297 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002298
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002299 if (priv_data.total_len <= 0 ||
2300 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002301 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002302 hddLog(VOS_TRACE_LEVEL_WARN,
2303 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2304 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002305 ret = -EINVAL;
2306 goto exit;
2307 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302308 status = wlan_hdd_validate_context(pHddCtx);
2309 if (0 != status)
2310 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302311 ret = -EINVAL;
2312 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302313 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002314 /* Allocate +1 for '\0' */
2315 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002316 if (!command)
2317 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002318 hddLog(VOS_TRACE_LEVEL_ERROR,
2319 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002320 ret = -ENOMEM;
2321 goto exit;
2322 }
2323
2324 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2325 {
2326 ret = -EFAULT;
2327 goto exit;
2328 }
2329
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002330 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002331 command[priv_data.total_len] = '\0';
2332
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002333 /* at one time the following block of code was conditional. braces
2334 * have been retained to avoid re-indenting the legacy code
2335 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002336 {
2337 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2338
2339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002340 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002341
2342 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2343 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302344 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2345 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2346 pAdapter->sessionId, (unsigned)
2347 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2348 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2349 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2350 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002351 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2352 sizeof(tSirMacAddr)))
2353 {
2354 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002355 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002356 ret = -EFAULT;
2357 }
2358 }
Amar Singhal0974e402013-02-12 14:27:46 -08002359 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002360 {
Amar Singhal0974e402013-02-12 14:27:46 -08002361 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002362
Jeff Johnson295189b2012-06-20 16:38:30 -07002363 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002364
2365 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002366 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002368 "%s: SetBandCommand Info comm %s UL %d, TL %d", __func__, command, priv_data.used_len, priv_data.total_len);
Anand N Sunkadb77a18f2015-07-13 14:39:11 +05302369 if(VOS_FTM_MODE != hdd_get_conparam())
2370 {
2371 /* Change band request received */
2372 ret = hdd_setBand_helper(pAdapter->dev, ptr);
2373 if(ret < 0)
2374 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2375 "%s: failed to set band ret=%d", __func__, ret);
2376 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002377 }
Kiet Lamf040f472013-11-20 21:15:23 +05302378 else if(strncmp(command, "SETWMMPS", 8) == 0)
2379 {
2380 tANI_U8 *ptr = command;
2381 ret = hdd_wmmps_helper(pAdapter, ptr);
2382 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05302383
2384 else if(strncmp(command, "TDLSSCAN", 8) == 0)
2385 {
2386 tANI_U8 *ptr = command;
2387 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
2388 }
2389
Jeff Johnson32d95a32012-09-10 13:15:23 -07002390 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2391 {
2392 char *country_code;
2393
2394 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002395
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002396 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002397 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002398#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302399 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002400#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002401 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2402 (void *)(tSmeChangeCountryCallback)
2403 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302404 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002405 if (eHAL_STATUS_SUCCESS == ret)
2406 {
2407 ret = wait_for_completion_interruptible_timeout(
2408 &pAdapter->change_country_code,
2409 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2410 if (0 >= ret)
2411 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002412 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302413 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002414 }
2415 }
2416 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002417 {
2418 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002419 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002420 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002421 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002422
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002423 }
2424 /*
2425 command should be a string having format
2426 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2427 */
Amar Singhal0974e402013-02-12 14:27:46 -08002428 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002429 {
Amar Singhal0974e402013-02-12 14:27:46 -08002430 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002431
2432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002433 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002434
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002435 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002436 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002437 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2438 {
2439 int suspend = 0;
2440 tANI_U8 *ptr = (tANI_U8*)command + 15;
2441
2442 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302443 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2444 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2445 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002446 hdd_set_wlan_suspend_mode(suspend);
2447 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002448#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2449 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2450 {
2451 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002452 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002453 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2454 eHalStatus status = eHAL_STATUS_SUCCESS;
2455
2456 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2457 value = value + 15;
2458
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002459 /* Convert the value from ascii to integer */
2460 ret = kstrtos8(value, 10, &rssi);
2461 if (ret < 0)
2462 {
2463 /* If the input value is greater than max value of datatype, then also
2464 kstrtou8 fails */
2465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2466 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002467 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002468 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2469 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2470 ret = -EINVAL;
2471 goto exit;
2472 }
2473
Srinivas Girigowdade697412013-02-14 16:31:48 -08002474 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002475
Srinivas Girigowdade697412013-02-14 16:31:48 -08002476 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2477 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2478 {
2479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2480 "Neighbor lookup threshold value %d is out of range"
2481 " (Min: %d Max: %d)", lookUpThreshold,
2482 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2483 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2484 ret = -EINVAL;
2485 goto exit;
2486 }
2487
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302488 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2489 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2490 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002491 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2492 "%s: Received Command to Set Roam trigger"
2493 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2494
2495 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2496 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2497 if (eHAL_STATUS_SUCCESS != status)
2498 {
2499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2500 "%s: Failed to set roam trigger, try again", __func__);
2501 ret = -EPERM;
2502 goto exit;
2503 }
2504
2505 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302506 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002507 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2508 }
2509 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2510 {
2511 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2512 int rssi = (-1) * lookUpThreshold;
2513 char extra[32];
2514 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302515 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2516 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2517 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002518 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda95adaf42015-07-13 15:10:10 +05302519 len = VOS_MIN(priv_data.total_len, len + 1);
2520 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002521 {
2522 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2523 "%s: failed to copy data to user buffer", __func__);
2524 ret = -EFAULT;
2525 goto exit;
2526 }
2527 }
2528 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2529 {
2530 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002531 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002532 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002533
Srinivas Girigowdade697412013-02-14 16:31:48 -08002534 /* input refresh period is in terms of seconds */
2535 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2536 value = value + 18;
2537 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002538 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002539 if (ret < 0)
2540 {
2541 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002542 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002544 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002545 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002546 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2547 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002548 ret = -EINVAL;
2549 goto exit;
2550 }
2551
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002552 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2553 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002554 {
2555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002556 "Roam scan period value %d is out of range"
2557 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002558 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2559 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002560 ret = -EINVAL;
2561 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302562 }
2563 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2564 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2565 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002566 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002567
2568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2569 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002570 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002571
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002572 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2573 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002574 }
2575 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2576 {
2577 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2578 char extra[32];
2579 tANI_U8 len = 0;
2580
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302581 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2582 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2583 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002584 len = scnprintf(extra, sizeof(extra), "%s %d",
2585 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002586 /* Returned value is in units of seconds */
Ratnam Rachuri0d07d682015-07-17 13:27:03 +05302587 len = VOS_MIN(priv_data.total_len, len + 1);
2588 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08002589 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2590 "%s: failed to copy data to user buffer", __func__);
2591 ret = -EFAULT;
2592 goto exit;
2593 }
2594 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002595 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2596 {
2597 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002598 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002599 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002600
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002601 /* input refresh period is in terms of seconds */
2602 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2603 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002604
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002605 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002606 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002607 if (ret < 0)
2608 {
2609 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002610 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002612 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002613 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002614 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2615 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2616 ret = -EINVAL;
2617 goto exit;
2618 }
2619
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002620 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2621 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2622 {
2623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2624 "Neighbor scan results refresh period value %d is out of range"
2625 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2626 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2627 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2628 ret = -EINVAL;
2629 goto exit;
2630 }
2631 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2632
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002633 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2634 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002635 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002636
2637 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2638 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2639 }
2640 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2641 {
2642 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2643 char extra[32];
2644 tANI_U8 len = 0;
2645
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002646 len = scnprintf(extra, sizeof(extra), "%s %d",
2647 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002648 /* Returned value is in units of seconds */
Ratnam Rachuri2c4d6db2015-07-17 13:25:16 +05302649 len = VOS_MIN(priv_data.total_len, len + 1);
2650 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002651 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2652 "%s: failed to copy data to user buffer", __func__);
2653 ret = -EFAULT;
2654 goto exit;
2655 }
2656 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002657#ifdef FEATURE_WLAN_LFR
2658 /* SETROAMMODE */
2659 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2660 {
2661 tANI_U8 *value = command;
2662 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2663
2664 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2665 value = value + SIZE_OF_SETROAMMODE + 1;
2666
2667 /* Convert the value from ascii to integer */
2668 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2669 if (ret < 0)
2670 {
2671 /* If the input value is greater than max value of datatype, then also
2672 kstrtou8 fails */
2673 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2674 "%s: kstrtou8 failed range [%d - %d]", __func__,
2675 CFG_LFR_FEATURE_ENABLED_MIN,
2676 CFG_LFR_FEATURE_ENABLED_MAX);
2677 ret = -EINVAL;
2678 goto exit;
2679 }
2680 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2681 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2682 {
2683 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2684 "Roam Mode value %d is out of range"
2685 " (Min: %d Max: %d)", roamMode,
2686 CFG_LFR_FEATURE_ENABLED_MIN,
2687 CFG_LFR_FEATURE_ENABLED_MAX);
2688 ret = -EINVAL;
2689 goto exit;
2690 }
2691
2692 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2693 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2694 /*
2695 * Note that
2696 * SETROAMMODE 0 is to enable LFR while
2697 * SETROAMMODE 1 is to disable LFR, but
2698 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2699 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2700 */
2701 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2702 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2703 else
2704 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2705
2706 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2707 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2708 }
2709 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302710 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002711 {
2712 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2713 char extra[32];
2714 tANI_U8 len = 0;
2715
2716 /*
2717 * roamMode value shall be inverted because the sementics is different.
2718 */
2719 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2720 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2721 else
2722 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2723
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002724 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Ratnam Rachuri627df442015-07-17 13:23:42 +05302725 len = VOS_MIN(priv_data.total_len, len + 1);
2726 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2728 "%s: failed to copy data to user buffer", __func__);
2729 ret = -EFAULT;
2730 goto exit;
2731 }
2732 }
2733#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002734#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002735#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002736 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2737 {
2738 tANI_U8 *value = command;
2739 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2740
2741 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2742 value = value + 13;
2743 /* Convert the value from ascii to integer */
2744 ret = kstrtou8(value, 10, &roamRssiDiff);
2745 if (ret < 0)
2746 {
2747 /* If the input value is greater than max value of datatype, then also
2748 kstrtou8 fails */
2749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2750 "%s: kstrtou8 failed range [%d - %d]", __func__,
2751 CFG_ROAM_RSSI_DIFF_MIN,
2752 CFG_ROAM_RSSI_DIFF_MAX);
2753 ret = -EINVAL;
2754 goto exit;
2755 }
2756
2757 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2758 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2759 {
2760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2761 "Roam rssi diff value %d is out of range"
2762 " (Min: %d Max: %d)", roamRssiDiff,
2763 CFG_ROAM_RSSI_DIFF_MIN,
2764 CFG_ROAM_RSSI_DIFF_MAX);
2765 ret = -EINVAL;
2766 goto exit;
2767 }
2768
2769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2770 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2771
2772 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2773 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2774 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302775 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002776 {
2777 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2778 char extra[32];
2779 tANI_U8 len = 0;
2780
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302781 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2782 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2783 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002784 len = scnprintf(extra, sizeof(extra), "%s %d",
2785 command, roamRssiDiff);
Ratnam Rachuri3c3d5622015-07-22 17:29:55 +05302786 len = VOS_MIN(priv_data.total_len, len + 1);
2787 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08002788 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2789 "%s: failed to copy data to user buffer", __func__);
2790 ret = -EFAULT;
2791 goto exit;
2792 }
2793 }
2794#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002795#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002796 else if (strncmp(command, "GETBAND", 7) == 0)
2797 {
2798 int band = -1;
2799 char extra[32];
2800 tANI_U8 len = 0;
2801 hdd_getBand_helper(pHddCtx, &band);
2802
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302803 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2804 TRACE_CODE_HDD_GETBAND_IOCTL,
2805 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002806 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Ratnam Rachuriedc4e852015-07-22 16:57:49 +05302807 len = VOS_MIN(priv_data.total_len, len + 1);
2808 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08002809 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2810 "%s: failed to copy data to user buffer", __func__);
2811 ret = -EFAULT;
2812 goto exit;
2813 }
2814 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002815 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2816 {
2817 tANI_U8 *value = command;
2818 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2819 tANI_U8 numChannels = 0;
2820 eHalStatus status = eHAL_STATUS_SUCCESS;
2821
2822 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2823 if (eHAL_STATUS_SUCCESS != status)
2824 {
2825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2826 "%s: Failed to parse channel list information", __func__);
2827 ret = -EINVAL;
2828 goto exit;
2829 }
2830
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302831 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2832 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2833 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002834 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2835 {
2836 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2837 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2838 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2839 ret = -EINVAL;
2840 goto exit;
2841 }
2842 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2843 numChannels);
2844 if (eHAL_STATUS_SUCCESS != status)
2845 {
2846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2847 "%s: Failed to update channel list information", __func__);
2848 ret = -EINVAL;
2849 goto exit;
2850 }
2851 }
2852 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2853 {
2854 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2855 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002856 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002857 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002858 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002859
2860 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2861 ChannelList, &numChannels ))
2862 {
2863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2864 "%s: failed to get roam scan channel list", __func__);
2865 ret = -EFAULT;
2866 goto exit;
2867 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302868 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2869 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2870 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002871 /* output channel list is of the format
2872 [Number of roam scan channels][Channel1][Channel2]... */
2873 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002874 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002875 for (j = 0; (j < numChannels); j++)
2876 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002877 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2878 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002879 }
2880
Sushant Kaushik842a9e52015-07-15 16:41:27 +05302881 len = VOS_MIN(priv_data.total_len, len + 1);
2882 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002883 {
2884 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2885 "%s: failed to copy data to user buffer", __func__);
2886 ret = -EFAULT;
2887 goto exit;
2888 }
2889 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002890 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2891 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002892 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002893 char extra[32];
2894 tANI_U8 len = 0;
2895
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002896 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002897 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002898 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002899 hdd_is_okc_mode_enabled(pHddCtx) &&
2900 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2901 {
2902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002903 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002904 " hence this operation is not permitted!", __func__);
2905 ret = -EPERM;
2906 goto exit;
2907 }
2908
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002909 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002910 "GETCCXMODE", eseMode);
Sushant Kaushik187a1952015-07-15 16:37:49 +05302911 len = VOS_MIN(priv_data.total_len, len + 1);
2912 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002913 {
2914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2915 "%s: failed to copy data to user buffer", __func__);
2916 ret = -EFAULT;
2917 goto exit;
2918 }
2919 }
2920 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2921 {
2922 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2923 char extra[32];
2924 tANI_U8 len = 0;
2925
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002926 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002927 then this operation is not permitted (return FAILURE) */
2928 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002929 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002930 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2931 {
2932 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002933 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002934 " hence this operation is not permitted!", __func__);
2935 ret = -EPERM;
2936 goto exit;
2937 }
2938
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002939 len = scnprintf(extra, sizeof(extra), "%s %d",
2940 "GETOKCMODE", okcMode);
Sushant Kaushik11be4582015-07-15 16:43:16 +05302941 len = VOS_MIN(priv_data.total_len, len + 1);
2942 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002943 {
2944 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2945 "%s: failed to copy data to user buffer", __func__);
2946 ret = -EFAULT;
2947 goto exit;
2948 }
2949 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002950 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002951 {
2952 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2953 char extra[32];
2954 tANI_U8 len = 0;
2955
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002956 len = scnprintf(extra, sizeof(extra), "%s %d",
2957 "GETFASTROAM", lfrMode);
Sushant Kaushik334e5172015-07-15 16:39:32 +05302958 len = VOS_MIN(priv_data.total_len, len + 1);
2959 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002960 {
2961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2962 "%s: failed to copy data to user buffer", __func__);
2963 ret = -EFAULT;
2964 goto exit;
2965 }
2966 }
2967 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2968 {
2969 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2970 char extra[32];
2971 tANI_U8 len = 0;
2972
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002973 len = scnprintf(extra, sizeof(extra), "%s %d",
2974 "GETFASTTRANSITION", ft);
Sushant Kaushikddbb3502015-07-15 16:23:56 +05302975 len = VOS_MIN(priv_data.total_len, len + 1);
2976 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002977 {
2978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2979 "%s: failed to copy data to user buffer", __func__);
2980 ret = -EFAULT;
2981 goto exit;
2982 }
2983 }
2984 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2985 {
2986 tANI_U8 *value = command;
2987 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2988
2989 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2990 value = value + 26;
2991 /* Convert the value from ascii to integer */
2992 ret = kstrtou8(value, 10, &minTime);
2993 if (ret < 0)
2994 {
2995 /* If the input value is greater than max value of datatype, then also
2996 kstrtou8 fails */
2997 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2998 "%s: kstrtou8 failed range [%d - %d]", __func__,
2999 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
3000 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
3001 ret = -EINVAL;
3002 goto exit;
3003 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003004 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
3005 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
3006 {
3007 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3008 "scan min channel time value %d is out of range"
3009 " (Min: %d Max: %d)", minTime,
3010 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
3011 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
3012 ret = -EINVAL;
3013 goto exit;
3014 }
3015
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303016 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3017 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
3018 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003019 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3020 "%s: Received Command to change channel min time = %d", __func__, minTime);
3021
3022 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
3023 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
3024 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003025 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
3026 {
3027 tANI_U8 *value = command;
3028 tANI_U8 channel = 0;
3029 tANI_U8 dwellTime = 0;
3030 tANI_U8 bufLen = 0;
3031 tANI_U8 *buf = NULL;
3032 tSirMacAddr targetApBssid;
3033 eHalStatus status = eHAL_STATUS_SUCCESS;
3034 struct ieee80211_channel chan;
3035 tANI_U8 finalLen = 0;
3036 tANI_U8 *finalBuf = NULL;
3037 tANI_U8 temp = 0;
3038 u64 cookie;
3039 hdd_station_ctx_t *pHddStaCtx = NULL;
3040 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3041
3042 /* if not associated, no need to send action frame */
3043 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3044 {
3045 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3046 ret = -EINVAL;
3047 goto exit;
3048 }
3049
3050 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
3051 &dwellTime, &buf, &bufLen);
3052 if (eHAL_STATUS_SUCCESS != status)
3053 {
3054 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3055 "%s: Failed to parse send action frame data", __func__);
3056 ret = -EINVAL;
3057 goto exit;
3058 }
3059
3060 /* if the target bssid is different from currently associated AP,
3061 then no need to send action frame */
3062 if (VOS_TRUE != vos_mem_compare(targetApBssid,
3063 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3064 {
3065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
3066 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003067 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003068 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003069 goto exit;
3070 }
3071
3072 /* if the channel number is different from operating channel then
3073 no need to send action frame */
3074 if (channel != pHddStaCtx->conn_info.operationChannel)
3075 {
3076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3077 "%s: channel(%d) is different from operating channel(%d)",
3078 __func__, channel, pHddStaCtx->conn_info.operationChannel);
3079 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003080 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003081 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003082 goto exit;
3083 }
3084 chan.center_freq = sme_ChnToFreq(channel);
3085
3086 finalLen = bufLen + 24;
3087 finalBuf = vos_mem_malloc(finalLen);
3088 if (NULL == finalBuf)
3089 {
3090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
3091 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07003092 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003093 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003094 goto exit;
3095 }
3096 vos_mem_zero(finalBuf, finalLen);
3097
3098 /* Fill subtype */
3099 temp = SIR_MAC_MGMT_ACTION << 4;
3100 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3101
3102 /* Fill type */
3103 temp = SIR_MAC_MGMT_FRAME;
3104 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3105
3106 /* Fill destination address (bssid of the AP) */
3107 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3108
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003109 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003110 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3111
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003112 /* Fill BSSID (AP mac address) */
3113 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003114
3115 /* Fill received buffer from 24th address */
3116 vos_mem_copy(finalBuf + 24, buf, bufLen);
3117
Jeff Johnson11c33152013-04-16 17:52:40 -07003118 /* done with the parsed buffer */
3119 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003120 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003121
Anand N Sunkad3e9fe782015-07-29 09:56:45 +05303122#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3123 params.chan = &chan;
3124 params.offchan = 0;
3125 params.wait = dwellTime;
3126 params.buf = finalBuf;
3127 params.len = finalLen;
3128 params.no_cck = 1;
3129 params.dont_wait_for_ack = 1;
3130 ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
3131#else
DARAM SUDHA39eede62014-02-12 11:16:40 +05303132 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003133#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3134 &(pAdapter->wdev),
3135#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003136 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003137#endif
3138 &chan, 0,
3139#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3140 NL80211_CHAN_HT20, 1,
3141#endif
3142 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003143 1, &cookie );
Anand N Sunkad3e9fe782015-07-29 09:56:45 +05303144#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003145 vos_mem_free(finalBuf);
3146 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003147 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3148 {
3149 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3150 char extra[32];
3151 tANI_U8 len = 0;
3152
3153 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003154 len = scnprintf(extra, sizeof(extra), "%s %d",
3155 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303156 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3157 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3158 pAdapter->sessionId, val));
Sushant Kaushik62a4e152015-07-15 16:36:23 +05303159 len = VOS_MIN(priv_data.total_len, len + 1);
3160 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003161 {
3162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3163 "%s: failed to copy data to user buffer", __func__);
3164 ret = -EFAULT;
3165 goto exit;
3166 }
3167 }
3168 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3169 {
3170 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003171 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003172
3173 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3174 value = value + 19;
3175 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003176 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003177 if (ret < 0)
3178 {
3179 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003180 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003181 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003182 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003183 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3184 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3185 ret = -EINVAL;
3186 goto exit;
3187 }
3188
3189 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3190 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3191 {
3192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3193 "lfr mode value %d is out of range"
3194 " (Min: %d Max: %d)", maxTime,
3195 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3196 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3197 ret = -EINVAL;
3198 goto exit;
3199 }
3200
3201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3202 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3203
3204 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3205 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3206 }
3207 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3208 {
3209 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3210 char extra[32];
3211 tANI_U8 len = 0;
3212
3213 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003214 len = scnprintf(extra, sizeof(extra), "%s %d",
3215 "GETSCANCHANNELTIME", val);
Ratheesh S Pceff0352015-07-16 15:27:18 +05303216 len = VOS_MIN(priv_data.total_len, len + 1);
3217 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003218 {
3219 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3220 "%s: failed to copy data to user buffer", __func__);
3221 ret = -EFAULT;
3222 goto exit;
3223 }
3224 }
3225 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3226 {
3227 tANI_U8 *value = command;
3228 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3229
3230 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3231 value = value + 16;
3232 /* Convert the value from ascii to integer */
3233 ret = kstrtou16(value, 10, &val);
3234 if (ret < 0)
3235 {
3236 /* If the input value is greater than max value of datatype, then also
3237 kstrtou16 fails */
3238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3239 "%s: kstrtou16 failed range [%d - %d]", __func__,
3240 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3241 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3242 ret = -EINVAL;
3243 goto exit;
3244 }
3245
3246 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3247 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3248 {
3249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3250 "scan home time value %d is out of range"
3251 " (Min: %d Max: %d)", val,
3252 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3253 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3254 ret = -EINVAL;
3255 goto exit;
3256 }
3257
3258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3259 "%s: Received Command to change scan home time = %d", __func__, val);
3260
3261 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3262 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3263 }
3264 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3265 {
3266 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3267 char extra[32];
3268 tANI_U8 len = 0;
3269
3270 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003271 len = scnprintf(extra, sizeof(extra), "%s %d",
3272 "GETSCANHOMETIME", val);
Ratheesh S P81f8e802015-07-16 15:38:58 +05303273 len = VOS_MIN(priv_data.total_len, len + 1);
3274 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003275 {
3276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3277 "%s: failed to copy data to user buffer", __func__);
3278 ret = -EFAULT;
3279 goto exit;
3280 }
3281 }
3282 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3283 {
3284 tANI_U8 *value = command;
3285 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3286
3287 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3288 value = value + 17;
3289 /* Convert the value from ascii to integer */
3290 ret = kstrtou8(value, 10, &val);
3291 if (ret < 0)
3292 {
3293 /* If the input value is greater than max value of datatype, then also
3294 kstrtou8 fails */
3295 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3296 "%s: kstrtou8 failed range [%d - %d]", __func__,
3297 CFG_ROAM_INTRA_BAND_MIN,
3298 CFG_ROAM_INTRA_BAND_MAX);
3299 ret = -EINVAL;
3300 goto exit;
3301 }
3302
3303 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3304 (val > CFG_ROAM_INTRA_BAND_MAX))
3305 {
3306 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3307 "intra band mode value %d is out of range"
3308 " (Min: %d Max: %d)", val,
3309 CFG_ROAM_INTRA_BAND_MIN,
3310 CFG_ROAM_INTRA_BAND_MAX);
3311 ret = -EINVAL;
3312 goto exit;
3313 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3315 "%s: Received Command to change intra band = %d", __func__, val);
3316
3317 pHddCtx->cfg_ini->nRoamIntraBand = val;
3318 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3319 }
3320 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3321 {
3322 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3323 char extra[32];
3324 tANI_U8 len = 0;
3325
3326 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003327 len = scnprintf(extra, sizeof(extra), "%s %d",
3328 "GETROAMINTRABAND", val);
Ratheesh S P351575b2015-07-16 15:34:23 +05303329 len = VOS_MIN(priv_data.total_len, len + 1);
3330 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003331 {
3332 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3333 "%s: failed to copy data to user buffer", __func__);
3334 ret = -EFAULT;
3335 goto exit;
3336 }
3337 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003338 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3339 {
3340 tANI_U8 *value = command;
3341 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3342
3343 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3344 value = value + 15;
3345 /* Convert the value from ascii to integer */
3346 ret = kstrtou8(value, 10, &nProbes);
3347 if (ret < 0)
3348 {
3349 /* If the input value is greater than max value of datatype, then also
3350 kstrtou8 fails */
3351 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3352 "%s: kstrtou8 failed range [%d - %d]", __func__,
3353 CFG_ROAM_SCAN_N_PROBES_MIN,
3354 CFG_ROAM_SCAN_N_PROBES_MAX);
3355 ret = -EINVAL;
3356 goto exit;
3357 }
3358
3359 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3360 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3361 {
3362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3363 "NProbes value %d is out of range"
3364 " (Min: %d Max: %d)", nProbes,
3365 CFG_ROAM_SCAN_N_PROBES_MIN,
3366 CFG_ROAM_SCAN_N_PROBES_MAX);
3367 ret = -EINVAL;
3368 goto exit;
3369 }
3370
3371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3372 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3373
3374 pHddCtx->cfg_ini->nProbes = nProbes;
3375 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3376 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303377 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003378 {
3379 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3380 char extra[32];
3381 tANI_U8 len = 0;
3382
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003383 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri46df3ed2015-08-07 13:55:54 +05303384 len = VOS_MIN(priv_data.total_len, len + 1);
3385 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003386 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3387 "%s: failed to copy data to user buffer", __func__);
3388 ret = -EFAULT;
3389 goto exit;
3390 }
3391 }
3392 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3393 {
3394 tANI_U8 *value = command;
3395 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3396
3397 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3398 /* input value is in units of msec */
3399 value = value + 20;
3400 /* Convert the value from ascii to integer */
3401 ret = kstrtou16(value, 10, &homeAwayTime);
3402 if (ret < 0)
3403 {
3404 /* If the input value is greater than max value of datatype, then also
3405 kstrtou8 fails */
3406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3407 "%s: kstrtou8 failed range [%d - %d]", __func__,
3408 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3409 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3410 ret = -EINVAL;
3411 goto exit;
3412 }
3413
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003414 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3415 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3416 {
3417 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3418 "homeAwayTime value %d is out of range"
3419 " (Min: %d Max: %d)", homeAwayTime,
3420 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3421 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3422 ret = -EINVAL;
3423 goto exit;
3424 }
3425
3426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3427 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003428 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3429 {
3430 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3431 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3432 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003433 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303434 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003435 {
3436 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3437 char extra[32];
3438 tANI_U8 len = 0;
3439
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003440 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri83c4c272015-08-07 14:06:37 +05303441 len = VOS_MIN(priv_data.total_len, len + 1);
3442 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3444 "%s: failed to copy data to user buffer", __func__);
3445 ret = -EFAULT;
3446 goto exit;
3447 }
3448 }
3449 else if (strncmp(command, "REASSOC", 7) == 0)
3450 {
3451 tANI_U8 *value = command;
3452 tANI_U8 channel = 0;
3453 tSirMacAddr targetApBssid;
3454 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003455#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3456 tCsrHandoffRequest handoffInfo;
3457#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003458 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003459 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3460
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003461 /* if not associated, no need to proceed with reassoc */
3462 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3463 {
3464 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3465 ret = -EINVAL;
3466 goto exit;
3467 }
3468
3469 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3470 if (eHAL_STATUS_SUCCESS != status)
3471 {
3472 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3473 "%s: Failed to parse reassoc command data", __func__);
3474 ret = -EINVAL;
3475 goto exit;
3476 }
3477
3478 /* if the target bssid is same as currently associated AP,
3479 then no need to proceed with reassoc */
3480 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3481 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3482 {
3483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3484 ret = -EINVAL;
3485 goto exit;
3486 }
3487
3488 /* Check channel number is a valid channel number */
3489 if(VOS_STATUS_SUCCESS !=
3490 wlan_hdd_validate_operation_channel(pAdapter, channel))
3491 {
3492 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003493 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003494 return -EINVAL;
3495 }
3496
3497 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003498#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3499 handoffInfo.channel = channel;
3500 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3501 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3502#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003503 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003504 else if (strncmp(command, "SETWESMODE", 10) == 0)
3505 {
3506 tANI_U8 *value = command;
3507 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3508
3509 /* Move pointer to ahead of SETWESMODE<delimiter> */
3510 value = value + 11;
3511 /* Convert the value from ascii to integer */
3512 ret = kstrtou8(value, 10, &wesMode);
3513 if (ret < 0)
3514 {
3515 /* If the input value is greater than max value of datatype, then also
3516 kstrtou8 fails */
3517 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3518 "%s: kstrtou8 failed range [%d - %d]", __func__,
3519 CFG_ENABLE_WES_MODE_NAME_MIN,
3520 CFG_ENABLE_WES_MODE_NAME_MAX);
3521 ret = -EINVAL;
3522 goto exit;
3523 }
3524
3525 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3526 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3527 {
3528 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3529 "WES Mode value %d is out of range"
3530 " (Min: %d Max: %d)", wesMode,
3531 CFG_ENABLE_WES_MODE_NAME_MIN,
3532 CFG_ENABLE_WES_MODE_NAME_MAX);
3533 ret = -EINVAL;
3534 goto exit;
3535 }
3536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3537 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3538
3539 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3540 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3541 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303542 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003543 {
3544 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3545 char extra[32];
3546 tANI_U8 len = 0;
3547
Arif Hussain826d9412013-11-12 16:44:54 -08003548 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
mukul sharma40f349e2015-08-07 14:03:26 +05303549 len = VOS_MIN(priv_data.total_len, len + 1);
3550 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3552 "%s: failed to copy data to user buffer", __func__);
3553 ret = -EFAULT;
3554 goto exit;
3555 }
3556 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003557#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003558#ifdef FEATURE_WLAN_LFR
3559 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3560 {
3561 tANI_U8 *value = command;
3562 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3563
3564 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3565 value = value + 12;
3566 /* Convert the value from ascii to integer */
3567 ret = kstrtou8(value, 10, &lfrMode);
3568 if (ret < 0)
3569 {
3570 /* If the input value is greater than max value of datatype, then also
3571 kstrtou8 fails */
3572 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3573 "%s: kstrtou8 failed range [%d - %d]", __func__,
3574 CFG_LFR_FEATURE_ENABLED_MIN,
3575 CFG_LFR_FEATURE_ENABLED_MAX);
3576 ret = -EINVAL;
3577 goto exit;
3578 }
3579
3580 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3581 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3582 {
3583 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3584 "lfr mode value %d is out of range"
3585 " (Min: %d Max: %d)", lfrMode,
3586 CFG_LFR_FEATURE_ENABLED_MIN,
3587 CFG_LFR_FEATURE_ENABLED_MAX);
3588 ret = -EINVAL;
3589 goto exit;
3590 }
3591
3592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3593 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3594
3595 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3596 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3597 }
3598#endif
3599#ifdef WLAN_FEATURE_VOWIFI_11R
3600 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3601 {
3602 tANI_U8 *value = command;
3603 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3604
3605 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3606 value = value + 18;
3607 /* Convert the value from ascii to integer */
3608 ret = kstrtou8(value, 10, &ft);
3609 if (ret < 0)
3610 {
3611 /* If the input value is greater than max value of datatype, then also
3612 kstrtou8 fails */
3613 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3614 "%s: kstrtou8 failed range [%d - %d]", __func__,
3615 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3616 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3617 ret = -EINVAL;
3618 goto exit;
3619 }
3620
3621 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3622 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3623 {
3624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3625 "ft mode value %d is out of range"
3626 " (Min: %d Max: %d)", ft,
3627 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3628 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3629 ret = -EINVAL;
3630 goto exit;
3631 }
3632
3633 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3634 "%s: Received Command to change ft mode = %d", __func__, ft);
3635
3636 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3637 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3638 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303639 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
3640 {
3641 tANI_U8 *value = command;
3642 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303643
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303644 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
3645 value = value + 15;
3646 /* Convert the value from ascii to integer */
3647 ret = kstrtou8(value, 10, &dfsScanMode);
3648 if (ret < 0)
3649 {
3650 /* If the input value is greater than max value of
3651 datatype, then also kstrtou8 fails
3652 */
3653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3654 "%s: kstrtou8 failed range [%d - %d]", __func__,
3655 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3656 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3657 ret = -EINVAL;
3658 goto exit;
3659 }
3660
3661 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
3662 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
3663 {
3664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3665 "dfsScanMode value %d is out of range"
3666 " (Min: %d Max: %d)", dfsScanMode,
3667 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3668 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3669 ret = -EINVAL;
3670 goto exit;
3671 }
3672 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3673 "%s: Received Command to Set DFS Scan Mode = %d",
3674 __func__, dfsScanMode);
3675
3676 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
3677 }
3678 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
3679 {
3680 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
3681 char extra[32];
3682 tANI_U8 len = 0;
3683
3684 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S Pd0bea392015-07-16 15:35:51 +05303685 len = VOS_MIN(priv_data.total_len, len + 1);
3686 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303687 {
3688 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3689 "%s: failed to copy data to user buffer", __func__);
3690 ret = -EFAULT;
3691 goto exit;
3692 }
3693 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303694 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3695 {
3696 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303697 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303698 tSirMacAddr targetApBssid;
3699 tANI_U8 trigger = 0;
3700 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303701 tHalHandle hHal;
3702 v_U32_t roamId = 0;
3703 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303704 hdd_station_ctx_t *pHddStaCtx = NULL;
3705 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303706 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303707
3708 /* if not associated, no need to proceed with reassoc */
3709 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3710 {
3711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3712 ret = -EINVAL;
3713 goto exit;
3714 }
3715
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303716 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303717 if (eHAL_STATUS_SUCCESS != status)
3718 {
3719 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3720 "%s: Failed to parse reassoc command data", __func__);
3721 ret = -EINVAL;
3722 goto exit;
3723 }
3724
3725 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303726 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303727 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3728 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3729 {
AnjaneeDevi Kapparapuaaa71692015-11-09 12:32:21 +05303730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3731 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3732 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303733 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3734 &modProfileFields);
3735 sme_RoamReassoc(hHal, pAdapter->sessionId,
3736 NULL, modProfileFields, &roamId, 1);
AnjaneeDevi Kapparapuaaa71692015-11-09 12:32:21 +05303737 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303738 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303739
3740 /* Check channel number is a valid channel number */
3741 if(VOS_STATUS_SUCCESS !=
3742 wlan_hdd_validate_operation_channel(pAdapter, channel))
3743 {
3744 hddLog(VOS_TRACE_LEVEL_ERROR,
3745 "%s: Invalid Channel [%d]", __func__, channel);
AnjaneeDevi Kapparapuaaa71692015-11-09 12:32:21 +05303746 return -EINVAL;
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303747 }
3748
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303749 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303750
3751 /* Proceed with scan/roam */
3752 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3753 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303754 (tSmeFastRoamTrigger)(trigger),
3755 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303756 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003757#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003758#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003759 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3760 {
3761 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003762 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003763
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003764 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003765 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003766 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003767 hdd_is_okc_mode_enabled(pHddCtx) &&
3768 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3769 {
3770 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003771 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003772 " hence this operation is not permitted!", __func__);
3773 ret = -EPERM;
3774 goto exit;
3775 }
3776
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003777 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3778 value = value + 11;
3779 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003780 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003781 if (ret < 0)
3782 {
3783 /* If the input value is greater than max value of datatype, then also
3784 kstrtou8 fails */
3785 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3786 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003787 CFG_ESE_FEATURE_ENABLED_MIN,
3788 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003789 ret = -EINVAL;
3790 goto exit;
3791 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003792 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3793 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003794 {
3795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003796 "Ese mode value %d is out of range"
3797 " (Min: %d Max: %d)", eseMode,
3798 CFG_ESE_FEATURE_ENABLED_MIN,
3799 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003800 ret = -EINVAL;
3801 goto exit;
3802 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003804 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003805
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003806 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3807 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003808 }
3809#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003810 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3811 {
3812 tANI_U8 *value = command;
3813 tANI_BOOLEAN roamScanControl = 0;
3814
3815 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3816 value = value + 19;
3817 /* Convert the value from ascii to integer */
3818 ret = kstrtou8(value, 10, &roamScanControl);
3819 if (ret < 0)
3820 {
3821 /* If the input value is greater than max value of datatype, then also
3822 kstrtou8 fails */
3823 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3824 "%s: kstrtou8 failed ", __func__);
3825 ret = -EINVAL;
3826 goto exit;
3827 }
3828
3829 if (0 != roamScanControl)
3830 {
3831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3832 "roam scan control invalid value = %d",
3833 roamScanControl);
3834 ret = -EINVAL;
3835 goto exit;
3836 }
3837 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3838 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3839
3840 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3841 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003842#ifdef FEATURE_WLAN_OKC
3843 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3844 {
3845 tANI_U8 *value = command;
3846 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3847
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003848 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003849 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003850 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003851 hdd_is_okc_mode_enabled(pHddCtx) &&
3852 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3853 {
3854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003855 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003856 " hence this operation is not permitted!", __func__);
3857 ret = -EPERM;
3858 goto exit;
3859 }
3860
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003861 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3862 value = value + 11;
3863 /* Convert the value from ascii to integer */
3864 ret = kstrtou8(value, 10, &okcMode);
3865 if (ret < 0)
3866 {
3867 /* If the input value is greater than max value of datatype, then also
3868 kstrtou8 fails */
3869 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3870 "%s: kstrtou8 failed range [%d - %d]", __func__,
3871 CFG_OKC_FEATURE_ENABLED_MIN,
3872 CFG_OKC_FEATURE_ENABLED_MAX);
3873 ret = -EINVAL;
3874 goto exit;
3875 }
3876
3877 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3878 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3879 {
3880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3881 "Okc mode value %d is out of range"
3882 " (Min: %d Max: %d)", okcMode,
3883 CFG_OKC_FEATURE_ENABLED_MIN,
3884 CFG_OKC_FEATURE_ENABLED_MAX);
3885 ret = -EINVAL;
3886 goto exit;
3887 }
3888
3889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3890 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3891
3892 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3893 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003894#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303895 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003896 {
3897 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3898 char extra[32];
3899 tANI_U8 len = 0;
3900
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003901 len = scnprintf(extra, sizeof(extra), "%s %d",
3902 command, roamScanControl);
mukul sharma8ec1dd62015-08-07 14:01:05 +05303903 len = VOS_MIN(priv_data.total_len, len + 1);
3904 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3906 "%s: failed to copy data to user buffer", __func__);
3907 ret = -EFAULT;
3908 goto exit;
3909 }
3910 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303911#ifdef WLAN_FEATURE_PACKET_FILTERING
3912 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3913 {
3914 tANI_U8 filterType = 0;
3915 tANI_U8 *value = command;
3916
3917 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3918 value = value + 22;
3919
3920 /* Convert the value from ascii to integer */
3921 ret = kstrtou8(value, 10, &filterType);
3922 if (ret < 0)
3923 {
3924 /* If the input value is greater than max value of datatype,
3925 * then also kstrtou8 fails
3926 */
3927 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3928 "%s: kstrtou8 failed range ", __func__);
3929 ret = -EINVAL;
3930 goto exit;
3931 }
3932
3933 if (filterType != 0 && filterType != 1)
3934 {
3935 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3936 "%s: Accepted Values are 0 and 1 ", __func__);
3937 ret = -EINVAL;
3938 goto exit;
3939 }
3940 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3941 pAdapter->sessionId);
3942 }
3943#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303944 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3945 {
Kiet Lamad161252014-07-22 11:23:32 -07003946 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303947 int ret;
3948
Kiet Lamad161252014-07-22 11:23:32 -07003949 dhcpPhase = command + 11;
3950 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303951 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303952 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003953 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303954
3955 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003956
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303957 ret = wlan_hdd_scan_abort(pAdapter);
3958 if (ret < 0)
3959 {
3960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3961 FL("failed to abort existing scan %d"), ret);
3962 }
3963
Kiet Lamad161252014-07-22 11:23:32 -07003964 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3965 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303966 }
Kiet Lamad161252014-07-22 11:23:32 -07003967 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303968 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303969 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003970 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303971
3972 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003973
3974 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3975 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303976 }
3977 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003978 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3979 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303980 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3981 FL("making default scan to ACTIVE"));
3982 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003983 }
3984 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3985 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303986 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3987 FL("making default scan to PASSIVE"));
3988 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003989 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303990 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3991 {
3992 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3993 char extra[32];
3994 tANI_U8 len = 0;
3995
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303996 memset(extra, 0, sizeof(extra));
3997 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
mukul sharma5eb0f372015-08-08 15:41:27 +05303998 len = VOS_MIN(priv_data.total_len, len + 1);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303999 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304000 {
4001 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4002 "%s: failed to copy data to user buffer", __func__);
4003 ret = -EFAULT;
4004 goto exit;
4005 }
4006 ret = len;
4007 }
4008 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
4009 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05304010 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304011 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004012 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
4013 {
4014 tANI_U8 filterType = 0;
4015 tANI_U8 *value;
4016 value = command + 9;
4017
4018 /* Convert the value from ascii to integer */
4019 ret = kstrtou8(value, 10, &filterType);
4020 if (ret < 0)
4021 {
4022 /* If the input value is greater than max value of datatype,
4023 * then also kstrtou8 fails
4024 */
4025 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4026 "%s: kstrtou8 failed range ", __func__);
4027 ret = -EINVAL;
4028 goto exit;
4029 }
4030 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
4031 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
4032 {
4033 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4034 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
4035 " 2-Sink ", __func__);
4036 ret = -EINVAL;
4037 goto exit;
4038 }
4039 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
4040 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05304041 pScanInfo = &pHddCtx->scan_info;
4042 if (filterType && pScanInfo != NULL &&
4043 pHddCtx->scan_info.mScanPending)
4044 {
4045 /*Miracast Session started. Abort Scan */
4046 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4047 "%s, Aborting Scan For Miracast",__func__);
4048 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
4049 eCSR_SCAN_ABORT_DEFAULT);
4050 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004051 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05304052 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004053 }
Leo Chang614d2072013-08-22 14:59:44 -07004054 else if (strncmp(command, "SETMCRATE", 9) == 0)
4055 {
Leo Chang614d2072013-08-22 14:59:44 -07004056 tANI_U8 *value = command;
4057 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07004058 tSirRateUpdateInd *rateUpdate;
4059 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07004060
4061 /* Only valid for SAP mode */
4062 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
4063 {
4064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4065 "%s: SAP mode is not running", __func__);
4066 ret = -EFAULT;
4067 goto exit;
4068 }
4069
4070 /* Move pointer to ahead of SETMCRATE<delimiter> */
4071 /* input value is in units of hundred kbps */
4072 value = value + 10;
4073 /* Convert the value from ascii to integer, decimal base */
4074 ret = kstrtouint(value, 10, &targetRate);
4075
Leo Chang1f98cbd2013-10-17 15:03:52 -07004076 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
4077 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07004078 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07004079 hddLog(VOS_TRACE_LEVEL_ERROR,
4080 "%s: SETMCRATE indication alloc fail", __func__);
4081 ret = -EFAULT;
4082 goto exit;
4083 }
4084 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
4085
4086 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4087 "MC Target rate %d", targetRate);
4088 /* Ignore unicast */
4089 rateUpdate->ucastDataRate = -1;
4090 rateUpdate->mcastDataRate24GHz = targetRate;
4091 rateUpdate->mcastDataRate5GHz = targetRate;
4092 rateUpdate->mcastDataRate24GHzTxFlag = 0;
4093 rateUpdate->mcastDataRate5GHzTxFlag = 0;
4094 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
4095 if (eHAL_STATUS_SUCCESS != status)
4096 {
4097 hddLog(VOS_TRACE_LEVEL_ERROR,
4098 "%s: SET_MC_RATE failed", __func__);
4099 vos_mem_free(rateUpdate);
4100 ret = -EFAULT;
4101 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07004102 }
4103 }
Rajeev79dbe4c2013-10-05 11:03:42 +05304104#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08004105 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05304106 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08004107 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05304108 }
4109#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004110#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004111 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
4112 {
4113 tANI_U8 *value = command;
4114 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4115 tANI_U8 numChannels = 0;
4116 eHalStatus status = eHAL_STATUS_SUCCESS;
4117
4118 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4119 if (eHAL_STATUS_SUCCESS != status)
4120 {
4121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4122 "%s: Failed to parse channel list information", __func__);
4123 ret = -EINVAL;
4124 goto exit;
4125 }
4126
4127 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4128 {
4129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4130 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4131 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4132 ret = -EINVAL;
4133 goto exit;
4134 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004135 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004136 ChannelList,
4137 numChannels);
4138 if (eHAL_STATUS_SUCCESS != status)
4139 {
4140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4141 "%s: Failed to update channel list information", __func__);
4142 ret = -EINVAL;
4143 goto exit;
4144 }
4145 }
4146 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
4147 {
4148 tANI_U8 *value = command;
4149 char extra[128] = {0};
4150 int len = 0;
4151 tANI_U8 tid = 0;
4152 hdd_station_ctx_t *pHddStaCtx = NULL;
4153 tAniTrafStrmMetrics tsmMetrics;
4154 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4155
4156 /* if not associated, return error */
4157 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4158 {
4159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
4160 ret = -EINVAL;
4161 goto exit;
4162 }
4163
4164 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
4165 value = value + 12;
4166 /* Convert the value from ascii to integer */
4167 ret = kstrtou8(value, 10, &tid);
4168 if (ret < 0)
4169 {
4170 /* If the input value is greater than max value of datatype, then also
4171 kstrtou8 fails */
4172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4173 "%s: kstrtou8 failed range [%d - %d]", __func__,
4174 TID_MIN_VALUE,
4175 TID_MAX_VALUE);
4176 ret = -EINVAL;
4177 goto exit;
4178 }
4179
4180 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4181 {
4182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4183 "tid value %d is out of range"
4184 " (Min: %d Max: %d)", tid,
4185 TID_MIN_VALUE,
4186 TID_MAX_VALUE);
4187 ret = -EINVAL;
4188 goto exit;
4189 }
4190
4191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4192 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4193
4194 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4195 {
4196 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4197 "%s: failed to get tsm stats", __func__);
4198 ret = -EFAULT;
4199 goto exit;
4200 }
4201
4202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4203 "UplinkPktQueueDly(%d)\n"
4204 "UplinkPktQueueDlyHist[0](%d)\n"
4205 "UplinkPktQueueDlyHist[1](%d)\n"
4206 "UplinkPktQueueDlyHist[2](%d)\n"
4207 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304208 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004209 "UplinkPktLoss(%d)\n"
4210 "UplinkPktCount(%d)\n"
4211 "RoamingCount(%d)\n"
4212 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4213 tsmMetrics.UplinkPktQueueDlyHist[0],
4214 tsmMetrics.UplinkPktQueueDlyHist[1],
4215 tsmMetrics.UplinkPktQueueDlyHist[2],
4216 tsmMetrics.UplinkPktQueueDlyHist[3],
4217 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4218 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4219
4220 /* Output TSM stats is of the format
4221 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4222 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004223 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004224 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4225 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4226 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4227 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4228 tsmMetrics.RoamingDly);
4229
Ratnam Rachuri1d1ace02015-08-07 13:59:00 +05304230 len = VOS_MIN(priv_data.total_len, len + 1);
4231 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4233 "%s: failed to copy data to user buffer", __func__);
4234 ret = -EFAULT;
4235 goto exit;
4236 }
4237 }
4238 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4239 {
4240 tANI_U8 *value = command;
4241 tANI_U8 *cckmIe = NULL;
4242 tANI_U8 cckmIeLen = 0;
4243 eHalStatus status = eHAL_STATUS_SUCCESS;
4244
4245 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4246 if (eHAL_STATUS_SUCCESS != status)
4247 {
4248 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4249 "%s: Failed to parse cckm ie data", __func__);
4250 ret = -EINVAL;
4251 goto exit;
4252 }
4253
4254 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4255 {
4256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4257 "%s: CCKM Ie input length is more than max[%d]", __func__,
4258 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004259 vos_mem_free(cckmIe);
4260 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004261 ret = -EINVAL;
4262 goto exit;
4263 }
4264 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004265 vos_mem_free(cckmIe);
4266 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004267 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004268 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4269 {
4270 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004271 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004272 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004273
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004274 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004275 if (eHAL_STATUS_SUCCESS != status)
4276 {
4277 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004278 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004279 ret = -EINVAL;
4280 goto exit;
4281 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004282 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4283 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4284 hdd_indicateEseBcnReportNoResults (pAdapter,
4285 eseBcnReq.bcnReq[0].measurementToken,
4286 0x02, //BIT(1) set for measurement done
4287 0); // no BSS
4288 goto exit;
4289 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004290
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004291 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4292 if (eHAL_STATUS_SUCCESS != status)
4293 {
4294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4295 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4296 ret = -EINVAL;
4297 goto exit;
4298 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004299 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004300#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304301 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4302 {
4303 eHalStatus status;
4304 char buf[32], len;
4305 long waitRet;
4306 bcnMissRateContext_t getBcnMissRateCtx;
4307
4308 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4309
4310 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4311 {
4312 hddLog(VOS_TRACE_LEVEL_WARN,
4313 FL("GETBCNMISSRATE: STA is not in connected state"));
4314 ret = -1;
4315 goto exit;
4316 }
4317
4318 init_completion(&(getBcnMissRateCtx.completion));
4319 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4320
4321 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4322 pAdapter->sessionId,
4323 (void *)getBcnMissRateCB,
4324 (void *)(&getBcnMissRateCtx));
4325 if( eHAL_STATUS_SUCCESS != status)
4326 {
4327 hddLog(VOS_TRACE_LEVEL_INFO,
4328 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4329 ret = -EINVAL;
4330 goto exit;
4331 }
4332
4333 waitRet = wait_for_completion_interruptible_timeout
4334 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4335 if(waitRet <= 0)
4336 {
4337 hddLog(VOS_TRACE_LEVEL_ERROR,
4338 FL("failed to wait on bcnMissRateComp %d"), ret);
4339
4340 //Make magic number to zero so that callback is not called.
4341 spin_lock(&hdd_context_lock);
4342 getBcnMissRateCtx.magic = 0x0;
4343 spin_unlock(&hdd_context_lock);
4344 ret = -EINVAL;
4345 goto exit;
4346 }
4347
4348 hddLog(VOS_TRACE_LEVEL_INFO,
4349 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4350
4351 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4352 if (copy_to_user(priv_data.buf, &buf, len + 1))
4353 {
4354 hddLog(VOS_TRACE_LEVEL_ERROR,
4355 "%s: failed to copy data to user buffer", __func__);
4356 ret = -EFAULT;
4357 goto exit;
4358 }
4359 ret = len;
4360 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304361#ifdef FEATURE_WLAN_TDLS
4362 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4363 tANI_U8 *value = command;
4364 int set_value;
4365 /* Move pointer to ahead of TDLSOFFCH*/
4366 value += 26;
c_manjee949b9382015-12-08 13:52:59 +05304367 if (!(sscanf(value, "%d", &set_value))) {
4368 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4369 FL("No input identified"));
4370 ret = -EINVAL;
4371 goto exit;
4372 }
4373
Atul Mittal87ec2422014-09-24 13:12:50 +05304374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4375 "%s: Tdls offchannel offset:%d",
4376 __func__, set_value);
4377 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4378 if (ret < 0)
4379 {
4380 ret = -EINVAL;
4381 goto exit;
4382 }
4383
4384 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4385 tANI_U8 *value = command;
4386 int set_value;
4387 /* Move pointer to ahead of tdlsoffchnmode*/
4388 value += 18;
c_manjee603ad442015-12-08 12:40:34 +05304389 ret = sscanf(value, "%d", &set_value);
4390 if (ret != 1) {
4391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4392 FL("No input identified"));
4393 ret = -EINVAL;
4394 goto exit;
4395 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304396 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4397 "%s: Tdls offchannel mode:%d",
4398 __func__, set_value);
4399 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4400 if (ret < 0)
4401 {
4402 ret = -EINVAL;
4403 goto exit;
4404 }
4405 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4406 tANI_U8 *value = command;
4407 int set_value;
4408 /* Move pointer to ahead of TDLSOFFCH*/
4409 value += 14;
4410 sscanf(value, "%d", &set_value);
4411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4412 "%s: Tdls offchannel num: %d",
4413 __func__, set_value);
4414 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4415 if (ret < 0)
4416 {
4417 ret = -EINVAL;
4418 goto exit;
4419 }
4420 }
4421#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304422 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4423 {
4424 eHalStatus status;
4425 char *buf = NULL;
4426 char len;
4427 long waitRet;
4428 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304429 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304430 tANI_U8 *ptr = command;
4431 int stats = *(ptr + 11) - '0';
4432
4433 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4434 if (!IS_FEATURE_FW_STATS_ENABLE)
4435 {
4436 hddLog(VOS_TRACE_LEVEL_INFO,
4437 FL("Get Firmware stats feature not supported"));
4438 ret = -EINVAL;
4439 goto exit;
4440 }
4441
4442 if (FW_STATS_MAX <= stats || 0 >= stats)
4443 {
4444 hddLog(VOS_TRACE_LEVEL_INFO,
4445 FL(" stats %d not supported"),stats);
4446 ret = -EINVAL;
4447 goto exit;
4448 }
4449
4450 init_completion(&(fwStatsCtx.completion));
4451 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4452 fwStatsCtx.pAdapter = pAdapter;
4453 fwStatsRsp->type = 0;
4454 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304455 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304456 if (eHAL_STATUS_SUCCESS != status)
4457 {
4458 hddLog(VOS_TRACE_LEVEL_ERROR,
4459 FL(" fail to post WDA cmd status = %d"), status);
4460 ret = -EINVAL;
4461 goto exit;
4462 }
4463 waitRet = wait_for_completion_timeout
4464 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4465 if (waitRet <= 0)
4466 {
4467 hddLog(VOS_TRACE_LEVEL_ERROR,
4468 FL("failed to wait on GwtFwstats"));
4469 //Make magic number to zero so that callback is not executed.
4470 spin_lock(&hdd_context_lock);
4471 fwStatsCtx.magic = 0x0;
4472 spin_unlock(&hdd_context_lock);
4473 ret = -EINVAL;
4474 goto exit;
4475 }
4476 if (fwStatsRsp->type)
4477 {
4478 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4479 if (!buf)
4480 {
4481 hddLog(VOS_TRACE_LEVEL_ERROR,
4482 FL(" failed to allocate memory"));
4483 ret = -ENOMEM;
4484 goto exit;
4485 }
4486 switch( fwStatsRsp->type )
4487 {
4488 case FW_UBSP_STATS:
4489 {
4490 len = snprintf(buf, FW_STATE_RSP_LEN,
4491 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304492 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4493 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304494 }
4495 break;
4496 default:
4497 {
4498 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4499 ret = -EFAULT;
4500 kfree(buf);
4501 goto exit;
4502 }
4503 }
4504 if (copy_to_user(priv_data.buf, buf, len + 1))
4505 {
4506 hddLog(VOS_TRACE_LEVEL_ERROR,
4507 FL(" failed to copy data to user buffer"));
4508 ret = -EFAULT;
4509 kfree(buf);
4510 goto exit;
4511 }
4512 ret = len;
4513 kfree(buf);
4514 }
4515 else
4516 {
4517 hddLog(VOS_TRACE_LEVEL_ERROR,
4518 FL("failed to fetch the stats"));
4519 ret = -EFAULT;
4520 goto exit;
4521 }
4522
4523 }
Agarwal Ashishea0af292015-06-12 18:03:45 +05304524 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
4525 {
4526 /*
4527 * this command wld be called by user-space when it detects WLAN
4528 * ON after airplane mode is set. When APM is set, WLAN turns off.
4529 * But it can be turned back on. Otherwise; when APM is turned back
4530 * off, WLAN wld turn back on. So at that point the command is
4531 * expected to come down. 0 means disable, 1 means enable. The
4532 * constraint is removed when parameter 1 is set or different
4533 * country code is set
4534 */
4535 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
4536 }
Mahesh A Saptasagar19675b02015-09-07 16:21:06 +05304537 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
4538 {
4539 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
4540 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004541 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304542 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4543 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4544 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304545 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4546 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004547 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004548 }
4549exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304550 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004551 if (command)
4552 {
4553 kfree(command);
4554 }
4555 return ret;
4556}
4557
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004558#ifdef CONFIG_COMPAT
4559static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4560{
4561 struct {
4562 compat_uptr_t buf;
4563 int used_len;
4564 int total_len;
4565 } compat_priv_data;
4566 hdd_priv_data_t priv_data;
4567 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004568
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004569 /*
4570 * Note that pAdapter and ifr have already been verified by caller,
4571 * and HDD context has also been validated
4572 */
4573 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4574 sizeof(compat_priv_data))) {
4575 ret = -EFAULT;
4576 goto exit;
4577 }
4578 priv_data.buf = compat_ptr(compat_priv_data.buf);
4579 priv_data.used_len = compat_priv_data.used_len;
4580 priv_data.total_len = compat_priv_data.total_len;
4581 ret = hdd_driver_command(pAdapter, &priv_data);
4582 exit:
4583 return ret;
4584}
4585#else /* CONFIG_COMPAT */
4586static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4587{
4588 /* will never be invoked */
4589 return 0;
4590}
4591#endif /* CONFIG_COMPAT */
4592
4593static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4594{
4595 hdd_priv_data_t priv_data;
4596 int ret = 0;
4597
4598 /*
4599 * Note that pAdapter and ifr have already been verified by caller,
4600 * and HDD context has also been validated
4601 */
4602 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4603 ret = -EFAULT;
4604 } else {
4605 ret = hdd_driver_command(pAdapter, &priv_data);
4606 }
4607 return ret;
4608}
4609
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304610int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004611{
4612 hdd_adapter_t *pAdapter;
4613 hdd_context_t *pHddCtx;
4614 int ret;
4615
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304616 ENTER();
4617
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004618 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4619 if (NULL == pAdapter) {
4620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4621 "%s: HDD adapter context is Null", __func__);
4622 ret = -ENODEV;
4623 goto exit;
4624 }
4625 if (dev != pAdapter->dev) {
4626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4627 "%s: HDD adapter/dev inconsistency", __func__);
4628 ret = -ENODEV;
4629 goto exit;
4630 }
4631
4632 if ((!ifr) || (!ifr->ifr_data)) {
4633 ret = -EINVAL;
4634 goto exit;
4635 }
4636
4637 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4638 ret = wlan_hdd_validate_context(pHddCtx);
4639 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004640 ret = -EBUSY;
4641 goto exit;
4642 }
4643
4644 switch (cmd) {
4645 case (SIOCDEVPRIVATE + 1):
4646 if (is_compat_task())
4647 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4648 else
4649 ret = hdd_driver_ioctl(pAdapter, ifr);
4650 break;
4651 default:
4652 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4653 __func__, cmd);
4654 ret = -EINVAL;
4655 break;
4656 }
4657 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304658 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004659 return ret;
4660}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004661
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304662int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4663{
4664 int ret;
4665
4666 vos_ssr_protect(__func__);
4667 ret = __hdd_ioctl(dev, ifr, cmd);
4668 vos_ssr_unprotect(__func__);
4669
4670 return ret;
4671}
4672
Katya Nigame7b69a82015-04-28 15:24:06 +05304673int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4674{
4675 return 0;
4676}
4677
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004678#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004679/**---------------------------------------------------------------------------
4680
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004681 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004682
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004683 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004684 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4685 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4686 <space>Scan Mode N<space>Meas Duration N
4687 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4688 then take N.
4689 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4690 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4691 This function does not take care of removing duplicate channels from the list
4692
4693 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004694 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004695
4696 \return - 0 for success non-zero for failure
4697
4698 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004699static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4700 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004701{
4702 tANI_U8 *inPtr = pValue;
4703 int tempInt = 0;
4704 int j = 0, i = 0, v = 0;
4705 char buf[32];
4706
4707 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4708 /*no argument after the command*/
4709 if (NULL == inPtr)
4710 {
4711 return -EINVAL;
4712 }
4713 /*no space after the command*/
4714 else if (SPACE_ASCII_VALUE != *inPtr)
4715 {
4716 return -EINVAL;
4717 }
4718
4719 /*removing empty spaces*/
4720 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4721
4722 /*no argument followed by spaces*/
4723 if ('\0' == *inPtr) return -EINVAL;
4724
4725 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004726 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004727 if (1 != v) return -EINVAL;
4728
4729 v = kstrtos32(buf, 10, &tempInt);
4730 if ( v < 0) return -EINVAL;
4731
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004732 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004733
4734 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004735 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004736
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004737 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004738 {
4739 for (i = 0; i < 4; i++)
4740 {
4741 /*inPtr pointing to the beginning of first space after number of ie fields*/
4742 inPtr = strpbrk( inPtr, " " );
4743 /*no ie data after the number of ie fields argument*/
4744 if (NULL == inPtr) return -EINVAL;
4745
4746 /*removing empty space*/
4747 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4748
4749 /*no ie data after the number of ie fields argument and spaces*/
4750 if ( '\0' == *inPtr ) return -EINVAL;
4751
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004752 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004753 if (1 != v) return -EINVAL;
4754
4755 v = kstrtos32(buf, 10, &tempInt);
4756 if (v < 0) return -EINVAL;
4757
4758 switch (i)
4759 {
4760 case 0: /* Measurement token */
4761 if (tempInt <= 0)
4762 {
4763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4764 "Invalid Measurement Token(%d)", tempInt);
4765 return -EINVAL;
4766 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004767 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004768 break;
4769
4770 case 1: /* Channel number */
4771 if ((tempInt <= 0) ||
4772 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4773 {
4774 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4775 "Invalid Channel Number(%d)", tempInt);
4776 return -EINVAL;
4777 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004778 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004779 break;
4780
4781 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004782 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004783 {
4784 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4785 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4786 return -EINVAL;
4787 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004788 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004789 break;
4790
4791 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004792 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4793 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004794 {
4795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4796 "Invalid Measurement Duration(%d)", tempInt);
4797 return -EINVAL;
4798 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004799 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004800 break;
4801 }
4802 }
4803 }
4804
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004805 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004806 {
4807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304808 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004809 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004810 pEseBcnReq->bcnReq[j].measurementToken,
4811 pEseBcnReq->bcnReq[j].channel,
4812 pEseBcnReq->bcnReq[j].scanMode,
4813 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004814 }
4815
4816 return VOS_STATUS_SUCCESS;
4817}
4818
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004819static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4820{
4821 struct statsContext *pStatsContext = NULL;
4822 hdd_adapter_t *pAdapter = NULL;
4823
4824 if (NULL == pContext)
4825 {
4826 hddLog(VOS_TRACE_LEVEL_ERROR,
4827 "%s: Bad param, pContext [%p]",
4828 __func__, pContext);
4829 return;
4830 }
4831
Jeff Johnson72a40512013-12-19 10:14:15 -08004832 /* there is a race condition that exists between this callback
4833 function and the caller since the caller could time out either
4834 before or while this code is executing. we use a spinlock to
4835 serialize these actions */
4836 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004837
4838 pStatsContext = pContext;
4839 pAdapter = pStatsContext->pAdapter;
4840 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4841 {
4842 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004843 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004844 hddLog(VOS_TRACE_LEVEL_WARN,
4845 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4846 __func__, pAdapter, pStatsContext->magic);
4847 return;
4848 }
4849
Jeff Johnson72a40512013-12-19 10:14:15 -08004850 /* context is valid so caller is still waiting */
4851
4852 /* paranoia: invalidate the magic */
4853 pStatsContext->magic = 0;
4854
4855 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004856 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4857 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4858 tsmMetrics.UplinkPktQueueDlyHist,
4859 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4860 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4861 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4862 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4863 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4864 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4865 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4866
Jeff Johnson72a40512013-12-19 10:14:15 -08004867 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004868 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004869
4870 /* serialization is complete */
4871 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004872}
4873
4874
4875
4876static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4877 tAniTrafStrmMetrics* pTsmMetrics)
4878{
4879 hdd_station_ctx_t *pHddStaCtx = NULL;
4880 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004881 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004882 long lrc;
4883 struct statsContext context;
4884 hdd_context_t *pHddCtx = NULL;
4885
4886 if (NULL == pAdapter)
4887 {
4888 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4889 return VOS_STATUS_E_FAULT;
4890 }
4891
4892 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4893 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4894
4895 /* we are connected prepare our callback context */
4896 init_completion(&context.completion);
4897 context.pAdapter = pAdapter;
4898 context.magic = STATS_CONTEXT_MAGIC;
4899
4900 /* query tsm stats */
4901 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4902 pHddStaCtx->conn_info.staId[ 0 ],
4903 pHddStaCtx->conn_info.bssId,
4904 &context, pHddCtx->pvosContext, tid);
4905
4906 if (eHAL_STATUS_SUCCESS != hstatus)
4907 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004908 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4909 __func__);
4910 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004911 }
4912 else
4913 {
4914 /* request was sent -- wait for the response */
4915 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4916 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004917 if (lrc <= 0)
4918 {
4919 hddLog(VOS_TRACE_LEVEL_ERROR,
4920 "%s: SME %s while retrieving statistics",
4921 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004922 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004923 }
4924 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004925
Jeff Johnson72a40512013-12-19 10:14:15 -08004926 /* either we never sent a request, we sent a request and received a
4927 response or we sent a request and timed out. if we never sent a
4928 request or if we sent a request and got a response, we want to
4929 clear the magic out of paranoia. if we timed out there is a
4930 race condition such that the callback function could be
4931 executing at the same time we are. of primary concern is if the
4932 callback function had already verified the "magic" but had not
4933 yet set the completion variable when a timeout occurred. we
4934 serialize these activities by invalidating the magic while
4935 holding a shared spinlock which will cause us to block if the
4936 callback is currently executing */
4937 spin_lock(&hdd_context_lock);
4938 context.magic = 0;
4939 spin_unlock(&hdd_context_lock);
4940
4941 if (VOS_STATUS_SUCCESS == vstatus)
4942 {
4943 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4944 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4945 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4946 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4947 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4948 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4949 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4950 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4951 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4952 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4953 }
4954 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004955}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004956#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004957
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004958#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004959void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4960{
4961 eCsrBand band = -1;
4962 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4963 switch (band)
4964 {
4965 case eCSR_BAND_ALL:
4966 *pBand = WLAN_HDD_UI_BAND_AUTO;
4967 break;
4968
4969 case eCSR_BAND_24:
4970 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4971 break;
4972
4973 case eCSR_BAND_5G:
4974 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4975 break;
4976
4977 default:
4978 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4979 *pBand = -1;
4980 break;
4981 }
4982}
4983
4984/**---------------------------------------------------------------------------
4985
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004986 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4987
4988 This function parses the send action frame data passed in the format
4989 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4990
Srinivas Girigowda56076852013-08-20 14:00:50 -07004991 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004992 \param - pTargetApBssid Pointer to target Ap bssid
4993 \param - pChannel Pointer to the Target AP channel
4994 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4995 \param - pBuf Pointer to data
4996 \param - pBufLen Pointer to data length
4997
4998 \return - 0 for success non-zero for failure
4999
5000 --------------------------------------------------------------------------*/
5001VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
5002 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
5003{
5004 tANI_U8 *inPtr = pValue;
5005 tANI_U8 *dataEnd;
5006 int tempInt;
5007 int j = 0;
5008 int i = 0;
5009 int v = 0;
5010 tANI_U8 tempBuf[32];
5011 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005012 /* 12 hexa decimal digits, 5 ':' and '\0' */
5013 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005014
5015 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5016 /*no argument after the command*/
5017 if (NULL == inPtr)
5018 {
5019 return -EINVAL;
5020 }
5021
5022 /*no space after the command*/
5023 else if (SPACE_ASCII_VALUE != *inPtr)
5024 {
5025 return -EINVAL;
5026 }
5027
5028 /*removing empty spaces*/
5029 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5030
5031 /*no argument followed by spaces*/
5032 if ('\0' == *inPtr)
5033 {
5034 return -EINVAL;
5035 }
5036
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005037 v = sscanf(inPtr, "%17s", macAddress);
5038 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005039 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005040 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5041 "Invalid MAC address or All hex inputs are not read (%d)", v);
5042 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005043 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005044
5045 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5046 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5047 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5048 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5049 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5050 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005051
5052 /* point to the next argument */
5053 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5054 /*no argument after the command*/
5055 if (NULL == inPtr) return -EINVAL;
5056
5057 /*removing empty spaces*/
5058 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5059
5060 /*no argument followed by spaces*/
5061 if ('\0' == *inPtr)
5062 {
5063 return -EINVAL;
5064 }
5065
5066 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005067 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005068 if (1 != v) return -EINVAL;
5069
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005070 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05305071 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05305072 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005073
5074 *pChannel = tempInt;
5075
5076 /* point to the next argument */
5077 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5078 /*no argument after the command*/
5079 if (NULL == inPtr) return -EINVAL;
5080 /*removing empty spaces*/
5081 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5082
5083 /*no argument followed by spaces*/
5084 if ('\0' == *inPtr)
5085 {
5086 return -EINVAL;
5087 }
5088
5089 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005090 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005091 if (1 != v) return -EINVAL;
5092
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005093 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08005094 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005095
5096 *pDwellTime = tempInt;
5097
5098 /* point to the next argument */
5099 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5100 /*no argument after the command*/
5101 if (NULL == inPtr) return -EINVAL;
5102 /*removing empty spaces*/
5103 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5104
5105 /*no argument followed by spaces*/
5106 if ('\0' == *inPtr)
5107 {
5108 return -EINVAL;
5109 }
5110
5111 /* find the length of data */
5112 dataEnd = inPtr;
5113 while(('\0' != *dataEnd) )
5114 {
5115 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005116 }
Kiet Lambe150c22013-11-21 16:30:32 +05305117 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005118 if ( *pBufLen <= 0) return -EINVAL;
5119
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07005120 /* Allocate the number of bytes based on the number of input characters
5121 whether it is even or odd.
5122 if the number of input characters are even, then we need N/2 byte.
5123 if the number of input characters are odd, then we need do (N+1)/2 to
5124 compensate rounding off.
5125 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5126 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5127 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005128 if (NULL == *pBuf)
5129 {
5130 hddLog(VOS_TRACE_LEVEL_FATAL,
5131 "%s: vos_mem_alloc failed ", __func__);
5132 return -EINVAL;
5133 }
5134
5135 /* the buffer received from the upper layer is character buffer,
5136 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5137 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5138 and f0 in 3rd location */
5139 for (i = 0, j = 0; j < *pBufLen; j += 2)
5140 {
Kiet Lambe150c22013-11-21 16:30:32 +05305141 if( j+1 == *pBufLen)
5142 {
5143 tempByte = hdd_parse_hex(inPtr[j]);
5144 }
5145 else
5146 {
5147 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5148 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005149 (*pBuf)[i++] = tempByte;
5150 }
5151 *pBufLen = i;
5152 return VOS_STATUS_SUCCESS;
5153}
5154
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005155/**---------------------------------------------------------------------------
5156
Srinivas Girigowdade697412013-02-14 16:31:48 -08005157 \brief hdd_parse_channellist() - HDD Parse channel list
5158
5159 This function parses the channel list passed in the format
5160 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005161 if the Number of channels (N) does not match with the actual number of channels passed
5162 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
5163 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
5164 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
5165 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08005166
5167 \param - pValue Pointer to input channel list
5168 \param - ChannelList Pointer to local output array to record channel list
5169 \param - pNumChannels Pointer to number of roam scan channels
5170
5171 \return - 0 for success non-zero for failure
5172
5173 --------------------------------------------------------------------------*/
5174VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
5175{
5176 tANI_U8 *inPtr = pValue;
5177 int tempInt;
5178 int j = 0;
5179 int v = 0;
5180 char buf[32];
5181
5182 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5183 /*no argument after the command*/
5184 if (NULL == inPtr)
5185 {
5186 return -EINVAL;
5187 }
5188
5189 /*no space after the command*/
5190 else if (SPACE_ASCII_VALUE != *inPtr)
5191 {
5192 return -EINVAL;
5193 }
5194
5195 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005196 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005197
5198 /*no argument followed by spaces*/
5199 if ('\0' == *inPtr)
5200 {
5201 return -EINVAL;
5202 }
5203
5204 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005205 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005206 if (1 != v) return -EINVAL;
5207
Srinivas Girigowdade697412013-02-14 16:31:48 -08005208 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005209 if ((v < 0) ||
5210 (tempInt <= 0) ||
5211 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
5212 {
5213 return -EINVAL;
5214 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005215
5216 *pNumChannels = tempInt;
5217
5218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5219 "Number of channels are: %d", *pNumChannels);
5220
5221 for (j = 0; j < (*pNumChannels); j++)
5222 {
5223 /*inPtr pointing to the beginning of first space after number of channels*/
5224 inPtr = strpbrk( inPtr, " " );
5225 /*no channel list after the number of channels argument*/
5226 if (NULL == inPtr)
5227 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005228 if (0 != j)
5229 {
5230 *pNumChannels = j;
5231 return VOS_STATUS_SUCCESS;
5232 }
5233 else
5234 {
5235 return -EINVAL;
5236 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005237 }
5238
5239 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005240 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005241
5242 /*no channel list after the number of channels argument and spaces*/
5243 if ( '\0' == *inPtr )
5244 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005245 if (0 != j)
5246 {
5247 *pNumChannels = j;
5248 return VOS_STATUS_SUCCESS;
5249 }
5250 else
5251 {
5252 return -EINVAL;
5253 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005254 }
5255
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005256 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005257 if (1 != v) return -EINVAL;
5258
Srinivas Girigowdade697412013-02-14 16:31:48 -08005259 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005260 if ((v < 0) ||
5261 (tempInt <= 0) ||
5262 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5263 {
5264 return -EINVAL;
5265 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005266 pChannelList[j] = tempInt;
5267
5268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5269 "Channel %d added to preferred channel list",
5270 pChannelList[j] );
5271 }
5272
Srinivas Girigowdade697412013-02-14 16:31:48 -08005273 return VOS_STATUS_SUCCESS;
5274}
5275
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005276
5277/**---------------------------------------------------------------------------
5278
5279 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5280
5281 This function parses the reasoc command data passed in the format
5282 REASSOC<space><bssid><space><channel>
5283
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005284 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005285 \param - pTargetApBssid Pointer to target Ap bssid
5286 \param - pChannel Pointer to the Target AP channel
5287
5288 \return - 0 for success non-zero for failure
5289
5290 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005291VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5292 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005293{
5294 tANI_U8 *inPtr = pValue;
5295 int tempInt;
5296 int v = 0;
5297 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005298 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005299 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005300
5301 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5302 /*no argument after the command*/
5303 if (NULL == inPtr)
5304 {
5305 return -EINVAL;
5306 }
5307
5308 /*no space after the command*/
5309 else if (SPACE_ASCII_VALUE != *inPtr)
5310 {
5311 return -EINVAL;
5312 }
5313
5314 /*removing empty spaces*/
5315 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5316
5317 /*no argument followed by spaces*/
5318 if ('\0' == *inPtr)
5319 {
5320 return -EINVAL;
5321 }
5322
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005323 v = sscanf(inPtr, "%17s", macAddress);
5324 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005325 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5327 "Invalid MAC address or All hex inputs are not read (%d)", v);
5328 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005329 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005330
5331 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5332 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5333 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5334 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5335 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5336 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005337
5338 /* point to the next argument */
5339 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5340 /*no argument after the command*/
5341 if (NULL == inPtr) return -EINVAL;
5342
5343 /*removing empty spaces*/
5344 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5345
5346 /*no argument followed by spaces*/
5347 if ('\0' == *inPtr)
5348 {
5349 return -EINVAL;
5350 }
5351
5352 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005353 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005354 if (1 != v) return -EINVAL;
5355
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005356 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005357 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305358 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005359 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5360 {
5361 return -EINVAL;
5362 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005363
5364 *pChannel = tempInt;
5365 return VOS_STATUS_SUCCESS;
5366}
5367
5368#endif
5369
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005370#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005371/**---------------------------------------------------------------------------
5372
5373 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5374
5375 This function parses the SETCCKM IE command
5376 SETCCKMIE<space><ie data>
5377
5378 \param - pValue Pointer to input data
5379 \param - pCckmIe Pointer to output cckm Ie
5380 \param - pCckmIeLen Pointer to output cckm ie length
5381
5382 \return - 0 for success non-zero for failure
5383
5384 --------------------------------------------------------------------------*/
5385VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5386 tANI_U8 *pCckmIeLen)
5387{
5388 tANI_U8 *inPtr = pValue;
5389 tANI_U8 *dataEnd;
5390 int j = 0;
5391 int i = 0;
5392 tANI_U8 tempByte = 0;
5393
5394 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5395 /*no argument after the command*/
5396 if (NULL == inPtr)
5397 {
5398 return -EINVAL;
5399 }
5400
5401 /*no space after the command*/
5402 else if (SPACE_ASCII_VALUE != *inPtr)
5403 {
5404 return -EINVAL;
5405 }
5406
5407 /*removing empty spaces*/
5408 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5409
5410 /*no argument followed by spaces*/
5411 if ('\0' == *inPtr)
5412 {
5413 return -EINVAL;
5414 }
5415
5416 /* find the length of data */
5417 dataEnd = inPtr;
5418 while(('\0' != *dataEnd) )
5419 {
5420 dataEnd++;
5421 ++(*pCckmIeLen);
5422 }
5423 if ( *pCckmIeLen <= 0) return -EINVAL;
5424
5425 /* Allocate the number of bytes based on the number of input characters
5426 whether it is even or odd.
5427 if the number of input characters are even, then we need N/2 byte.
5428 if the number of input characters are odd, then we need do (N+1)/2 to
5429 compensate rounding off.
5430 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5431 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5432 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5433 if (NULL == *pCckmIe)
5434 {
5435 hddLog(VOS_TRACE_LEVEL_FATAL,
5436 "%s: vos_mem_alloc failed ", __func__);
5437 return -EINVAL;
5438 }
5439 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5440 /* the buffer received from the upper layer is character buffer,
5441 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5442 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5443 and f0 in 3rd location */
5444 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5445 {
5446 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5447 (*pCckmIe)[i++] = tempByte;
5448 }
5449 *pCckmIeLen = i;
5450
5451 return VOS_STATUS_SUCCESS;
5452}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005453#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005454
Jeff Johnson295189b2012-06-20 16:38:30 -07005455/**---------------------------------------------------------------------------
5456
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005457 \brief hdd_is_valid_mac_address() - Validate MAC address
5458
5459 This function validates whether the given MAC address is valid or not
5460 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5461 where X is the hexa decimal digit character and separated by ':'
5462 This algorithm works even if MAC address is not separated by ':'
5463
5464 This code checks given input string mac contains exactly 12 hexadecimal digits.
5465 and a separator colon : appears in the input string only after
5466 an even number of hex digits.
5467
5468 \param - pMacAddr pointer to the input MAC address
5469 \return - 1 for valid and 0 for invalid
5470
5471 --------------------------------------------------------------------------*/
5472
5473v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5474{
5475 int xdigit = 0;
5476 int separator = 0;
5477 while (*pMacAddr)
5478 {
5479 if (isxdigit(*pMacAddr))
5480 {
5481 xdigit++;
5482 }
5483 else if (':' == *pMacAddr)
5484 {
5485 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5486 break;
5487
5488 ++separator;
5489 }
5490 else
5491 {
5492 separator = -1;
5493 /* Invalid MAC found */
5494 return 0;
5495 }
5496 ++pMacAddr;
5497 }
5498 return (xdigit == 12 && (separator == 5 || separator == 0));
5499}
5500
5501/**---------------------------------------------------------------------------
5502
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305503 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005504
5505 \param - dev Pointer to net_device structure
5506
5507 \return - 0 for success non-zero for failure
5508
5509 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305510int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005511{
5512 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5513 hdd_context_t *pHddCtx;
5514 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5515 VOS_STATUS status;
5516 v_BOOL_t in_standby = TRUE;
5517
5518 if (NULL == pAdapter)
5519 {
5520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305521 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005522 return -ENODEV;
5523 }
5524
5525 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305526 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5527 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005528 if (NULL == pHddCtx)
5529 {
5530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005531 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005532 return -ENODEV;
5533 }
5534
5535 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5536 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5537 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005538 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5539 {
5540 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305541 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005542 in_standby = FALSE;
5543 break;
5544 }
5545 else
5546 {
5547 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5548 pAdapterNode = pNext;
5549 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005550 }
5551
5552 if (TRUE == in_standby)
5553 {
5554 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5555 {
5556 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5557 "wlan out of power save", __func__);
5558 return -EINVAL;
5559 }
5560 }
5561
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005562 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005563 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5564 {
5565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005566 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005567 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305568 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005569 netif_tx_start_all_queues(dev);
5570 }
5571
5572 return 0;
5573}
5574
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305575/**---------------------------------------------------------------------------
5576
5577 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5578
5579 This is called in response to ifconfig up
5580
5581 \param - dev Pointer to net_device structure
5582
5583 \return - 0 for success non-zero for failure
5584
5585 --------------------------------------------------------------------------*/
5586int hdd_open(struct net_device *dev)
5587{
5588 int ret;
5589
5590 vos_ssr_protect(__func__);
5591 ret = __hdd_open(dev);
5592 vos_ssr_unprotect(__func__);
5593
5594 return ret;
5595}
5596
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305597int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005598{
5599 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5600
5601 if(pAdapter == NULL) {
5602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005603 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005604 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005605 }
5606
Jeff Johnson295189b2012-06-20 16:38:30 -07005607 return 0;
5608}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305609
5610int hdd_mon_open (struct net_device *dev)
5611{
5612 int ret;
5613
5614 vos_ssr_protect(__func__);
5615 ret = __hdd_mon_open(dev);
5616 vos_ssr_unprotect(__func__);
5617
5618 return ret;
5619}
5620
Katya Nigame7b69a82015-04-28 15:24:06 +05305621int hdd_mon_stop(struct net_device *dev)
5622{
5623 return 0;
5624}
5625
Jeff Johnson295189b2012-06-20 16:38:30 -07005626/**---------------------------------------------------------------------------
5627
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305628 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005629
5630 \param - dev Pointer to net_device structure
5631
5632 \return - 0 for success non-zero for failure
5633
5634 --------------------------------------------------------------------------*/
5635
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305636int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005637{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305638 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005639 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5640 hdd_context_t *pHddCtx;
5641 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5642 VOS_STATUS status;
5643 v_BOOL_t enter_standby = TRUE;
5644
5645 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005646 if (NULL == pAdapter)
5647 {
5648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305649 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005650 return -ENODEV;
5651 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305652 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305653 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305654
5655 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5656 ret = wlan_hdd_validate_context(pHddCtx);
5657 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005658 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305659 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005660 }
5661
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305662 /* Nothing to be done if the interface is not opened */
5663 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5664 {
5665 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5666 "%s: NETDEV Interface is not OPENED", __func__);
5667 return -ENODEV;
5668 }
5669
5670 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005671 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005672 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305673
5674 /* Disable TX on the interface, after this hard_start_xmit() will not
5675 * be called on that interface
5676 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305677 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005678 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305679
5680 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005681 netif_carrier_off(pAdapter->dev);
5682
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305683 /* The interface is marked as down for outside world (aka kernel)
5684 * But the driver is pretty much alive inside. The driver needs to
5685 * tear down the existing connection on the netdev (session)
5686 * cleanup the data pipes and wait until the control plane is stabilized
5687 * for this interface. The call also needs to wait until the above
5688 * mentioned actions are completed before returning to the caller.
5689 * Notice that the hdd_stop_adapter is requested not to close the session
5690 * That is intentional to be able to scan if it is a STA/P2P interface
5691 */
5692 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305693#ifdef FEATURE_WLAN_TDLS
5694 mutex_lock(&pHddCtx->tdls_lock);
5695#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305696 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305697 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305698#ifdef FEATURE_WLAN_TDLS
5699 mutex_unlock(&pHddCtx->tdls_lock);
5700#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005701 /* SoftAP ifaces should never go in power save mode
5702 making sure same here. */
5703 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5704 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005705 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005706 )
5707 {
5708 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305709 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5710 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005711 EXIT();
5712 return 0;
5713 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305714 /* Find if any iface is up. If any iface is up then can't put device to
5715 * sleep/power save mode
5716 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005717 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5718 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5719 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005720 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5721 {
5722 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305723 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005724 enter_standby = FALSE;
5725 break;
5726 }
5727 else
5728 {
5729 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5730 pAdapterNode = pNext;
5731 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005732 }
5733
5734 if (TRUE == enter_standby)
5735 {
5736 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5737 "entering standby", __func__);
5738 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5739 {
5740 /*log and return success*/
5741 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5742 "wlan in power save", __func__);
5743 }
5744 }
5745
5746 EXIT();
5747 return 0;
5748}
5749
5750/**---------------------------------------------------------------------------
5751
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305752 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005753
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305754 This is called in response to ifconfig down
5755
5756 \param - dev Pointer to net_device structure
5757
5758 \return - 0 for success non-zero for failure
5759-----------------------------------------------------------------------------*/
5760int hdd_stop (struct net_device *dev)
5761{
5762 int ret;
5763
5764 vos_ssr_protect(__func__);
5765 ret = __hdd_stop(dev);
5766 vos_ssr_unprotect(__func__);
5767
5768 return ret;
5769}
5770
5771/**---------------------------------------------------------------------------
5772
5773 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005774
5775 \param - dev Pointer to net_device structure
5776
5777 \return - void
5778
5779 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305780static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005781{
5782 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305783 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005784 ENTER();
5785
5786 do
5787 {
5788 if (NULL == pAdapter)
5789 {
5790 hddLog(VOS_TRACE_LEVEL_FATAL,
5791 "%s: NULL pAdapter", __func__);
5792 break;
5793 }
5794
5795 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5796 {
5797 hddLog(VOS_TRACE_LEVEL_FATAL,
5798 "%s: Invalid magic", __func__);
5799 break;
5800 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305801 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5802 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005803 {
5804 hddLog(VOS_TRACE_LEVEL_FATAL,
5805 "%s: NULL pHddCtx", __func__);
5806 break;
5807 }
5808
5809 if (dev != pAdapter->dev)
5810 {
5811 hddLog(VOS_TRACE_LEVEL_FATAL,
5812 "%s: Invalid device reference", __func__);
5813 /* we haven't validated all cases so let this go for now */
5814 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305815#ifdef FEATURE_WLAN_TDLS
5816 mutex_lock(&pHddCtx->tdls_lock);
5817#endif
c_hpothu002231a2015-02-05 14:58:51 +05305818 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305819#ifdef FEATURE_WLAN_TDLS
5820 mutex_unlock(&pHddCtx->tdls_lock);
5821#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005822
5823 /* after uninit our adapter structure will no longer be valid */
5824 pAdapter->dev = NULL;
5825 pAdapter->magic = 0;
5826 } while (0);
5827
5828 EXIT();
5829}
5830
5831/**---------------------------------------------------------------------------
5832
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305833 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5834
5835 This is called during the netdev unregister to uninitialize all data
5836associated with the device
5837
5838 \param - dev Pointer to net_device structure
5839
5840 \return - void
5841
5842 --------------------------------------------------------------------------*/
5843static void hdd_uninit (struct net_device *dev)
5844{
5845 vos_ssr_protect(__func__);
5846 __hdd_uninit(dev);
5847 vos_ssr_unprotect(__func__);
5848}
5849
5850/**---------------------------------------------------------------------------
5851
Jeff Johnson295189b2012-06-20 16:38:30 -07005852 \brief hdd_release_firmware() -
5853
5854 This function calls the release firmware API to free the firmware buffer.
5855
5856 \param - pFileName Pointer to the File Name.
5857 pCtx - Pointer to the adapter .
5858
5859
5860 \return - 0 for success, non zero for failure
5861
5862 --------------------------------------------------------------------------*/
5863
5864VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5865{
5866 VOS_STATUS status = VOS_STATUS_SUCCESS;
5867 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5868 ENTER();
5869
5870
5871 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5872
5873 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5874
5875 if(pHddCtx->fw) {
5876 release_firmware(pHddCtx->fw);
5877 pHddCtx->fw = NULL;
5878 }
5879 else
5880 status = VOS_STATUS_E_FAILURE;
5881 }
5882 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5883 if(pHddCtx->nv) {
5884 release_firmware(pHddCtx->nv);
5885 pHddCtx->nv = NULL;
5886 }
5887 else
5888 status = VOS_STATUS_E_FAILURE;
5889
5890 }
5891
5892 EXIT();
5893 return status;
5894}
5895
5896/**---------------------------------------------------------------------------
5897
5898 \brief hdd_request_firmware() -
5899
5900 This function reads the firmware file using the request firmware
5901 API and returns the the firmware data and the firmware file size.
5902
5903 \param - pfileName - Pointer to the file name.
5904 - pCtx - Pointer to the adapter .
5905 - ppfw_data - Pointer to the pointer of the firmware data.
5906 - pSize - Pointer to the file size.
5907
5908 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5909
5910 --------------------------------------------------------------------------*/
5911
5912
5913VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5914{
5915 int status;
5916 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5917 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5918 ENTER();
5919
5920 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5921
5922 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5923
5924 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5925 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5926 __func__, pfileName);
5927 retval = VOS_STATUS_E_FAILURE;
5928 }
5929
5930 else {
5931 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5932 *pSize = pHddCtx->fw->size;
5933 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5934 __func__, *pSize);
5935 }
5936 }
5937 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5938
5939 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5940
5941 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5942 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5943 __func__, pfileName);
5944 retval = VOS_STATUS_E_FAILURE;
5945 }
5946
5947 else {
5948 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5949 *pSize = pHddCtx->nv->size;
5950 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5951 __func__, *pSize);
5952 }
5953 }
5954
5955 EXIT();
5956 return retval;
5957}
5958/**---------------------------------------------------------------------------
5959 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5960
5961 This is the function invoked by SME to inform the result of a full power
5962 request issued by HDD
5963
5964 \param - callbackcontext - Pointer to cookie
5965 status - result of request
5966
5967 \return - None
5968
5969--------------------------------------------------------------------------*/
5970void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5971{
5972 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5973
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005974 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005975 if(&pHddCtx->full_pwr_comp_var)
5976 {
5977 complete(&pHddCtx->full_pwr_comp_var);
5978 }
5979}
5980
5981/**---------------------------------------------------------------------------
5982
5983 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5984
5985 This is the function invoked by SME to inform the result of BMPS
5986 request issued by HDD
5987
5988 \param - callbackcontext - Pointer to cookie
5989 status - result of request
5990
5991 \return - None
5992
5993--------------------------------------------------------------------------*/
5994void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5995{
5996
5997 struct completion *completion_var = (struct completion*) callbackContext;
5998
Arif Hussain6d2a3322013-11-17 19:50:10 -08005999 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006000 if(completion_var != NULL)
6001 {
6002 complete(completion_var);
6003 }
6004}
6005
6006/**---------------------------------------------------------------------------
6007
6008 \brief hdd_get_cfg_file_size() -
6009
6010 This function reads the configuration file using the request firmware
6011 API and returns the configuration file size.
6012
6013 \param - pCtx - Pointer to the adapter .
6014 - pFileName - Pointer to the file name.
6015 - pBufSize - Pointer to the buffer size.
6016
6017 \return - 0 for success, non zero for failure
6018
6019 --------------------------------------------------------------------------*/
6020
6021VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
6022{
6023 int status;
6024 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
6025
6026 ENTER();
6027
6028 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
6029
6030 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
6031 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
6032 status = VOS_STATUS_E_FAILURE;
6033 }
6034 else {
6035 *pBufSize = pHddCtx->fw->size;
6036 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
6037 release_firmware(pHddCtx->fw);
6038 pHddCtx->fw = NULL;
6039 }
6040
6041 EXIT();
6042 return VOS_STATUS_SUCCESS;
6043}
6044
6045/**---------------------------------------------------------------------------
6046
6047 \brief hdd_read_cfg_file() -
6048
6049 This function reads the configuration file using the request firmware
6050 API and returns the cfg data and the buffer size of the configuration file.
6051
6052 \param - pCtx - Pointer to the adapter .
6053 - pFileName - Pointer to the file name.
6054 - pBuffer - Pointer to the data buffer.
6055 - pBufSize - Pointer to the buffer size.
6056
6057 \return - 0 for success, non zero for failure
6058
6059 --------------------------------------------------------------------------*/
6060
6061VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
6062 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
6063{
6064 int status;
6065 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
6066
6067 ENTER();
6068
6069 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
6070
6071 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
6072 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
6073 return VOS_STATUS_E_FAILURE;
6074 }
6075 else {
6076 if(*pBufSize != pHddCtx->fw->size) {
6077 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
6078 "file size", __func__);
6079 release_firmware(pHddCtx->fw);
6080 pHddCtx->fw = NULL;
6081 return VOS_STATUS_E_FAILURE;
6082 }
6083 else {
6084 if(pBuffer) {
6085 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
6086 }
6087 release_firmware(pHddCtx->fw);
6088 pHddCtx->fw = NULL;
6089 }
6090 }
6091
6092 EXIT();
6093
6094 return VOS_STATUS_SUCCESS;
6095}
6096
6097/**---------------------------------------------------------------------------
6098
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306099 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07006100
6101 This function sets the user specified mac address using
6102 the command ifconfig wlanX hw ether <mac adress>.
6103
6104 \param - dev - Pointer to the net device.
6105 - addr - Pointer to the sockaddr.
6106 \return - 0 for success, non zero for failure
6107
6108 --------------------------------------------------------------------------*/
6109
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306110static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07006111{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306112 hdd_adapter_t *pAdapter;
6113 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006114 struct sockaddr *psta_mac_addr = addr;
6115 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306116 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006117
6118 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306119 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6120 if (NULL == pAdapter)
6121 {
6122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6123 "%s: Adapter is NULL",__func__);
6124 return -EINVAL;
6125 }
6126 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6127 ret = wlan_hdd_validate_context(pHddCtx);
6128 if (0 != ret)
6129 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306130 return ret;
6131 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006132
6133 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07006134 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
6135
6136 EXIT();
6137 return halStatus;
6138}
6139
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306140/**---------------------------------------------------------------------------
6141
6142 \brief hdd_set_mac_address() -
6143
6144 Wrapper function to protect __hdd_set_mac_address() function from ssr
6145
6146 \param - dev - Pointer to the net device.
6147 - addr - Pointer to the sockaddr.
6148 \return - 0 for success, non zero for failure
6149
6150 --------------------------------------------------------------------------*/
6151static int hdd_set_mac_address(struct net_device *dev, void *addr)
6152{
6153 int ret;
6154
6155 vos_ssr_protect(__func__);
6156 ret = __hdd_set_mac_address(dev, addr);
6157 vos_ssr_unprotect(__func__);
6158
6159 return ret;
6160}
6161
Jeff Johnson295189b2012-06-20 16:38:30 -07006162tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
6163{
6164 int i;
6165 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6166 {
Abhishek Singheb183782014-02-06 13:37:21 +05306167 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006168 break;
6169 }
6170
6171 if( VOS_MAX_CONCURRENCY_PERSONA == i)
6172 return NULL;
6173
6174 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
6175 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
6176}
6177
6178void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
6179{
6180 int i;
6181 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6182 {
6183 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
6184 {
6185 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
6186 break;
6187 }
6188 }
6189 return;
6190}
6191
6192#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6193 static struct net_device_ops wlan_drv_ops = {
6194 .ndo_open = hdd_open,
6195 .ndo_stop = hdd_stop,
6196 .ndo_uninit = hdd_uninit,
6197 .ndo_start_xmit = hdd_hard_start_xmit,
6198 .ndo_tx_timeout = hdd_tx_timeout,
6199 .ndo_get_stats = hdd_stats,
6200 .ndo_do_ioctl = hdd_ioctl,
6201 .ndo_set_mac_address = hdd_set_mac_address,
6202 .ndo_select_queue = hdd_select_queue,
6203#ifdef WLAN_FEATURE_PACKET_FILTERING
6204#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
6205 .ndo_set_rx_mode = hdd_set_multicast_list,
6206#else
6207 .ndo_set_multicast_list = hdd_set_multicast_list,
6208#endif //LINUX_VERSION_CODE
6209#endif
6210 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006211 static struct net_device_ops wlan_mon_drv_ops = {
6212 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05306213 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07006214 .ndo_uninit = hdd_uninit,
6215 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6216 .ndo_tx_timeout = hdd_tx_timeout,
6217 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05306218 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07006219 .ndo_set_mac_address = hdd_set_mac_address,
6220 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306221
Jeff Johnson295189b2012-06-20 16:38:30 -07006222#endif
6223
6224void hdd_set_station_ops( struct net_device *pWlanDev )
6225{
6226#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006227 pWlanDev->netdev_ops = &wlan_drv_ops;
6228#else
6229 pWlanDev->open = hdd_open;
6230 pWlanDev->stop = hdd_stop;
6231 pWlanDev->uninit = hdd_uninit;
6232 pWlanDev->hard_start_xmit = NULL;
6233 pWlanDev->tx_timeout = hdd_tx_timeout;
6234 pWlanDev->get_stats = hdd_stats;
6235 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006236 pWlanDev->set_mac_address = hdd_set_mac_address;
6237#endif
6238}
6239
Katya Nigam1fd24402015-02-16 14:52:19 +05306240void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
6241{
6242 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6243 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
6244 #else
6245 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
6246 #endif
6247}
6248
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006249static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006250{
6251 struct net_device *pWlanDev = NULL;
6252 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006253 /*
6254 * cfg80211 initialization and registration....
6255 */
Anand N Sunkadae6fa552015-07-29 09:52:59 +05306256 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
6257#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
6258 NET_NAME_UNKNOWN,
6259#endif
6260 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07006261 if(pWlanDev != NULL)
6262 {
6263
6264 //Save the pointer to the net_device in the HDD adapter
6265 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6266
Jeff Johnson295189b2012-06-20 16:38:30 -07006267 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6268
6269 pAdapter->dev = pWlanDev;
6270 pAdapter->pHddCtx = pHddCtx;
6271 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306272 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006273
Rajeev79dbe4c2013-10-05 11:03:42 +05306274#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05306275 pAdapter->pBatchScanRsp = NULL;
6276 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006277 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006278 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306279 mutex_init(&pAdapter->hdd_batch_scan_lock);
6280#endif
6281
Jeff Johnson295189b2012-06-20 16:38:30 -07006282 pAdapter->isLinkUpSvcNeeded = FALSE;
6283 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6284 //Init the net_device structure
6285 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6286
6287 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6288 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6289 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6290 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6291
6292 hdd_set_station_ops( pAdapter->dev );
6293
6294 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006295 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6296 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6297 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006298 /* set pWlanDev's parent to underlying device */
6299 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006300
6301 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006302 }
6303
6304 return pAdapter;
6305}
6306
6307VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6308{
6309 struct net_device *pWlanDev = pAdapter->dev;
6310 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6311 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6312 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6313
6314 if( rtnl_lock_held )
6315 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006316 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006317 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6318 {
6319 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6320 return VOS_STATUS_E_FAILURE;
6321 }
6322 }
6323 if (register_netdevice(pWlanDev))
6324 {
6325 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6326 return VOS_STATUS_E_FAILURE;
6327 }
6328 }
6329 else
6330 {
6331 if(register_netdev(pWlanDev))
6332 {
6333 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6334 return VOS_STATUS_E_FAILURE;
6335 }
6336 }
6337 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6338
6339 return VOS_STATUS_SUCCESS;
6340}
6341
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006342static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006343{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006344 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006345
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006346 if (NULL == pAdapter)
6347 {
6348 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6349 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006350 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006351
6352 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6353 {
6354 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6355 return eHAL_STATUS_NOT_INITIALIZED;
6356 }
6357
6358 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6359
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006360#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006361 /* need to make sure all of our scheduled work has completed.
6362 * This callback is called from MC thread context, so it is safe to
6363 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006364 *
6365 * Even though this is called from MC thread context, if there is a faulty
6366 * work item in the system, that can hang this call forever. So flushing
6367 * this global work queue is not safe; and now we make sure that
6368 * individual work queues are stopped correctly. But the cancel work queue
6369 * is a GPL only API, so the proprietary version of the driver would still
6370 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006371 */
6372 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006373#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006374
6375 /* We can be blocked while waiting for scheduled work to be
6376 * flushed, and the adapter structure can potentially be freed, in
6377 * which case the magic will have been reset. So make sure the
6378 * magic is still good, and hence the adapter structure is still
6379 * valid, before signaling completion */
6380 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6381 {
6382 complete(&pAdapter->session_close_comp_var);
6383 }
6384
Jeff Johnson295189b2012-06-20 16:38:30 -07006385 return eHAL_STATUS_SUCCESS;
6386}
6387
6388VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6389{
6390 struct net_device *pWlanDev = pAdapter->dev;
6391 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6392 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6393 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6394 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306395 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006396
Nirav Shaha7b2c952015-06-22 23:51:42 +05306397 spin_lock_init( &pAdapter->sta_hash_lock);
6398 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
6399
Jeff Johnson295189b2012-06-20 16:38:30 -07006400 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006401 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006402 //Open a SME session for future operation
6403 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006404 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006405 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6406 {
6407 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006408 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006409 halStatus, halStatus );
6410 status = VOS_STATUS_E_FAILURE;
6411 goto error_sme_open;
6412 }
6413
6414 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306415 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006416 &pAdapter->session_open_comp_var,
6417 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306418 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006419 {
6420 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306421 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006422 status = VOS_STATUS_E_FAILURE;
6423 goto error_sme_open;
6424 }
6425
6426 // Register wireless extensions
6427 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6428 {
6429 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006430 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006431 halStatus, halStatus );
6432 status = VOS_STATUS_E_FAILURE;
6433 goto error_register_wext;
6434 }
Katya Nigam1fd24402015-02-16 14:52:19 +05306435
Jeff Johnson295189b2012-06-20 16:38:30 -07006436 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05306437 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6438 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6439 #else
6440 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6441 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006442
6443 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306444 hddLog(VOS_TRACE_LEVEL_INFO,
6445 "%s: Set HDD connState to eConnectionState_NotConnected",
6446 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006447 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6448
6449 //Set the default operation channel
6450 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6451
6452 /* Make the default Auth Type as OPEN*/
6453 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6454
6455 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6456 {
6457 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006458 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006459 status, status );
6460 goto error_init_txrx;
6461 }
6462
6463 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6464
6465 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6466 {
6467 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006468 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006469 status, status );
6470 goto error_wmm_init;
6471 }
6472
6473 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6474
6475 return VOS_STATUS_SUCCESS;
6476
6477error_wmm_init:
6478 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6479 hdd_deinit_tx_rx(pAdapter);
6480error_init_txrx:
6481 hdd_UnregisterWext(pWlanDev);
6482error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006483 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006484 {
6485 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006486 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
mukul sharma8ac8bb22015-06-11 17:14:55 +05306487 pAdapter->sessionId, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006488 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006489 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306490 unsigned long rc;
6491
Jeff Johnson295189b2012-06-20 16:38:30 -07006492 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306493 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006494 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006495 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306496 if (rc <= 0)
6497 hddLog(VOS_TRACE_LEVEL_ERROR,
6498 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006499 }
6500}
6501error_sme_open:
6502 return status;
6503}
6504
Jeff Johnson295189b2012-06-20 16:38:30 -07006505void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6506{
6507 hdd_cfg80211_state_t *cfgState;
6508
6509 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6510
6511 if( NULL != cfgState->buf )
6512 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306513 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006514 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6515 rc = wait_for_completion_interruptible_timeout(
6516 &pAdapter->tx_action_cnf_event,
6517 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306518 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006519 {
Deepthi Gowri14b72072015-08-25 13:14:58 +05306520 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6521 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6522 , __func__, rc);
6523
6524 // Inform tx status as FAILURE to upper layer and free cfgState->buf
6525 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006526 }
6527 }
6528 return;
6529}
Jeff Johnson295189b2012-06-20 16:38:30 -07006530
c_hpothu002231a2015-02-05 14:58:51 +05306531void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006532{
6533 ENTER();
6534 switch ( pAdapter->device_mode )
6535 {
Katya Nigam1fd24402015-02-16 14:52:19 +05306536 case WLAN_HDD_IBSS:
6537 {
6538 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6539 {
6540 hdd_ibss_deinit_tx_rx( pAdapter );
6541 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6542 }
6543 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006544 case WLAN_HDD_INFRA_STATION:
6545 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006546 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006547 {
6548 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6549 {
6550 hdd_deinit_tx_rx( pAdapter );
6551 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6552 }
6553
6554 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6555 {
6556 hdd_wmm_adapter_close( pAdapter );
6557 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6558 }
6559
Jeff Johnson295189b2012-06-20 16:38:30 -07006560 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006561 break;
6562 }
6563
6564 case WLAN_HDD_SOFTAP:
6565 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006566 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306567
6568 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6569 {
6570 hdd_wmm_adapter_close( pAdapter );
6571 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6572 }
6573
Jeff Johnson295189b2012-06-20 16:38:30 -07006574 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006575
c_hpothu002231a2015-02-05 14:58:51 +05306576 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006577 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006578 break;
6579 }
6580
6581 case WLAN_HDD_MONITOR:
6582 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006583 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6584 {
6585 hdd_deinit_tx_rx( pAdapter );
6586 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6587 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006588 break;
6589 }
6590
6591
6592 default:
6593 break;
6594 }
6595
6596 EXIT();
6597}
6598
6599void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6600{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006601 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306602
6603 ENTER();
6604 if (NULL == pAdapter)
6605 {
6606 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6607 "%s: HDD adapter is Null", __func__);
6608 return;
6609 }
6610
6611 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006612
Rajeev79dbe4c2013-10-05 11:03:42 +05306613#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306614 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6615 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006616 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306617 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6618 )
6619 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006620 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306621 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006622 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6623 {
6624 hdd_deinit_batch_scan(pAdapter);
6625 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306626 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006627 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306628#endif
6629
Jeff Johnson295189b2012-06-20 16:38:30 -07006630 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6631 if( rtnl_held )
6632 {
6633 unregister_netdevice(pWlanDev);
6634 }
6635 else
6636 {
6637 unregister_netdev(pWlanDev);
6638 }
6639 // note that the pAdapter is no longer valid at this point
6640 // since the memory has been reclaimed
6641 }
6642
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306643 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006644}
6645
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006646void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6647{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306648 VOS_STATUS status;
6649 hdd_adapter_t *pAdapter = NULL;
6650 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006651
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306652 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006653
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306654 /*loop through all adapters.*/
6655 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006656 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306657 pAdapter = pAdapterNode->pAdapter;
6658 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6659 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006660
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306661 { // we skip this registration for modes other than STA and P2P client modes.
6662 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6663 pAdapterNode = pNext;
6664 continue;
6665 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006666
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306667 //Apply Dynamic DTIM For P2P
6668 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6669 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6670 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6671 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6672 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6673 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6674 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6675 (eConnectionState_Associated ==
6676 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6677 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6678 {
6679 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006680
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306681 powerRequest.uIgnoreDTIM = 1;
6682 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6683
6684 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6685 {
6686 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6687 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6688 }
6689 else
6690 {
6691 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6692 }
6693
6694 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6695 * specified during Enter/Exit BMPS when LCD off*/
6696 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6697 NULL, eANI_BOOLEAN_FALSE);
6698 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6699 NULL, eANI_BOOLEAN_FALSE);
6700
6701 /* switch to the DTIM specified in cfg.ini */
6702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh8a829142015-10-27 13:45:17 +05306703 "Switch to DTIM %d Listen interval %d",
6704 powerRequest.uDTIMPeriod,
6705 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306706 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6707 break;
6708
6709 }
6710
6711 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6712 pAdapterNode = pNext;
6713 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006714}
6715
6716void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6717{
6718 /*Switch back to DTIM 1*/
6719 tSirSetPowerParamsReq powerRequest = { 0 };
6720
6721 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6722 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006723 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006724
6725 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6726 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6727 NULL, eANI_BOOLEAN_FALSE);
6728 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6729 NULL, eANI_BOOLEAN_FALSE);
6730
6731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6732 "Switch to DTIM%d",powerRequest.uListenInterval);
6733 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6734
6735}
6736
Jeff Johnson295189b2012-06-20 16:38:30 -07006737VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6738{
6739 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306740 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6741 {
6742 hddLog( LOGE, FL("Wlan Unload in progress"));
6743 return VOS_STATUS_E_PERM;
6744 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006745 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6746 {
6747 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6748 }
6749
6750 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6751 {
6752 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6753 }
6754
6755 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6756 {
6757 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6758 }
6759
6760 return status;
6761}
6762
6763VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6764{
6765 hdd_adapter_t *pAdapter = NULL;
6766 eHalStatus halStatus;
6767 VOS_STATUS status = VOS_STATUS_E_INVAL;
6768 v_BOOL_t disableBmps = FALSE;
6769 v_BOOL_t disableImps = FALSE;
6770
6771 switch(session_type)
6772 {
6773 case WLAN_HDD_INFRA_STATION:
6774 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006775 case WLAN_HDD_P2P_CLIENT:
6776 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006777 //Exit BMPS -> Is Sta/P2P Client is already connected
6778 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6779 if((NULL != pAdapter)&&
6780 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6781 {
6782 disableBmps = TRUE;
6783 }
6784
6785 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6786 if((NULL != pAdapter)&&
6787 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6788 {
6789 disableBmps = TRUE;
6790 }
6791
6792 //Exit both Bmps and Imps incase of Go/SAP Mode
6793 if((WLAN_HDD_SOFTAP == session_type) ||
6794 (WLAN_HDD_P2P_GO == session_type))
6795 {
6796 disableBmps = TRUE;
6797 disableImps = TRUE;
6798 }
6799
6800 if(TRUE == disableImps)
6801 {
6802 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6803 {
6804 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6805 }
6806 }
6807
6808 if(TRUE == disableBmps)
6809 {
6810 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6811 {
6812 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6813
6814 if(eHAL_STATUS_SUCCESS != halStatus)
6815 {
6816 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006817 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006818 VOS_ASSERT(0);
6819 return status;
6820 }
6821 }
6822
6823 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6824 {
6825 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6826
6827 if(eHAL_STATUS_SUCCESS != halStatus)
6828 {
6829 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006830 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006831 VOS_ASSERT(0);
6832 return status;
6833 }
6834 }
6835 }
6836
6837 if((TRUE == disableBmps) ||
6838 (TRUE == disableImps))
6839 {
6840 /* Now, get the chip into Full Power now */
6841 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6842 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6843 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6844
6845 if(halStatus != eHAL_STATUS_SUCCESS)
6846 {
6847 if(halStatus == eHAL_STATUS_PMC_PENDING)
6848 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306849 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006850 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306851 ret = wait_for_completion_interruptible_timeout(
6852 &pHddCtx->full_pwr_comp_var,
6853 msecs_to_jiffies(1000));
6854 if (ret <= 0)
6855 {
6856 hddLog(VOS_TRACE_LEVEL_ERROR,
6857 "%s: wait on full_pwr_comp_var failed %ld",
6858 __func__, ret);
6859 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006860 }
6861 else
6862 {
6863 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006864 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006865 VOS_ASSERT(0);
6866 return status;
6867 }
6868 }
6869
6870 status = VOS_STATUS_SUCCESS;
6871 }
6872
6873 break;
6874 }
6875 return status;
6876}
Hanumantha Reddy Pothula6adbe4c2015-09-03 21:25:16 +05306877
6878void hdd_monPostMsgCb(tANI_U32 *magic, struct completion *cmpVar)
6879{
6880 if (magic == NULL || cmpVar == NULL) {
6881 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6882 FL("invalid arguments %p %p"), magic, cmpVar);
6883 return;
6884 }
6885 if (*magic != MON_MODE_MSG_MAGIC) {
6886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6887 FL("maic: %x"), *magic);
6888 return;
6889 }
6890
6891 complete(cmpVar);
6892 return;
6893}
6894
Katya Nigame7b69a82015-04-28 15:24:06 +05306895void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
6896 {
6897 hdd_mon_ctx_t *pMonCtx = NULL;
6898 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
6899
6900 pMonCtx->state = 0;
6901 pMonCtx->ChannelNo = 1;
6902 pMonCtx->ChannelBW = 20;
Katya Nigamfefee602015-06-11 14:04:24 +05306903 pMonCtx->crcCheckEnabled = 1;
6904 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
6905 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05306906 pMonCtx->numOfMacFilters = 0;
6907 }
6908
Jeff Johnson295189b2012-06-20 16:38:30 -07006909
6910hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006911 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006912 tANI_U8 rtnl_held )
6913{
6914 hdd_adapter_t *pAdapter = NULL;
6915 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6916 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6917 VOS_STATUS exitbmpsStatus;
6918
Arif Hussain6d2a3322013-11-17 19:50:10 -08006919 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006920
Nirav Shah436658f2014-02-28 17:05:45 +05306921 if(macAddr == NULL)
6922 {
6923 /* Not received valid macAddr */
6924 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6925 "%s:Unable to add virtual intf: Not able to get"
6926 "valid mac address",__func__);
6927 return NULL;
6928 }
6929
Jeff Johnson295189b2012-06-20 16:38:30 -07006930 //Disable BMPS incase of Concurrency
6931 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6932
6933 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6934 {
6935 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306936 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006937 VOS_ASSERT(0);
6938 return NULL;
6939 }
6940
6941 switch(session_type)
6942 {
6943 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006944 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006945 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006946 {
6947 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6948
6949 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306950 {
6951 hddLog(VOS_TRACE_LEVEL_FATAL,
6952 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006953 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306954 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006955
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306956#ifdef FEATURE_WLAN_TDLS
6957 /* A Mutex Lock is introduced while changing/initializing the mode to
6958 * protect the concurrent access for the Adapters by TDLS module.
6959 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306960 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306961#endif
6962
Jeff Johnsone7245742012-09-05 17:12:55 -07006963 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6964 NL80211_IFTYPE_P2P_CLIENT:
6965 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006966
Jeff Johnson295189b2012-06-20 16:38:30 -07006967 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306968#ifdef FEATURE_WLAN_TDLS
6969 mutex_unlock(&pHddCtx->tdls_lock);
6970#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306971
Mahesh A Saptasagarcb5ccd52015-10-21 15:38:41 +05306972 hdd_initialize_adapter_common(pAdapter);
Sunil Dutt66485cb2013-12-19 19:05:03 +05306973 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006974 if( VOS_STATUS_SUCCESS != status )
6975 goto err_free_netdev;
6976
6977 status = hdd_register_interface( pAdapter, rtnl_held );
6978 if( VOS_STATUS_SUCCESS != status )
6979 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306980#ifdef FEATURE_WLAN_TDLS
6981 mutex_lock(&pHddCtx->tdls_lock);
6982#endif
c_hpothu002231a2015-02-05 14:58:51 +05306983 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306984#ifdef FEATURE_WLAN_TDLS
6985 mutex_unlock(&pHddCtx->tdls_lock);
6986#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006987 goto err_free_netdev;
6988 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306989
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306990 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkada7ab27f2015-06-03 14:33:24 +05306991 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306992
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306993#ifdef WLAN_NS_OFFLOAD
6994 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkada7ab27f2015-06-03 14:33:24 +05306995 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306996#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006997 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306998 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006999 netif_tx_disable(pAdapter->dev);
7000 //netif_tx_disable(pWlanDev);
7001 netif_carrier_off(pAdapter->dev);
7002
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307003 if (WLAN_HDD_P2P_CLIENT == session_type ||
7004 WLAN_HDD_P2P_DEVICE == session_type)
7005 {
7006 /* Initialize the work queue to defer the
7007 * back to back RoC request */
Anand N Sunkada7ab27f2015-06-03 14:33:24 +05307008 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307009 hdd_p2p_roc_work_queue);
7010 }
7011
Jeff Johnson295189b2012-06-20 16:38:30 -07007012 break;
7013 }
7014
Jeff Johnson295189b2012-06-20 16:38:30 -07007015 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007016 case WLAN_HDD_SOFTAP:
7017 {
7018 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
7019 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307020 {
7021 hddLog(VOS_TRACE_LEVEL_FATAL,
7022 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007023 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307024 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007025
Jeff Johnson295189b2012-06-20 16:38:30 -07007026 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
7027 NL80211_IFTYPE_AP:
7028 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007029 pAdapter->device_mode = session_type;
7030
Mahesh A Saptasagarcb5ccd52015-10-21 15:38:41 +05307031 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007032 status = hdd_init_ap_mode(pAdapter);
7033 if( VOS_STATUS_SUCCESS != status )
7034 goto err_free_netdev;
7035
Nirav Shaha7b2c952015-06-22 23:51:42 +05307036 status = hdd_sta_id_hash_attach(pAdapter);
7037 if (VOS_STATUS_SUCCESS != status)
7038 {
7039 hddLog(VOS_TRACE_LEVEL_FATAL,
7040 FL("failed to attach hash for session %d"), session_type);
7041 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
7042 goto err_free_netdev;
7043 }
7044
Jeff Johnson295189b2012-06-20 16:38:30 -07007045 status = hdd_register_hostapd( pAdapter, rtnl_held );
7046 if( VOS_STATUS_SUCCESS != status )
7047 {
c_hpothu002231a2015-02-05 14:58:51 +05307048 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07007049 goto err_free_netdev;
7050 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307051 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007052 netif_tx_disable(pAdapter->dev);
7053 netif_carrier_off(pAdapter->dev);
7054
7055 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307056
7057 if (WLAN_HDD_P2P_GO == session_type)
7058 {
7059 /* Initialize the work queue to
7060 * defer the back to back RoC request */
7061 INIT_DELAYED_WORK(&pAdapter->roc_work,
7062 hdd_p2p_roc_work_queue);
7063 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007064 break;
7065 }
7066 case WLAN_HDD_MONITOR:
7067 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007068 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7069 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307070 {
7071 hddLog(VOS_TRACE_LEVEL_FATAL,
7072 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007073 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307074 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007075
Katya Nigame7b69a82015-04-28 15:24:06 +05307076 // Register wireless extensions
7077 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
7078 {
7079 hddLog(VOS_TRACE_LEVEL_FATAL,
7080 "hdd_register_wext() failed with status code %08d [x%08x]",
7081 status, status );
7082 status = VOS_STATUS_E_FAILURE;
7083 }
7084
Jeff Johnson295189b2012-06-20 16:38:30 -07007085 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
7086 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007087#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
7088 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
7089#else
7090 pAdapter->dev->open = hdd_mon_open;
7091 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05307092 pAdapter->dev->stop = hdd_mon_stop;
7093 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07007094#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05307095 status = hdd_register_interface( pAdapter, rtnl_held );
7096 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagarcb5ccd52015-10-21 15:38:41 +05307097 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007098 hdd_init_tx_rx( pAdapter );
7099 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05307100 //Stop the Interface TX queue.
7101 netif_tx_disable(pAdapter->dev);
7102 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007103 }
7104 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007105 case WLAN_HDD_FTM:
7106 {
7107 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7108
7109 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307110 {
7111 hddLog(VOS_TRACE_LEVEL_FATAL,
7112 FL("failed to allocate adapter for session %d"), session_type);
7113 return NULL;
7114 }
7115
Jeff Johnson295189b2012-06-20 16:38:30 -07007116 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
7117 * message while loading driver in FTM mode. */
7118 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
7119 pAdapter->device_mode = session_type;
7120 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307121
Mahesh A Saptasagarcb5ccd52015-10-21 15:38:41 +05307122 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307123 hdd_init_tx_rx( pAdapter );
7124
7125 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307126 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307127 netif_tx_disable(pAdapter->dev);
7128 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007129 }
7130 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007131 default:
7132 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307133 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
7134 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007135 VOS_ASSERT(0);
7136 return NULL;
7137 }
7138 }
7139
Jeff Johnson295189b2012-06-20 16:38:30 -07007140 if( VOS_STATUS_SUCCESS == status )
7141 {
Mahesh A Saptasagarcb5ccd52015-10-21 15:38:41 +05307142 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -07007143 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
7144 if( NULL == pHddAdapterNode )
7145 {
7146 status = VOS_STATUS_E_NOMEM;
7147 }
7148 else
7149 {
7150 pHddAdapterNode->pAdapter = pAdapter;
7151 status = hdd_add_adapter_back ( pHddCtx,
7152 pHddAdapterNode );
7153 }
7154 }
7155
7156 if( VOS_STATUS_SUCCESS != status )
7157 {
7158 if( NULL != pAdapter )
7159 {
7160 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
7161 pAdapter = NULL;
7162 }
7163 if( NULL != pHddAdapterNode )
7164 {
7165 vos_mem_free( pHddAdapterNode );
7166 }
7167
7168 goto resume_bmps;
7169 }
7170
7171 if(VOS_STATUS_SUCCESS == status)
7172 {
7173 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
7174
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07007175 //Initialize the WoWL service
7176 if(!hdd_init_wowl(pAdapter))
7177 {
7178 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
7179 goto err_free_netdev;
7180 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007181 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007182 return pAdapter;
7183
7184err_free_netdev:
7185 free_netdev(pAdapter->dev);
7186 wlan_hdd_release_intf_addr( pHddCtx,
7187 pAdapter->macAddressCurrent.bytes );
7188
7189resume_bmps:
7190 //If bmps disabled enable it
7191 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
7192 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307193 if (pHddCtx->hdd_wlan_suspended)
7194 {
7195 hdd_set_pwrparams(pHddCtx);
7196 }
7197 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007198 }
7199 return NULL;
7200}
7201
7202VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7203 tANI_U8 rtnl_held )
7204{
7205 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
7206 VOS_STATUS status;
7207
7208 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
7209 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307210 {
7211 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
7212 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007213 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307214 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007215
7216 while ( pCurrent->pAdapter != pAdapter )
7217 {
7218 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
7219 if( VOS_STATUS_SUCCESS != status )
7220 break;
7221
7222 pCurrent = pNext;
7223 }
7224 pAdapterNode = pCurrent;
7225 if( VOS_STATUS_SUCCESS == status )
7226 {
7227 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7228 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307229
7230#ifdef FEATURE_WLAN_TDLS
7231
7232 /* A Mutex Lock is introduced while changing/initializing the mode to
7233 * protect the concurrent access for the Adapters by TDLS module.
7234 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307235 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307236#endif
7237
Jeff Johnson295189b2012-06-20 16:38:30 -07007238 hdd_remove_adapter( pHddCtx, pAdapterNode );
7239 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007240 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007241
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307242#ifdef FEATURE_WLAN_TDLS
7243 mutex_unlock(&pHddCtx->tdls_lock);
7244#endif
7245
Jeff Johnson295189b2012-06-20 16:38:30 -07007246
7247 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307248 if ((!vos_concurrent_open_sessions_running()) &&
7249 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7250 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007251 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307252 if (pHddCtx->hdd_wlan_suspended)
7253 {
7254 hdd_set_pwrparams(pHddCtx);
7255 }
7256 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007257 }
7258
7259 return VOS_STATUS_SUCCESS;
7260 }
7261
7262 return VOS_STATUS_E_FAILURE;
7263}
7264
7265VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7266{
7267 hdd_adapter_list_node_t *pHddAdapterNode;
7268 VOS_STATUS status;
7269
7270 ENTER();
7271
7272 do
7273 {
7274 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7275 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7276 {
7277 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7278 vos_mem_free( pHddAdapterNode );
7279 }
7280 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7281
7282 EXIT();
7283
7284 return VOS_STATUS_SUCCESS;
7285}
7286
7287void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7288{
7289 v_U8_t addIE[1] = {0};
7290
7291 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7292 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7293 eANI_BOOLEAN_FALSE) )
7294 {
7295 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007296 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007297 }
7298
7299 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7300 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7301 eANI_BOOLEAN_FALSE) )
7302 {
7303 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007304 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007305 }
7306
7307 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7308 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7309 eANI_BOOLEAN_FALSE) )
7310 {
7311 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007312 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007313 }
7314}
7315
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307316VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7317 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007318{
7319 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7320 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307321 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007322 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307323 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307324 long ret;
Nirav Shaha7b2c952015-06-22 23:51:42 +05307325 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007326
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307327 if (pHddCtx->isLogpInProgress) {
7328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7329 "%s:LOGP in Progress. Ignore!!!",__func__);
7330 return VOS_STATUS_E_FAILURE;
7331 }
7332
Jeff Johnson295189b2012-06-20 16:38:30 -07007333 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307334
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307335 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007336 switch(pAdapter->device_mode)
7337 {
Nirav Shah4aa57092015-11-05 16:27:27 +05307338 case WLAN_HDD_IBSS:
7339 if ( VOS_TRUE == bCloseSession )
7340 {
7341 status = hdd_sta_id_hash_detach(pAdapter);
7342 if (status != VOS_STATUS_SUCCESS)
7343 hddLog(VOS_TRACE_LEVEL_ERROR,
7344 FL("sta id hash detach failed"));
7345 }
7346
Jeff Johnson295189b2012-06-20 16:38:30 -07007347 case WLAN_HDD_INFRA_STATION:
7348 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007349 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307350 {
7351 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagarf3176be2015-07-02 16:17:20 +05307352#ifdef FEATURE_WLAN_TDLS
7353 mutex_lock(&pHddCtx->tdls_lock);
7354 wlan_hdd_tdls_exit(pAdapter, TRUE);
7355 mutex_unlock(&pHddCtx->tdls_lock);
7356#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307357 if( hdd_connIsConnected(pstation) ||
7358 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007359 {
7360 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7361 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7362 pAdapter->sessionId,
7363 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7364 else
7365 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7366 pAdapter->sessionId,
7367 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7368 //success implies disconnect command got queued up successfully
7369 if(halStatus == eHAL_STATUS_SUCCESS)
7370 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307371 ret = wait_for_completion_interruptible_timeout(
7372 &pAdapter->disconnect_comp_var,
7373 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7374 if (ret <= 0)
7375 {
7376 hddLog(VOS_TRACE_LEVEL_ERROR,
7377 "%s: wait on disconnect_comp_var failed %ld",
7378 __func__, ret);
7379 }
7380 }
7381 else
7382 {
7383 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7384 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007385 }
7386 memset(&wrqu, '\0', sizeof(wrqu));
7387 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7388 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7389 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7390 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307391 else if(pstation->conn_info.connState ==
7392 eConnectionState_Disconnecting)
7393 {
7394 ret = wait_for_completion_interruptible_timeout(
7395 &pAdapter->disconnect_comp_var,
7396 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7397 if (ret <= 0)
7398 {
7399 hddLog(VOS_TRACE_LEVEL_ERROR,
7400 FL("wait on disconnect_comp_var failed %ld"), ret);
7401 }
7402 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307403 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007404 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307405 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307406 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007407 }
Abhishek Singh6ac075e2015-09-21 10:01:34 +05307408 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
7409 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307410 {
7411 while (pAdapter->is_roc_inprogress)
7412 {
7413 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7414 "%s: ROC in progress for session %d!!!",
7415 __func__, pAdapter->sessionId);
7416 // waiting for ROC to expire
7417 msleep(500);
7418 /* In GO present case , if retry exceeds 3,
7419 it means something went wrong. */
7420 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7421 {
7422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7423 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307424 if (eHAL_STATUS_SUCCESS !=
7425 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7426 pAdapter->sessionId ))
7427 {
7428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7429 FL("Failed to Cancel Remain on Channel"));
7430 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307431 wait_for_completion_interruptible_timeout(
7432 &pAdapter->cancel_rem_on_chan_var,
7433 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7434 break;
7435 }
7436 }
Anand N Sunkada7ab27f2015-06-03 14:33:24 +05307437 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307438 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307439#ifdef WLAN_NS_OFFLOAD
Anand N Sunkada7ab27f2015-06-03 14:33:24 +05307440 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307441#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307442
Anand N Sunkada7ab27f2015-06-03 14:33:24 +05307443 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307444
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307445 /* It is possible that the caller of this function does not
7446 * wish to close the session
7447 */
7448 if (VOS_TRUE == bCloseSession &&
7449 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007450 {
7451 INIT_COMPLETION(pAdapter->session_close_comp_var);
7452 if (eHAL_STATUS_SUCCESS ==
mukul sharma8ac8bb22015-06-11 17:14:55 +05307453 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, VOS_FALSE,
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307454 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007455 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307456 unsigned long ret;
7457
Jeff Johnson295189b2012-06-20 16:38:30 -07007458 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307459 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307460 &pAdapter->session_close_comp_var,
7461 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307462 if ( 0 >= ret)
7463 {
7464 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307465 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307466 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007467 }
7468 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307469 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007470 break;
7471
7472 case WLAN_HDD_SOFTAP:
7473 case WLAN_HDD_P2P_GO:
Nirav Shah4aa57092015-11-05 16:27:27 +05307474 if ( VOS_TRUE == bCloseSession )
7475 {
7476 status = hdd_sta_id_hash_detach(pAdapter);
7477 if (status != VOS_STATUS_SUCCESS)
7478 hddLog(VOS_TRACE_LEVEL_ERROR,
7479 FL("sta id hash detach failed"));
7480 }
7481
Jeff Johnson295189b2012-06-20 16:38:30 -07007482 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307483 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7484 while (pAdapter->is_roc_inprogress) {
7485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7486 "%s: ROC in progress for session %d!!!",
7487 __func__, pAdapter->sessionId);
7488 msleep(500);
7489 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7491 "%s: ROC completion is not received.!!!", __func__);
7492 WLANSAP_CancelRemainOnChannel(
7493 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7494 wait_for_completion_interruptible_timeout(
7495 &pAdapter->cancel_rem_on_chan_var,
7496 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7497 break;
7498 }
7499 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307500
Anand N Sunkada7ab27f2015-06-03 14:33:24 +05307501 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307502 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007503 mutex_lock(&pHddCtx->sap_lock);
7504 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7505 {
7506 VOS_STATUS status;
7507 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7508
7509 //Stop Bss.
7510 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7511 if (VOS_IS_STATUS_SUCCESS(status))
7512 {
7513 hdd_hostapd_state_t *pHostapdState =
7514 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7515
7516 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7517
7518 if (!VOS_IS_STATUS_SUCCESS(status))
7519 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307520 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7521 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007522 }
7523 }
7524 else
7525 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007526 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007527 }
7528 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307529 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007530
7531 if (eHAL_STATUS_FAILURE ==
7532 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7533 0, NULL, eANI_BOOLEAN_FALSE))
7534 {
7535 hddLog(LOGE,
7536 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007537 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007538 }
7539
7540 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7541 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7542 eANI_BOOLEAN_FALSE) )
7543 {
7544 hddLog(LOGE,
7545 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7546 }
7547
7548 // Reset WNI_CFG_PROBE_RSP Flags
7549 wlan_hdd_reset_prob_rspies(pAdapter);
7550 kfree(pAdapter->sessionCtx.ap.beacon);
7551 pAdapter->sessionCtx.ap.beacon = NULL;
7552 }
7553 mutex_unlock(&pHddCtx->sap_lock);
7554 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007555
Jeff Johnson295189b2012-06-20 16:38:30 -07007556 case WLAN_HDD_MONITOR:
7557 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007558
Jeff Johnson295189b2012-06-20 16:38:30 -07007559 default:
7560 break;
7561 }
7562
7563 EXIT();
7564 return VOS_STATUS_SUCCESS;
7565}
7566
7567VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7568{
7569 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7570 VOS_STATUS status;
7571 hdd_adapter_t *pAdapter;
7572
7573 ENTER();
7574
7575 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7576
7577 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7578 {
7579 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007580
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307581 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007582
7583 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7584 pAdapterNode = pNext;
7585 }
7586
7587 EXIT();
7588
7589 return VOS_STATUS_SUCCESS;
7590}
7591
Rajeev Kumarf999e582014-01-09 17:33:29 -08007592
7593#ifdef FEATURE_WLAN_BATCH_SCAN
7594/**---------------------------------------------------------------------------
7595
7596 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7597 structures
7598
7599 \param - pAdapter Pointer to HDD adapter
7600
7601 \return - None
7602
7603 --------------------------------------------------------------------------*/
7604void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7605{
7606 tHddBatchScanRsp *pNode;
7607 tHddBatchScanRsp *pPrev;
7608
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307609 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007610 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307611 hddLog(VOS_TRACE_LEVEL_ERROR,
7612 "%s: Adapter context is Null", __func__);
7613 return;
7614 }
7615
7616 pNode = pAdapter->pBatchScanRsp;
7617 while (pNode)
7618 {
7619 pPrev = pNode;
7620 pNode = pNode->pNext;
7621 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007622 }
7623
7624 pAdapter->pBatchScanRsp = NULL;
7625 pAdapter->numScanList = 0;
7626 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7627 pAdapter->prev_batch_id = 0;
7628
7629 return;
7630}
7631#endif
7632
7633
Jeff Johnson295189b2012-06-20 16:38:30 -07007634VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7635{
7636 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7637 VOS_STATUS status;
7638 hdd_adapter_t *pAdapter;
7639
7640 ENTER();
7641
7642 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7643
7644 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7645 {
7646 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307647 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007648 netif_tx_disable(pAdapter->dev);
7649 netif_carrier_off(pAdapter->dev);
7650
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007651 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7652
Jeff Johnson295189b2012-06-20 16:38:30 -07007653 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307654
Katya Nigam1fd24402015-02-16 14:52:19 +05307655 if(pAdapter->device_mode == WLAN_HDD_IBSS )
7656 hdd_ibss_deinit_tx_rx(pAdapter);
7657
Nirav Shaha7b2c952015-06-22 23:51:42 +05307658 status = hdd_sta_id_hash_detach(pAdapter);
7659 if (status != VOS_STATUS_SUCCESS)
7660 hddLog(VOS_TRACE_LEVEL_ERROR,
7661 FL("sta id hash detach failed for session id %d"),
7662 pAdapter->sessionId);
7663
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307664 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7665
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307666 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7667 {
7668 hdd_wmm_adapter_close( pAdapter );
7669 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7670 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007671
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307672 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7673 {
7674 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7675 }
7676
Rajeev Kumarf999e582014-01-09 17:33:29 -08007677#ifdef FEATURE_WLAN_BATCH_SCAN
7678 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7679 {
7680 hdd_deinit_batch_scan(pAdapter);
7681 }
7682#endif
7683
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307684#ifdef FEATURE_WLAN_TDLS
7685 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307686 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307687 mutex_unlock(&pHddCtx->tdls_lock);
7688#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007689 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7690 pAdapterNode = pNext;
7691 }
7692
7693 EXIT();
7694
7695 return VOS_STATUS_SUCCESS;
7696}
7697
7698VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7699{
7700 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7701 VOS_STATUS status;
7702 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307703 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007704
7705 ENTER();
7706
7707 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7708
7709 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7710 {
7711 pAdapter = pAdapterNode->pAdapter;
7712
Kumar Anand82c009f2014-05-29 00:29:42 -07007713 hdd_wmm_init( pAdapter );
7714
Jeff Johnson295189b2012-06-20 16:38:30 -07007715 switch(pAdapter->device_mode)
7716 {
7717 case WLAN_HDD_INFRA_STATION:
7718 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007719 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307720
7721 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7722
Ratheesh S P718378d2015-09-09 19:50:40 +05307723 hdd_init_station_mode(pAdapter);
Mukul Sharma27362042015-08-12 22:06:37 +05307724
Jeff Johnson295189b2012-06-20 16:38:30 -07007725 /* Open the gates for HDD to receive Wext commands */
7726 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007727 pHddCtx->scan_info.mScanPending = FALSE;
7728 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007729
7730 //Trigger the initial scan
Mukul Sharmaad911df2015-08-06 23:55:49 +05307731 if (!pHddCtx->isLogpInProgress)
7732 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007733
7734 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307735 if (eConnectionState_Associated == connState ||
7736 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007737 {
7738 union iwreq_data wrqu;
7739 memset(&wrqu, '\0', sizeof(wrqu));
7740 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7741 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7742 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007743 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007744
Jeff Johnson295189b2012-06-20 16:38:30 -07007745 /* indicate disconnected event to nl80211 */
7746 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7747 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007748 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307749 else if (eConnectionState_Connecting == connState)
7750 {
7751 /*
7752 * Indicate connect failure to supplicant if we were in the
7753 * process of connecting
7754 */
7755 cfg80211_connect_result(pAdapter->dev, NULL,
7756 NULL, 0, NULL, 0,
7757 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7758 GFP_KERNEL);
7759 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007760 break;
7761
7762 case WLAN_HDD_SOFTAP:
7763 /* softAP can handle SSR */
7764 break;
7765
7766 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007767 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007768 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007769 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007770 break;
7771
7772 case WLAN_HDD_MONITOR:
7773 /* monitor interface start */
7774 break;
7775 default:
7776 break;
7777 }
7778
7779 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7780 pAdapterNode = pNext;
7781 }
7782
7783 EXIT();
7784
7785 return VOS_STATUS_SUCCESS;
7786}
7787
7788VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7789{
7790 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7791 hdd_adapter_t *pAdapter;
7792 VOS_STATUS status;
7793 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307794 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007795
7796 ENTER();
7797
7798 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7799
7800 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7801 {
7802 pAdapter = pAdapterNode->pAdapter;
7803
7804 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7805 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7806 {
7807 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7808 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7809
Abhishek Singhf4669da2014-05-26 15:07:49 +05307810 hddLog(VOS_TRACE_LEVEL_INFO,
7811 "%s: Set HDD connState to eConnectionState_NotConnected",
7812 __func__);
Ganesh Kondabattini72c2d142015-09-21 13:53:06 +05307813 spin_lock_bh(&pAdapter->lock_for_active_session);
7814 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
7815 {
7816 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7817 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007818 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini72c2d142015-09-21 13:53:06 +05307819 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07007820 init_completion(&pAdapter->disconnect_comp_var);
7821 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7822 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7823
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307824 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007825 &pAdapter->disconnect_comp_var,
7826 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307827 if (0 >= ret)
7828 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7829 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007830
7831 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7832 pHddCtx->isAmpAllowed = VOS_FALSE;
7833 sme_RoamConnect(pHddCtx->hHal,
7834 pAdapter->sessionId, &(pWextState->roamProfile),
7835 &roamId);
7836 }
7837
7838 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7839 pAdapterNode = pNext;
7840 }
7841
7842 EXIT();
7843
7844 return VOS_STATUS_SUCCESS;
7845}
7846
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007847void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7848{
7849 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7850 VOS_STATUS status;
7851 hdd_adapter_t *pAdapter;
7852 hdd_station_ctx_t *pHddStaCtx;
7853 hdd_ap_ctx_t *pHddApCtx;
7854 hdd_hostapd_state_t * pHostapdState;
7855 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7856 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7857 const char *p2pMode = "DEV";
7858 const char *ccMode = "Standalone";
7859 int n;
7860
7861 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7862 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7863 {
7864 pAdapter = pAdapterNode->pAdapter;
7865 switch (pAdapter->device_mode) {
7866 case WLAN_HDD_INFRA_STATION:
7867 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7868 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7869 staChannel = pHddStaCtx->conn_info.operationChannel;
7870 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7871 }
7872 break;
7873 case WLAN_HDD_P2P_CLIENT:
7874 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7875 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7876 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7877 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7878 p2pMode = "CLI";
7879 }
7880 break;
7881 case WLAN_HDD_P2P_GO:
7882 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7883 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7884 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7885 p2pChannel = pHddApCtx->operatingChannel;
7886 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7887 }
7888 p2pMode = "GO";
7889 break;
7890 case WLAN_HDD_SOFTAP:
7891 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7892 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7893 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7894 apChannel = pHddApCtx->operatingChannel;
7895 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7896 }
7897 break;
7898 default:
7899 break;
7900 }
7901 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7902 pAdapterNode = pNext;
7903 }
7904 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7905 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7906 }
7907 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7908 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7909 if (p2pChannel > 0) {
7910 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7911 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7912 }
7913 if (apChannel > 0) {
7914 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7915 apChannel, MAC_ADDR_ARRAY(apBssid));
7916 }
7917
7918 if (p2pChannel > 0 && apChannel > 0) {
7919 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7920 }
7921}
7922
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007923bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007924{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007925 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007926}
7927
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007928/* Once SSR is disabled then it cannot be set. */
7929void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007930{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007931 if (HDD_SSR_DISABLED == isSsrRequired)
7932 return;
7933
Jeff Johnson295189b2012-06-20 16:38:30 -07007934 isSsrRequired = value;
7935}
7936
Hema Aparna Medicharlae20feb02015-06-23 04:09:12 +05307937void hdd_set_pre_close( hdd_context_t *pHddCtx)
7938{
7939 sme_PreClose(pHddCtx->hHal);
7940}
7941
Jeff Johnson295189b2012-06-20 16:38:30 -07007942VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7943 hdd_adapter_list_node_t** ppAdapterNode)
7944{
7945 VOS_STATUS status;
Mukul Sharmafe6b5e82015-06-26 15:29:53 +05307946 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007947 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7948 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmafe6b5e82015-06-26 15:29:53 +05307949 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007950 return status;
7951}
7952
7953VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7954 hdd_adapter_list_node_t* pAdapterNode,
7955 hdd_adapter_list_node_t** pNextAdapterNode)
7956{
7957 VOS_STATUS status;
Mukul Sharmafe6b5e82015-06-26 15:29:53 +05307958 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007959 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7960 (hdd_list_node_t*) pAdapterNode,
7961 (hdd_list_node_t**)pNextAdapterNode );
7962
Mukul Sharmafe6b5e82015-06-26 15:29:53 +05307963 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007964 return status;
7965}
7966
7967VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7968 hdd_adapter_list_node_t* pAdapterNode)
7969{
7970 VOS_STATUS status;
Mukul Sharmafe6b5e82015-06-26 15:29:53 +05307971 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007972 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7973 &pAdapterNode->node );
Mukul Sharmafe6b5e82015-06-26 15:29:53 +05307974 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007975 return status;
7976}
7977
7978VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7979 hdd_adapter_list_node_t** ppAdapterNode)
7980{
7981 VOS_STATUS status;
Mukul Sharmafe6b5e82015-06-26 15:29:53 +05307982 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007983 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7984 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmafe6b5e82015-06-26 15:29:53 +05307985 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007986 return status;
7987}
7988
7989VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7990 hdd_adapter_list_node_t* pAdapterNode)
7991{
7992 VOS_STATUS status;
Mukul Sharmafe6b5e82015-06-26 15:29:53 +05307993 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007994 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7995 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmafe6b5e82015-06-26 15:29:53 +05307996 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007997 return status;
7998}
7999
8000VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
8001 hdd_adapter_list_node_t* pAdapterNode)
8002{
8003 VOS_STATUS status;
Mukul Sharmafe6b5e82015-06-26 15:29:53 +05308004 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008005 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
8006 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmafe6b5e82015-06-26 15:29:53 +05308007 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008008 return status;
8009}
8010
8011hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
8012 tSirMacAddr macAddr )
8013{
8014 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8015 hdd_adapter_t *pAdapter;
8016 VOS_STATUS status;
8017
8018 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8019
8020 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8021 {
8022 pAdapter = pAdapterNode->pAdapter;
8023
8024 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
8025 macAddr, sizeof(tSirMacAddr) ) )
8026 {
8027 return pAdapter;
8028 }
8029 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8030 pAdapterNode = pNext;
8031 }
8032
8033 return NULL;
8034
8035}
8036
8037hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
8038{
8039 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8040 hdd_adapter_t *pAdapter;
8041 VOS_STATUS status;
8042
8043 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8044
8045 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8046 {
8047 pAdapter = pAdapterNode->pAdapter;
8048
8049 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
8050 IFNAMSIZ ) )
8051 {
8052 return pAdapter;
8053 }
8054 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8055 pAdapterNode = pNext;
8056 }
8057
8058 return NULL;
8059
8060}
8061
Ganesh Kondabattini64fdefa2015-09-21 13:52:09 +05308062hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
8063 tANI_U32 sme_session_id )
8064{
8065 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8066 hdd_adapter_t *pAdapter;
8067 VOS_STATUS vos_status;
8068
8069
8070 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
8071
8072 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
8073 {
8074 pAdapter = pAdapterNode->pAdapter;
8075
8076 if (pAdapter->sessionId == sme_session_id)
8077 return pAdapter;
8078
8079 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
8080 pAdapterNode = pNext;
8081 }
8082
8083 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8084 "%s: sme_session_id %d does not exist with host",
8085 __func__, sme_session_id);
8086
8087 return NULL;
8088}
8089
Jeff Johnson295189b2012-06-20 16:38:30 -07008090hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
8091{
8092 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8093 hdd_adapter_t *pAdapter;
8094 VOS_STATUS status;
8095
8096 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8097
8098 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8099 {
8100 pAdapter = pAdapterNode->pAdapter;
8101
8102 if( pAdapter && (mode == pAdapter->device_mode) )
8103 {
8104 return pAdapter;
8105 }
8106 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8107 pAdapterNode = pNext;
8108 }
8109
8110 return NULL;
8111
8112}
8113
8114//Remove this function later
8115hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
8116{
8117 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8118 hdd_adapter_t *pAdapter;
8119 VOS_STATUS status;
8120
8121 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8122
8123 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8124 {
8125 pAdapter = pAdapterNode->pAdapter;
8126
8127 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
8128 {
8129 return pAdapter;
8130 }
8131
8132 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8133 pAdapterNode = pNext;
8134 }
8135
8136 return NULL;
8137
8138}
8139
Jeff Johnson295189b2012-06-20 16:38:30 -07008140/**---------------------------------------------------------------------------
8141
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308142 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008143
8144 This API returns the operating channel of the requested device mode
8145
8146 \param - pHddCtx - Pointer to the HDD context.
8147 - mode - Device mode for which operating channel is required
8148 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
8149 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
8150 \return - channel number. "0" id the requested device is not found OR it is not connected.
8151 --------------------------------------------------------------------------*/
8152v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
8153{
8154 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8155 VOS_STATUS status;
8156 hdd_adapter_t *pAdapter;
8157 v_U8_t operatingChannel = 0;
8158
8159 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8160
8161 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8162 {
8163 pAdapter = pAdapterNode->pAdapter;
8164
8165 if( mode == pAdapter->device_mode )
8166 {
8167 switch(pAdapter->device_mode)
8168 {
8169 case WLAN_HDD_INFRA_STATION:
8170 case WLAN_HDD_P2P_CLIENT:
8171 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
8172 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
8173 break;
8174 case WLAN_HDD_SOFTAP:
8175 case WLAN_HDD_P2P_GO:
8176 /*softap connection info */
8177 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8178 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
8179 break;
8180 default:
8181 break;
8182 }
8183
8184 break; //Found the device of interest. break the loop
8185 }
8186
8187 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8188 pAdapterNode = pNext;
8189 }
8190 return operatingChannel;
8191}
8192
8193#ifdef WLAN_FEATURE_PACKET_FILTERING
8194/**---------------------------------------------------------------------------
8195
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308196 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008197
8198 This used to set the multicast address list.
8199
8200 \param - dev - Pointer to the WLAN device.
8201 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308202 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07008203
8204 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308205static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008206{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308207 hdd_adapter_t *pAdapter;
8208 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008209 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308210 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008211 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308212
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308213 ENTER();
8214
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308215 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308216 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008217 {
8218 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308219 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008220 return;
8221 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308222 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8223 ret = wlan_hdd_validate_context(pHddCtx);
8224 if (0 != ret)
8225 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308226 return;
8227 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008228 if (dev->flags & IFF_ALLMULTI)
8229 {
8230 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008231 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308232 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008233 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308234 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008235 {
8236 mc_count = netdev_mc_count(dev);
8237 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008238 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07008239 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
8240 {
8241 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008242 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308243 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008244 return;
8245 }
8246
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308247 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07008248
8249 netdev_for_each_mc_addr(ha, dev) {
8250 if (i == mc_count)
8251 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308252 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
8253 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008254 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308255 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308256 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07008257 i++;
8258 }
8259 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308260
8261 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008262 return;
8263}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308264
8265static void hdd_set_multicast_list(struct net_device *dev)
8266{
8267 vos_ssr_protect(__func__);
8268 __hdd_set_multicast_list(dev);
8269 vos_ssr_unprotect(__func__);
8270}
Jeff Johnson295189b2012-06-20 16:38:30 -07008271#endif
8272
8273/**---------------------------------------------------------------------------
8274
8275 \brief hdd_select_queue() -
8276
8277 This function is registered with the Linux OS for network
8278 core to decide which queue to use first.
8279
8280 \param - dev - Pointer to the WLAN device.
8281 - skb - Pointer to OS packet (sk_buff).
8282 \return - ac, Queue Index/access category corresponding to UP in IP header
8283
8284 --------------------------------------------------------------------------*/
8285v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkad3e9fe782015-07-29 09:56:45 +05308286 struct sk_buff *skb
8287#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
8288 , void *accel_priv
8289#endif
8290#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8291 , select_queue_fallback_t fallback
8292#endif
8293)
Jeff Johnson295189b2012-06-20 16:38:30 -07008294{
8295 return hdd_wmm_select_queue(dev, skb);
8296}
8297
8298
8299/**---------------------------------------------------------------------------
8300
8301 \brief hdd_wlan_initial_scan() -
8302
8303 This function triggers the initial scan
8304
8305 \param - pAdapter - Pointer to the HDD adapter.
8306
8307 --------------------------------------------------------------------------*/
8308void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8309{
8310 tCsrScanRequest scanReq;
8311 tCsrChannelInfo channelInfo;
8312 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008313 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008314 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8315
8316 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8317 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8318 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8319
8320 if(sme_Is11dSupported(pHddCtx->hHal))
8321 {
8322 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8323 if ( HAL_STATUS_SUCCESS( halStatus ) )
8324 {
8325 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8326 if( !scanReq.ChannelInfo.ChannelList )
8327 {
8328 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8329 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008330 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008331 return;
8332 }
8333 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8334 channelInfo.numOfChannels);
8335 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8336 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008337 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008338 }
8339
8340 scanReq.scanType = eSIR_PASSIVE_SCAN;
8341 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8342 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8343 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8344 }
8345 else
8346 {
8347 scanReq.scanType = eSIR_ACTIVE_SCAN;
8348 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8349 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8350 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8351 }
8352
8353 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8354 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8355 {
8356 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8357 __func__, halStatus );
8358 }
8359
8360 if(sme_Is11dSupported(pHddCtx->hHal))
8361 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8362}
8363
mukul sharma8ac8bb22015-06-11 17:14:55 +05308364void hdd_purge_cmd_list_all_adapters( hdd_context_t *pHddCtx )
8365{
8366 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8367 VOS_STATUS status;
8368 hdd_adapter_t *pAdapter;
8369
8370 ENTER();
8371
8372 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8373
8374 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8375 {
8376 pAdapter = pAdapterNode->pAdapter;
8377
8378 status = sme_PurgeCmdList(pHddCtx->hHal, pAdapter->sessionId);
8379 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8380 pAdapterNode = pNext;
8381 }
8382
8383 EXIT();
8384}
Jeff Johnson295189b2012-06-20 16:38:30 -07008385/**---------------------------------------------------------------------------
8386
8387 \brief hdd_full_power_callback() - HDD full power callback function
8388
8389 This is the function invoked by SME to inform the result of a full power
8390 request issued by HDD
8391
8392 \param - callbackcontext - Pointer to cookie
8393 \param - status - result of request
8394
8395 \return - None
8396
8397 --------------------------------------------------------------------------*/
8398static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8399{
Jeff Johnson72a40512013-12-19 10:14:15 -08008400 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008401
8402 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308403 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008404
8405 if (NULL == callbackContext)
8406 {
8407 hddLog(VOS_TRACE_LEVEL_ERROR,
8408 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008409 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008410 return;
8411 }
8412
Jeff Johnson72a40512013-12-19 10:14:15 -08008413 /* there is a race condition that exists between this callback
8414 function and the caller since the caller could time out either
8415 before or while this code is executing. we use a spinlock to
8416 serialize these actions */
8417 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008418
8419 if (POWER_CONTEXT_MAGIC != pContext->magic)
8420 {
8421 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008422 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008423 hddLog(VOS_TRACE_LEVEL_WARN,
8424 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008425 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008426 return;
8427 }
8428
Jeff Johnson72a40512013-12-19 10:14:15 -08008429 /* context is valid so caller is still waiting */
8430
8431 /* paranoia: invalidate the magic */
8432 pContext->magic = 0;
8433
8434 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008435 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008436
8437 /* serialization is complete */
8438 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008439}
8440
Katya Nigamf0511f62015-05-05 16:40:57 +05308441void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
8442{
8443 pMonCtx->typeSubtypeBitmap = 0;
8444 if( type%10 ) /* Management Packets */
8445 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
8446 type/=10;
8447 if( type%10 ) /* Control Packets */
8448 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
8449 type/=10;
8450 if( type%10 ) /* Data Packets */
8451 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
8452}
8453
Hanumantha Reddy Pothula6adbe4c2015-09-03 21:25:16 +05308454VOS_STATUS wlan_hdd_mon_postMsg(tANI_U32 *magic, struct completion *cmpVar,
8455 hdd_mon_ctx_t *pMonCtx , void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +05308456{
8457 vos_msg_t monMsg;
Hanumantha Reddy Pothula6adbe4c2015-09-03 21:25:16 +05308458 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +05308459
Hanumantha Reddy Pothula6adbe4c2015-09-03 21:25:16 +05308460 if (MON_MODE_START == pMonCtx->state)
8461 monMsg.type = WDA_MON_START_REQ;
8462 else if (MON_MODE_STOP == pMonCtx->state)
8463 monMsg.type = WDA_MON_STOP_REQ;
8464 else {
8465 hddLog(VOS_TRACE_LEVEL_ERROR,
8466 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +05308467 return VOS_STATUS_E_FAILURE;
8468 }
8469
Hanumantha Reddy Pothula6adbe4c2015-09-03 21:25:16 +05308470 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
8471 if (pMonModeReq == NULL) {
8472 hddLog(VOS_TRACE_LEVEL_ERROR,
8473 FL("fail to allocate memory for monitor mode req"));
8474 return VOS_STATUS_E_FAILURE;
8475 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308476
Hanumantha Reddy Pothula6adbe4c2015-09-03 21:25:16 +05308477 pMonModeReq->magic = magic;
8478 pMonModeReq->cmpVar = cmpVar;
8479 pMonModeReq->data = pMonCtx;
8480 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +05308481
Katya Nigamf0511f62015-05-05 16:40:57 +05308482 monMsg.reserved = 0;
Hanumantha Reddy Pothula6adbe4c2015-09-03 21:25:16 +05308483 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +05308484 monMsg.bodyval = 0;
8485
8486 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8487 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8488 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula6adbe4c2015-09-03 21:25:16 +05308489 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +05308490 }
Hanumantha Reddy Pothula6adbe4c2015-09-03 21:25:16 +05308491 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +05308492}
8493
Katya Nigame7b69a82015-04-28 15:24:06 +05308494void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
8495{
8496 VOS_STATUS vosStatus;
8497 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula6adbe4c2015-09-03 21:25:16 +05308498 long ret;
8499 hdd_mon_ctx_t *pMonCtx = NULL;
8500 v_U32_t magic;
8501 struct completion cmpVar;
Hanumantha Reddy Pothula8d66abf2015-09-08 14:59:26 +05308502
Katya Nigame7b69a82015-04-28 15:24:06 +05308503 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
8504 if(pAdapter == NULL || pVosContext == NULL)
8505 {
8506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
8507 return ;
8508 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308509
Hanumantha Reddy Pothula6adbe4c2015-09-03 21:25:16 +05308510 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
8511 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
8512 pMonCtx->state = MON_MODE_STOP;
8513 magic = MON_MODE_MSG_MAGIC;
8514 init_completion(&cmpVar);
8515 if (VOS_STATUS_SUCCESS !=
8516 wlan_hdd_mon_postMsg(&magic, &cmpVar,
8517 pMonCtx, hdd_monPostMsgCb)) {
8518 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8519 FL("failed to post MON MODE REQ"));
8520 pMonCtx->state = MON_MODE_START;
8521 magic = 0;
8522 return;
8523 }
8524 ret = wait_for_completion_timeout(&cmpVar, MON_MODE_MSG_TIMEOUT);
8525 magic = 0;
8526 if (ret <= 0 ) {
8527 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8528 FL("timeout on monitor mode completion %ld"), ret);
8529 }
8530 }
8531
Katya Nigame7b69a82015-04-28 15:24:06 +05308532 hdd_UnregisterWext(pAdapter->dev);
8533
8534 vos_mon_stop( pVosContext );
8535
8536 vosStatus = vos_sched_close( pVosContext );
8537 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8538 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8539 "%s: Failed to close VOSS Scheduler",__func__);
8540 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8541 }
8542
8543 vosStatus = vos_nv_close();
8544 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8545 {
8546 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8547 "%s: Failed to close NV", __func__);
8548 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8549 }
8550
8551 vos_close(pVosContext);
8552
8553 #ifdef WLAN_KD_READY_NOTIFIER
8554 nl_srv_exit(pHddCtx->ptt_pid);
8555 #else
8556 nl_srv_exit();
8557 #endif
8558
Katya Nigame7b69a82015-04-28 15:24:06 +05308559 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +05308560}
Agrawal Ashishd4232f02015-11-26 20:20:58 +05308561/**
8562 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
8563 * @ wiphy: the wiphy to validate against
8564 *
8565 * Return: void
8566 */
8567void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
8568{
8569 int i =0;
8570 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8571 {
8572 if (NULL != wiphy->bands[i] &&
8573 (NULL != wiphy->bands[i]->channels))
8574 {
8575 vos_mem_free(wiphy->bands[i]->channels);
8576 wiphy->bands[i]->channels = NULL;
8577 }
8578 }
8579}
Jeff Johnson295189b2012-06-20 16:38:30 -07008580/**---------------------------------------------------------------------------
8581
8582 \brief hdd_wlan_exit() - HDD WLAN exit function
8583
8584 This is the driver exit point (invoked during rmmod)
8585
8586 \param - pHddCtx - Pointer to the HDD Context
8587
8588 \return - None
8589
8590 --------------------------------------------------------------------------*/
8591void hdd_wlan_exit(hdd_context_t *pHddCtx)
8592{
8593 eHalStatus halStatus;
8594 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8595 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308596 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008597 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008598 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008599 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308600 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008601
8602 ENTER();
8603
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308604
Katya Nigame7b69a82015-04-28 15:24:06 +05308605 if (VOS_MONITOR_MODE == hdd_get_conparam())
8606 {
8607 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
8608 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothula8d66abf2015-09-08 14:59:26 +05308609 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +05308610 }
8611 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08008612 {
8613 // Unloading, restart logic is no more required.
8614 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008615
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308616#ifdef FEATURE_WLAN_TDLS
8617 /* At the time of driver unloading; if tdls connection is present;
8618 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8619 * wlan_hdd_tdls_find_peer always checks for valid context;
8620 * as load/unload in progress there can be a race condition.
8621 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8622 * when tdls state is enabled.
8623 * As soon as driver set load/unload flag; tdls flag also needs
8624 * to be disabled so that hdd_rx_packet_cbk won't call
8625 * wlan_hdd_tdls_find_peer.
8626 */
8627 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8628#endif
8629
c_hpothu5ab05e92014-06-13 17:34:05 +05308630 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8631 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008632 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308633 pAdapter = pAdapterNode->pAdapter;
8634 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008635 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308636 /* Disable TX on the interface, after this hard_start_xmit() will
8637 * not be called on that interface
8638 */
8639 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8640 netif_tx_disable(pAdapter->dev);
8641
8642 /* Mark the interface status as "down" for outside world */
8643 netif_carrier_off(pAdapter->dev);
8644
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308645 /* DeInit the adapter. This ensures that all data packets
8646 * are freed.
8647 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308648#ifdef FEATURE_WLAN_TDLS
8649 mutex_lock(&pHddCtx->tdls_lock);
8650#endif
c_hpothu002231a2015-02-05 14:58:51 +05308651 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308652#ifdef FEATURE_WLAN_TDLS
8653 mutex_unlock(&pHddCtx->tdls_lock);
8654#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308655
c_hpothu5ab05e92014-06-13 17:34:05 +05308656 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8657 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8658 {
8659 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8660 hdd_UnregisterWext(pAdapter->dev);
8661 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308662
Jeff Johnson295189b2012-06-20 16:38:30 -07008663 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308664 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8665 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008666 }
mukul sharma8ac8bb22015-06-11 17:14:55 +05308667
8668 //Purge all sme cmd's for all interface
8669 hdd_purge_cmd_list_all_adapters(pHddCtx);
8670
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308671 // Cancel any outstanding scan requests. We are about to close all
8672 // of our adapters, but an adapter structure is what SME passes back
8673 // to our callback function. Hence if there are any outstanding scan
8674 // requests then there is a race condition between when the adapter
8675 // is closed and when the callback is invoked.We try to resolve that
8676 // race condition here by canceling any outstanding scans before we
8677 // close the adapters.
8678 // Note that the scans may be cancelled in an asynchronous manner,
8679 // so ideally there needs to be some kind of synchronization. Rather
8680 // than introduce a new synchronization here, we will utilize the
8681 // fact that we are about to Request Full Power, and since that is
8682 // synchronized, the expectation is that by the time Request Full
8683 // Power has completed all scans will be cancelled.
8684 if (pHddCtx->scan_info.mScanPending)
8685 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308686 if(NULL != pAdapter)
8687 {
8688 hddLog(VOS_TRACE_LEVEL_INFO,
8689 FL("abort scan mode: %d sessionId: %d"),
8690 pAdapter->device_mode,
8691 pAdapter->sessionId);
8692 }
8693 hdd_abort_mac_scan(pHddCtx,
8694 pHddCtx->scan_info.sessionId,
8695 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308696 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008697 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308698 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008699 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308700 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308701 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8702 {
8703 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8705 "%s: in middle of FTM START", __func__);
8706 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8707 msecs_to_jiffies(20000));
8708 if(!lrc)
8709 {
8710 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8711 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8712 }
8713 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008714 wlan_hdd_ftm_close(pHddCtx);
8715 goto free_hdd_ctx;
8716 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308717
Jeff Johnson295189b2012-06-20 16:38:30 -07008718 /* DeRegister with platform driver as client for Suspend/Resume */
8719 vosStatus = hddDeregisterPmOps(pHddCtx);
8720 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8721 {
8722 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8723 VOS_ASSERT(0);
8724 }
8725
8726 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8727 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8728 {
8729 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8730 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008731
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008732 //Stop the traffic monitor timer
8733 if ( VOS_TIMER_STATE_RUNNING ==
8734 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8735 {
8736 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8737 }
8738
8739 // Destroy the traffic monitor timer
8740 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8741 &pHddCtx->tx_rx_trafficTmr)))
8742 {
8743 hddLog(VOS_TRACE_LEVEL_ERROR,
8744 "%s: Cannot deallocate Traffic monitor timer", __func__);
8745 }
8746
Jeff Johnson295189b2012-06-20 16:38:30 -07008747 //Disable IMPS/BMPS as we do not want the device to enter any power
8748 //save mode during shutdown
8749 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8750 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8751 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8752
8753 //Ensure that device is in full power as we will touch H/W during vos_Stop
8754 init_completion(&powerContext.completion);
8755 powerContext.magic = POWER_CONTEXT_MAGIC;
8756
8757 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8758 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8759
8760 if (eHAL_STATUS_SUCCESS != halStatus)
8761 {
8762 if (eHAL_STATUS_PMC_PENDING == halStatus)
8763 {
8764 /* request was sent -- wait for the response */
8765 lrc = wait_for_completion_interruptible_timeout(
8766 &powerContext.completion,
8767 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008768 if (lrc <= 0)
8769 {
8770 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008771 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008772 }
8773 }
8774 else
8775 {
8776 hddLog(VOS_TRACE_LEVEL_ERROR,
8777 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008778 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008779 /* continue -- need to clean up as much as possible */
8780 }
8781 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +05308782 if ((eHAL_STATUS_SUCCESS == halStatus) ||
8783 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
8784 {
8785 /* This will issue a dump command which will clean up
8786 BTQM queues and unblock MC thread */
8787 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
8788 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008789
Jeff Johnson72a40512013-12-19 10:14:15 -08008790 /* either we never sent a request, we sent a request and received a
8791 response or we sent a request and timed out. if we never sent a
8792 request or if we sent a request and got a response, we want to
8793 clear the magic out of paranoia. if we timed out there is a
8794 race condition such that the callback function could be
8795 executing at the same time we are. of primary concern is if the
8796 callback function had already verified the "magic" but had not
8797 yet set the completion variable when a timeout occurred. we
8798 serialize these activities by invalidating the magic while
8799 holding a shared spinlock which will cause us to block if the
8800 callback is currently executing */
8801 spin_lock(&hdd_context_lock);
8802 powerContext.magic = 0;
8803 spin_unlock(&hdd_context_lock);
8804
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +05308805 /* If Device is shutdown, no point for SME to wait for responses
8806 from device. Pre Close SME */
8807 if(wcnss_device_is_shutdown())
8808 {
8809 sme_PreClose(pHddCtx->hHal);
8810 }
Yue Ma0d4891e2013-08-06 17:01:45 -07008811 hdd_debugfs_exit(pHddCtx);
8812
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308813#ifdef WLAN_NS_OFFLOAD
Ratheesh S P8671ef02015-08-15 14:08:20 +05308814 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308815 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8816#endif
Ratheesh S P8671ef02015-08-15 14:08:20 +05308817 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308818 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8819
Jeff Johnson295189b2012-06-20 16:38:30 -07008820 // Unregister the Net Device Notifier
8821 unregister_netdevice_notifier(&hdd_netdev_notifier);
8822
Jeff Johnson295189b2012-06-20 16:38:30 -07008823 hdd_stop_all_adapters( pHddCtx );
8824
Jeff Johnson295189b2012-06-20 16:38:30 -07008825#ifdef WLAN_BTAMP_FEATURE
8826 vosStatus = WLANBAP_Stop(pVosContext);
8827 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8828 {
8829 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8830 "%s: Failed to stop BAP",__func__);
8831 }
8832#endif //WLAN_BTAMP_FEATURE
8833
8834 //Stop all the modules
8835 vosStatus = vos_stop( pVosContext );
8836 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8837 {
8838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8839 "%s: Failed to stop VOSS",__func__);
8840 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothulaa61d2452015-09-22 14:05:18 +05308841 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07008842 }
8843
Jeff Johnson295189b2012-06-20 16:38:30 -07008844 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008845 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008846
8847 //Close the scheduler before calling vos_close to make sure no thread is
8848 // scheduled after the each module close is called i.e after all the data
8849 // structures are freed.
8850 vosStatus = vos_sched_close( pVosContext );
8851 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8852 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8853 "%s: Failed to close VOSS Scheduler",__func__);
8854 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8855 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008856#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8857 /* Destroy the wake lock */
Sushant Kaushikd8a351d2015-05-05 17:44:40 +05308858 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008859#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008860 /* Destroy the wake lock */
Sushant Kaushikd8a351d2015-05-05 17:44:40 +05308861 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008862
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308863#ifdef CONFIG_ENABLE_LINUX_REG
8864 vosStatus = vos_nv_close();
8865 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8866 {
8867 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8868 "%s: Failed to close NV", __func__);
8869 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8870 }
8871#endif
8872
Jeff Johnson295189b2012-06-20 16:38:30 -07008873 //Close VOSS
8874 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8875 vos_close(pVosContext);
8876
Jeff Johnson295189b2012-06-20 16:38:30 -07008877 //Close Watchdog
8878 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8879 vos_watchdog_close(pVosContext);
8880
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308881 //Clean up HDD Nlink Service
8882 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308883
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308884#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308885 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308886 {
8887 wlan_logging_sock_deactivate_svc();
8888 }
8889#endif
8890
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308891#ifdef WLAN_KD_READY_NOTIFIER
8892 nl_srv_exit(pHddCtx->ptt_pid);
8893#else
8894 nl_srv_exit();
8895#endif /* WLAN_KD_READY_NOTIFIER */
8896
8897
Jeff Johnson295189b2012-06-20 16:38:30 -07008898 hdd_close_all_adapters( pHddCtx );
8899
Hanumantha Reddy Pothulaad0a6d52015-08-10 17:21:20 +05308900free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -07008901 /* free the power on lock from platform driver */
8902 if (free_riva_power_on_lock("wlan"))
8903 {
8904 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8905 __func__);
8906 }
8907
c_hpothu78c7b602014-05-17 17:35:49 +05308908 //Free up dynamically allocated members inside HDD Adapter
8909 if (pHddCtx->cfg_ini)
8910 {
8911 kfree(pHddCtx->cfg_ini);
8912 pHddCtx->cfg_ini= NULL;
8913 }
8914
Leo Changf04ddad2013-09-18 13:46:38 -07008915 /* FTM mode, WIPHY did not registered
8916 If un-register here, system crash will happen */
8917 if (VOS_FTM_MODE != hdd_get_conparam())
8918 {
8919 wiphy_unregister(wiphy) ;
Agrawal Ashishd4232f02015-11-26 20:20:58 +05308920 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -07008921 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008922 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008923 if (hdd_is_ssr_required())
8924 {
8925 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008926 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008927 msleep(5000);
8928 }
8929 hdd_set_ssr_required (VOS_FALSE);
8930}
8931
8932
8933/**---------------------------------------------------------------------------
8934
8935 \brief hdd_update_config_from_nv() - Function to update the contents of
8936 the running configuration with parameters taken from NV storage
8937
8938 \param - pHddCtx - Pointer to the HDD global context
8939
8940 \return - VOS_STATUS_SUCCESS if successful
8941
8942 --------------------------------------------------------------------------*/
8943static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8944{
Jeff Johnson295189b2012-06-20 16:38:30 -07008945 v_BOOL_t itemIsValid = VOS_FALSE;
8946 VOS_STATUS status;
8947 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8948 v_U8_t macLoop;
8949
8950 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8951 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8952 if(status != VOS_STATUS_SUCCESS)
8953 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008954 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008955 return VOS_STATUS_E_FAILURE;
8956 }
8957
8958 if (itemIsValid == VOS_TRUE)
8959 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008960 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008961 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8962 VOS_MAX_CONCURRENCY_PERSONA);
8963 if(status != VOS_STATUS_SUCCESS)
8964 {
8965 /* Get MAC from NV fail, not update CFG info
8966 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008967 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008968 return VOS_STATUS_E_FAILURE;
8969 }
8970
8971 /* If first MAC is not valid, treat all others are not valid
8972 * Then all MACs will be got from ini file */
8973 if(vos_is_macaddr_zero(&macFromNV[0]))
8974 {
8975 /* MAC address in NV file is not configured yet */
8976 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8977 return VOS_STATUS_E_INVAL;
8978 }
8979
8980 /* Get MAC address from NV, update CFG info */
8981 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8982 {
8983 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8984 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308985 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008986 /* This MAC is not valid, skip it
8987 * This MAC will be got from ini file */
8988 }
8989 else
8990 {
8991 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8992 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8993 VOS_MAC_ADDR_SIZE);
8994 }
8995 }
8996 }
8997 else
8998 {
8999 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
9000 return VOS_STATUS_E_FAILURE;
9001 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009002
Jeff Johnson295189b2012-06-20 16:38:30 -07009003
9004 return VOS_STATUS_SUCCESS;
9005}
9006
9007/**---------------------------------------------------------------------------
9008
9009 \brief hdd_post_voss_start_config() - HDD post voss start config helper
9010
9011 \param - pAdapter - Pointer to the HDD
9012
9013 \return - None
9014
9015 --------------------------------------------------------------------------*/
9016VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
9017{
9018 eHalStatus halStatus;
9019 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309020 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07009021
Jeff Johnson295189b2012-06-20 16:38:30 -07009022
9023 // Send ready indication to the HDD. This will kick off the MAC
9024 // into a 'running' state and should kick off an initial scan.
9025 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
9026 if ( !HAL_STATUS_SUCCESS( halStatus ) )
9027 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309028 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07009029 "code %08d [x%08x]",__func__, halStatus, halStatus );
9030 return VOS_STATUS_E_FAILURE;
9031 }
9032
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309033 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07009034 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
9035 // And RIVA will crash
9036 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
9037 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309038 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
9039 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
9040
9041
Jeff Johnson295189b2012-06-20 16:38:30 -07009042 return VOS_STATUS_SUCCESS;
9043}
9044
Jeff Johnson295189b2012-06-20 16:38:30 -07009045/* wake lock APIs for HDD */
Sushant Kaushikd8a351d2015-05-05 17:44:40 +05309046void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07009047{
Sushant Kaushikd8a351d2015-05-05 17:44:40 +05309048
9049 vos_wake_lock_acquire(&wlan_wake_lock, reason);
9050
Jeff Johnson295189b2012-06-20 16:38:30 -07009051}
9052
Sushant Kaushikd8a351d2015-05-05 17:44:40 +05309053void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07009054{
Sushant Kaushikd8a351d2015-05-05 17:44:40 +05309055
9056 vos_wake_lock_release(&wlan_wake_lock, reason);
9057
Jeff Johnson295189b2012-06-20 16:38:30 -07009058}
9059
Sushant Kaushikd8a351d2015-05-05 17:44:40 +05309060void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009061{
Sushant Kaushikd8a351d2015-05-05 17:44:40 +05309062
9063 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
9064 reason);
9065
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009066}
9067
Jeff Johnson295189b2012-06-20 16:38:30 -07009068/**---------------------------------------------------------------------------
9069
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009070 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
9071 information between Host and Riva
9072
9073 This function gets reported version of FW
9074 It also finds the version of Riva headers used to compile the host
9075 It compares the above two and prints a warning if they are different
9076 It gets the SW and HW version string
9077 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
9078 indicating the features they support through a bitmap
9079
9080 \param - pHddCtx - Pointer to HDD context
9081
9082 \return - void
9083
9084 --------------------------------------------------------------------------*/
9085
9086void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
9087{
9088
9089 tSirVersionType versionCompiled;
9090 tSirVersionType versionReported;
9091 tSirVersionString versionString;
9092 tANI_U8 fwFeatCapsMsgSupported = 0;
9093 VOS_STATUS vstatus;
9094
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08009095 memset(&versionCompiled, 0, sizeof(versionCompiled));
9096 memset(&versionReported, 0, sizeof(versionReported));
9097
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009098 /* retrieve and display WCNSS version information */
9099 do {
9100
9101 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
9102 &versionCompiled);
9103 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9104 {
9105 hddLog(VOS_TRACE_LEVEL_FATAL,
9106 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009107 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009108 break;
9109 }
9110
9111 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
9112 &versionReported);
9113 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9114 {
9115 hddLog(VOS_TRACE_LEVEL_FATAL,
9116 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009117 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009118 break;
9119 }
9120
9121 if ((versionCompiled.major != versionReported.major) ||
9122 (versionCompiled.minor != versionReported.minor) ||
9123 (versionCompiled.version != versionReported.version) ||
9124 (versionCompiled.revision != versionReported.revision))
9125 {
9126 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
9127 "Host expected %u.%u.%u.%u\n",
9128 WLAN_MODULE_NAME,
9129 (int)versionReported.major,
9130 (int)versionReported.minor,
9131 (int)versionReported.version,
9132 (int)versionReported.revision,
9133 (int)versionCompiled.major,
9134 (int)versionCompiled.minor,
9135 (int)versionCompiled.version,
9136 (int)versionCompiled.revision);
9137 }
9138 else
9139 {
9140 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
9141 WLAN_MODULE_NAME,
9142 (int)versionReported.major,
9143 (int)versionReported.minor,
9144 (int)versionReported.version,
9145 (int)versionReported.revision);
9146 }
9147
9148 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
9149 versionString,
9150 sizeof(versionString));
9151 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9152 {
9153 hddLog(VOS_TRACE_LEVEL_FATAL,
9154 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009155 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009156 break;
9157 }
9158
9159 pr_info("%s: WCNSS software version %s\n",
9160 WLAN_MODULE_NAME, versionString);
9161
9162 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
9163 versionString,
9164 sizeof(versionString));
9165 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9166 {
9167 hddLog(VOS_TRACE_LEVEL_FATAL,
9168 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009169 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009170 break;
9171 }
9172
9173 pr_info("%s: WCNSS hardware version %s\n",
9174 WLAN_MODULE_NAME, versionString);
9175
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009176 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
9177 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009178 send the message only if it the riva is 1.1
9179 minor numbers for different riva branches:
9180 0 -> (1.0)Mainline Build
9181 1 -> (1.1)Mainline Build
9182 2->(1.04) Stability Build
9183 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009184 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009185 ((versionReported.minor>=1) && (versionReported.version>=1)))
9186 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
9187 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009188
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009189 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08009190 {
9191#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9192 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
9193 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
9194#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07009195 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
9196 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
9197 {
9198 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
9199 }
9200
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009201 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08009202 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009203
9204 } while (0);
9205
9206}
Neelansh Mittaledafed22014-09-04 18:54:39 +05309207void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
9208{
9209 struct sk_buff *skb;
9210 struct nlmsghdr *nlh;
9211 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309212 int flags = GFP_KERNEL;
Bhargav shahf60d68d2015-10-13 12:48:35 +05309213 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309214
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309215 if (in_interrupt() || irqs_disabled() || in_atomic())
9216 flags = GFP_ATOMIC;
9217
9218 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +05309219
9220 if(skb == NULL) {
9221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9222 "%s: alloc_skb failed", __func__);
9223 return;
9224 }
9225
9226 nlh = (struct nlmsghdr *)skb->data;
9227 nlh->nlmsg_pid = 0; /* from kernel */
9228 nlh->nlmsg_flags = 0;
9229 nlh->nlmsg_seq = 0;
9230 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
9231
9232 ani_hdr = NLMSG_DATA(nlh);
9233 ani_hdr->type = type;
9234
9235 switch(type) {
9236 case WLAN_SVC_SAP_RESTART_IND:
9237 ani_hdr->length = 0;
9238 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
9239 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
9240 break;
Bhargav shahf60d68d2015-10-13 12:48:35 +05309241 case WLAN_MSG_RPS_ENABLE_IND:
9242 ani_hdr->length = len;
9243 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
9244 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
9245 memcpy(nl_data, data, len);
9246 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
9247 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309248 default:
9249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9250 "Attempt to send unknown nlink message %d", type);
9251 kfree_skb(skb);
9252 return;
9253 }
9254
9255 nl_srv_bcast(skb);
9256
9257 return;
9258}
9259
9260
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009261
9262/**---------------------------------------------------------------------------
9263
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309264 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
9265
9266 \param - pHddCtx - Pointer to the hdd context
9267
9268 \return - true if hardware supports 5GHz
9269
9270 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309271boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309272{
9273 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
9274 * then hardware support 5Ghz.
9275 */
9276 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
9277 {
Ratheesh S P8671ef02015-08-15 14:08:20 +05309278 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309279 return true;
9280 }
9281 else
9282 {
Ratheesh S P8671ef02015-08-15 14:08:20 +05309283 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309284 __func__);
9285 return false;
9286 }
9287}
9288
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309289/**---------------------------------------------------------------------------
9290
9291 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
9292 generate function
9293
9294 This is generate the random mac address for WLAN interface
9295
9296 \param - pHddCtx - Pointer to HDD context
9297 idx - Start interface index to get auto
9298 generated mac addr.
9299 mac_addr - Mac address
9300
9301 \return - 0 for success, < 0 for failure
9302
9303 --------------------------------------------------------------------------*/
9304
9305static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
9306 int idx, v_MACADDR_t mac_addr)
9307{
9308 int i;
9309 unsigned int serialno;
9310 serialno = wcnss_get_serial_number();
9311
9312 if (0 != serialno)
9313 {
9314 /* MAC address has 3 bytes of OUI so we have a maximum of 3
9315 bytes of the serial number that can be used to generate
9316 the other 3 bytes of the MAC address. Mask off all but
9317 the lower 3 bytes (this will also make sure we don't
9318 overflow in the next step) */
9319 serialno &= 0x00FFFFFF;
9320
9321 /* we need a unique address for each session */
9322 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
9323
9324 /* autogen other Mac addresses */
9325 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
9326 {
9327 /* start with the entire default address */
9328 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
9329 /* then replace the lower 3 bytes */
9330 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
9331 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
9332 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
9333
9334 serialno++;
9335 hddLog(VOS_TRACE_LEVEL_ERROR,
9336 "%s: Derived Mac Addr: "
9337 MAC_ADDRESS_STR, __func__,
9338 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
9339 }
9340
9341 }
9342 else
9343 {
9344 hddLog(LOGE, FL("Failed to Get Serial NO"));
9345 return -1;
9346 }
9347 return 0;
9348}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309349
Katya Nigame7b69a82015-04-28 15:24:06 +05309350int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
9351{
9352 VOS_STATUS status;
9353 v_CONTEXT_t pVosContext= NULL;
9354 hdd_adapter_t *pAdapter= NULL;
9355
9356 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9357
9358 if (NULL == pVosContext)
9359 {
9360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9361 "%s: Trying to open VOSS without a PreOpen", __func__);
9362 VOS_ASSERT(0);
9363 return VOS_STATUS_E_FAILURE;
9364 }
9365
9366 status = vos_nv_open();
9367 if (!VOS_IS_STATUS_SUCCESS(status))
9368 {
9369 /* NV module cannot be initialized */
9370 hddLog( VOS_TRACE_LEVEL_FATAL,
9371 "%s: vos_nv_open failed", __func__);
9372 return VOS_STATUS_E_FAILURE;
9373 }
9374
9375 status = vos_init_wiphy_from_nv_bin();
9376 if (!VOS_IS_STATUS_SUCCESS(status))
9377 {
9378 /* NV module cannot be initialized */
9379 hddLog( VOS_TRACE_LEVEL_FATAL,
9380 "%s: vos_init_wiphy failed", __func__);
9381 goto err_vos_nv_close;
9382 }
9383
9384 status = vos_open( &pVosContext, pHddCtx->parent_dev);
9385 if ( !VOS_IS_STATUS_SUCCESS( status ))
9386 {
9387 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
9388 goto err_vos_nv_close;
9389 }
9390
9391 status = vos_mon_start( pVosContext );
9392 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9393 {
9394 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
9395 goto err_vosclose;
9396 }
9397
9398 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9399 WDA_featureCapsExchange(pVosContext);
9400 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9401
9402 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
9403 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9404 if( pAdapter == NULL )
9405 {
9406 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9407 goto err_close_adapter;
9408 }
9409
9410 //Initialize the nlink service
9411 if(nl_srv_init() != 0)
9412 {
9413 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
9414 goto err_close_adapter;
9415 }
9416 return VOS_STATUS_SUCCESS;
9417
9418err_close_adapter:
9419 hdd_close_all_adapters( pHddCtx );
9420 vos_mon_stop( pVosContext );
9421err_vosclose:
9422 status = vos_sched_close( pVosContext );
9423 if (!VOS_IS_STATUS_SUCCESS(status)) {
9424 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9425 "%s: Failed to close VOSS Scheduler", __func__);
9426 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9427 }
9428 vos_close(pVosContext );
9429
9430err_vos_nv_close:
9431 vos_nv_close();
9432
9433return status;
9434}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309435/**---------------------------------------------------------------------------
9436
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309437 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
9438 completed to flush out the scan results
9439
9440 11d scan is done during driver load and is a passive scan on all
9441 channels supported by the device, 11d scans may find some APs on
9442 frequencies which are forbidden to be used in the regulatory domain
9443 the device is operating in. If these APs are notified to the supplicant
9444 it may try to connect to these APs, thus flush out all the scan results
9445 which are present in SME after 11d scan is done.
9446
9447 \return - eHalStatus
9448
9449 --------------------------------------------------------------------------*/
9450static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
9451 tANI_U32 scanId, eCsrScanStatus status)
9452{
9453 ENTER();
9454
9455 sme_ScanFlushResult(halHandle, 0);
9456
9457 EXIT();
9458
9459 return eHAL_STATUS_SUCCESS;
9460}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309461/**---------------------------------------------------------------------------
9462
9463 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
9464 logging is completed successfully.
9465
9466 \return - None
9467
9468 --------------------------------------------------------------------------*/
Siddharth Bhal55d9a252015-05-27 22:39:59 +05309469void hdd_init_frame_logging_done(void *fwlogInitCbContext, VOS_STATUS status)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309470{
Siddharth Bhal55d9a252015-05-27 22:39:59 +05309471 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309472
9473 if (NULL == pHddCtx)
9474 {
9475 hddLog(VOS_TRACE_LEVEL_ERROR,
9476 "%s: HDD context is NULL",__func__);
9477 return;
9478 }
9479
Mahesh A Saptasagar22f09d92015-06-29 12:17:04 +05309480 if ((VOS_STATUS_SUCCESS == status) &&
9481 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309482 {
9483 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
9484 pHddCtx->mgmt_frame_logging = TRUE;
9485 }
9486 else
9487 {
9488 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
9489 pHddCtx->mgmt_frame_logging = FALSE;
9490 }
9491
9492 return;
9493}
9494/**---------------------------------------------------------------------------
9495
9496 \brief hdd_init_frame_logging - function to initialize frame logging.
9497 Currently only Mgmt Frames are logged in both TX
9498 and Rx direction and are sent to userspace
9499 application using logger thread when queried.
9500
9501 \return - None
9502
9503 --------------------------------------------------------------------------*/
Siddharth Bhal55d9a252015-05-27 22:39:59 +05309504void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309505{
9506 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Siddharth Bhal55d9a252015-05-27 22:39:59 +05309507 tpSirFWLoggingInitParam wlanFWLoggingInitParam;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309508
Siddharth Bhal55d9a252015-05-27 22:39:59 +05309509 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
9510 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309511 {
9512 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
9513 return;
9514 }
9515
Siddharth Bhal55d9a252015-05-27 22:39:59 +05309516 wlanFWLoggingInitParam = vos_mem_malloc(sizeof(tSirFWLoggingInitParam));
9517 if(NULL == wlanFWLoggingInitParam)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309518 {
9519 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed ", __func__);
9520 return;
9521 }
9522
Siddharth Bhal55d9a252015-05-27 22:39:59 +05309523 vos_mem_set(wlanFWLoggingInitParam, sizeof(tSirFWLoggingInitParam), 0);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309524
Siddharth Bhal55d9a252015-05-27 22:39:59 +05309525 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s Logging",__func__,
9526 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
9527 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
9528 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309529
Siddharth Bhal55d9a252015-05-27 22:39:59 +05309530 if (pHddCtx->cfg_ini->enableFWLogging ||
9531 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309532 {
Siddharth Bhal55d9a252015-05-27 22:39:59 +05309533 wlanFWLoggingInitParam->enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309534 }
9535
Sushant Kaushike13281f2015-07-08 14:46:03 +05309536 if (pHddCtx->cfg_ini->enableMgmtLogging)
9537 {
9538 wlanFWLoggingInitParam->enableFlag |= WLAN_FRAME_LOG_EN;
9539 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309540 if (pHddCtx->cfg_ini->enableBMUHWtracing)
9541 {
Siddharth Bhal55d9a252015-05-27 22:39:59 +05309542 wlanFWLoggingInitParam->enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309543 }
9544
Siddharth Bhal55d9a252015-05-27 22:39:59 +05309545 wlanFWLoggingInitParam->frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
9546 wlanFWLoggingInitParam->frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
9547 wlanFWLoggingInitParam->bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
9548 wlanFWLoggingInitParam->continuousFrameLogging =
9549 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309550
Siddharth Bhal55d9a252015-05-27 22:39:59 +05309551 wlanFWLoggingInitParam->enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309552
Siddharth Bhal55d9a252015-05-27 22:39:59 +05309553 wlanFWLoggingInitParam->minLogBufferSize =
9554 pHddCtx->cfg_ini->minLoggingBufferSize;
9555 wlanFWLoggingInitParam->maxLogBufferSize =
9556 pHddCtx->cfg_ini->maxLoggingBufferSize;
9557 wlanFWLoggingInitParam->fwlogInitCallback = hdd_init_frame_logging_done;
9558 wlanFWLoggingInitParam->fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309559
Siddharth Bhal55d9a252015-05-27 22:39:59 +05309560 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309561
9562 if (eHAL_STATUS_SUCCESS != halStatus)
9563 {
Siddharth Bhal55d9a252015-05-27 22:39:59 +05309564 vos_mem_free(wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309565 }
9566
9567 return;
9568}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309569
Bhargav shahf60d68d2015-10-13 12:48:35 +05309570static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
9571{
9572 hdd_adapter_t *adapter;
9573 hdd_adapter_list_node_t *adapter_node, *next;
9574 VOS_STATUS status = VOS_STATUS_SUCCESS;
9575 struct wlan_rps_data rps_data;
9576 int count;
9577
9578 if(!hdd_ctxt->cfg_ini->rps_mask)
9579 {
9580 return;
9581 }
9582
9583 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
9584 {
9585 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
9586 }
9587
9588 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
9589
9590 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
9591 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
9592 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
9593
9594 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
9595
9596 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
9597 {
9598 adapter = adapter_node->pAdapter;
9599 if (NULL != adapter) {
9600 strlcpy(rps_data.ifname, adapter->dev->name,
9601 sizeof(rps_data.ifname));
9602 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
9603 (void *)&rps_data,sizeof(rps_data));
9604 }
9605 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
9606 adapter_node = next;
9607 }
9608}
9609
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309610/**---------------------------------------------------------------------------
9611
Jeff Johnson295189b2012-06-20 16:38:30 -07009612 \brief hdd_wlan_startup() - HDD init function
9613
9614 This is the driver startup code executed once a WLAN device has been detected
9615
9616 \param - dev - Pointer to the underlying device
9617
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009618 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07009619
9620 --------------------------------------------------------------------------*/
9621
9622int hdd_wlan_startup(struct device *dev )
9623{
9624 VOS_STATUS status;
9625 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009626 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009627 hdd_context_t *pHddCtx = NULL;
9628 v_CONTEXT_t pVosContext= NULL;
9629#ifdef WLAN_BTAMP_FEATURE
9630 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
9631 WLANBAP_ConfigType btAmpConfig;
9632 hdd_config_t *pConfig;
9633#endif
9634 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009635 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309636 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009637
9638 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009639 /*
9640 * cfg80211: wiphy allocation
9641 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309642 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009643
9644 if(wiphy == NULL)
9645 {
9646 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009647 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009648 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009649 pHddCtx = wiphy_priv(wiphy);
9650
Jeff Johnson295189b2012-06-20 16:38:30 -07009651 //Initialize the adapter context to zeros.
9652 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
9653
Jeff Johnson295189b2012-06-20 16:38:30 -07009654 pHddCtx->wiphy = wiphy;
Sushant Kaushikd8a351d2015-05-05 17:44:40 +05309655 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +05309656 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009657
9658 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9659
Siddharth Bhal6d195022015-06-29 12:25:40 +05309660 /* register for riva power on lock to platform driver
9661 * Locking power early to ensure FW doesn't reset by kernel while
9662 * host driver is busy initializing itself */
9663 if (req_riva_power_on_lock("wlan"))
9664 {
9665 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9666 __func__);
9667 goto err_free_hdd_context;
9668 }
9669
Jeff Johnson295189b2012-06-20 16:38:30 -07009670 /*Get vos context here bcoz vos_open requires it*/
9671 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9672
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08009673 if(pVosContext == NULL)
9674 {
9675 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
9676 goto err_free_hdd_context;
9677 }
9678
Jeff Johnson295189b2012-06-20 16:38:30 -07009679 //Save the Global VOSS context in adapter context for future.
9680 pHddCtx->pvosContext = pVosContext;
9681
9682 //Save the adapter context in global context for future.
9683 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
9684
Jeff Johnson295189b2012-06-20 16:38:30 -07009685 pHddCtx->parent_dev = dev;
9686
9687 init_completion(&pHddCtx->full_pwr_comp_var);
9688 init_completion(&pHddCtx->standby_comp_var);
9689 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009690 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009691 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05309692 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309693 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagarcb5ccd52015-10-21 15:38:41 +05309694 init_completion(&pHddCtx->mc_sus_event_var);
9695 init_completion(&pHddCtx->tx_sus_event_var);
9696 init_completion(&pHddCtx->rx_sus_event_var);
9697
Amar Singhala49cbc52013-10-08 18:37:44 -07009698
mukul sharmadcf3c2a2015-08-13 20:33:25 +05309699 hdd_init_ll_stats_ctx(pHddCtx);
9700
Amar Singhala49cbc52013-10-08 18:37:44 -07009701#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07009702 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07009703#else
9704 init_completion(&pHddCtx->driver_crda_req);
9705#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009706
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309707 spin_lock_init(&pHddCtx->schedScan_lock);
9708
Jeff Johnson295189b2012-06-20 16:38:30 -07009709 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
9710
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309711#ifdef FEATURE_WLAN_TDLS
9712 /* tdls_lock is initialized before an hdd_open_adapter ( which is
9713 * invoked by other instances also) to protect the concurrent
9714 * access for the Adapters by TDLS module.
9715 */
9716 mutex_init(&pHddCtx->tdls_lock);
9717#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05309718 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05309719 mutex_init(&pHddCtx->wmmLock);
9720
Agarwal Ashish1f422872014-07-22 00:11:55 +05309721 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309722
Agarwal Ashish1f422872014-07-22 00:11:55 +05309723 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009724 // Load all config first as TL config is needed during vos_open
9725 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9726 if(pHddCtx->cfg_ini == NULL)
9727 {
9728 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9729 goto err_free_hdd_context;
9730 }
9731
9732 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9733
9734 // Read and parse the qcom_cfg.ini file
9735 status = hdd_parse_config_ini( pHddCtx );
9736 if ( VOS_STATUS_SUCCESS != status )
9737 {
9738 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9739 __func__, WLAN_INI_FILE);
9740 goto err_config;
9741 }
Arif Hussaind5218912013-12-05 01:10:55 -08009742#ifdef MEMORY_DEBUG
9743 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9744 vos_mem_init();
9745
9746 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9747 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9748#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009749
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309750 /* INI has been read, initialise the configuredMcastBcastFilter with
9751 * INI value as this will serve as the default value
9752 */
9753 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9754 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9755 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309756
9757 if (false == hdd_is_5g_supported(pHddCtx))
9758 {
9759 //5Ghz is not supported.
9760 if (1 != pHddCtx->cfg_ini->nBandCapability)
9761 {
9762 hddLog(VOS_TRACE_LEVEL_INFO,
9763 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9764 pHddCtx->cfg_ini->nBandCapability = 1;
9765 }
9766 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309767
9768 /* If SNR Monitoring is enabled, FW has to parse all beacons
9769 * for calcaluting and storing the average SNR, so set Nth beacon
9770 * filter to 1 to enable FW to parse all the beaocons
9771 */
9772 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9773 {
9774 /* The log level is deliberately set to WARN as overriding
9775 * nthBeaconFilter to 1 will increase power cosumption and this
9776 * might just prove helpful to detect the power issue.
9777 */
9778 hddLog(VOS_TRACE_LEVEL_WARN,
9779 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9780 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9781 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009782 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309783 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009784 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009785 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009786 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009787 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9788 {
9789 hddLog(VOS_TRACE_LEVEL_FATAL,
9790 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9791 goto err_config;
9792 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009793 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009794
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009795 // Update VOS trace levels based upon the cfg.ini
9796 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9797 pHddCtx->cfg_ini->vosTraceEnableBAP);
9798 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9799 pHddCtx->cfg_ini->vosTraceEnableTL);
9800 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9801 pHddCtx->cfg_ini->vosTraceEnableWDI);
9802 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9803 pHddCtx->cfg_ini->vosTraceEnableHDD);
9804 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9805 pHddCtx->cfg_ini->vosTraceEnableSME);
9806 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9807 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309808 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9809 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009810 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9811 pHddCtx->cfg_ini->vosTraceEnableWDA);
9812 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9813 pHddCtx->cfg_ini->vosTraceEnableSYS);
9814 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9815 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009816 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9817 pHddCtx->cfg_ini->vosTraceEnableSAP);
9818 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9819 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009820
Jeff Johnson295189b2012-06-20 16:38:30 -07009821 // Update WDI trace levels based upon the cfg.ini
9822 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9823 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9824 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9825 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9826 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9827 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9828 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9829 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009830
Jeff Johnson88ba7742013-02-27 14:36:02 -08009831 if (VOS_FTM_MODE == hdd_get_conparam())
9832 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009833 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9834 {
9835 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9836 goto err_free_hdd_context;
9837 }
9838 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +05309839 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +05309840 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009841 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009842 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009843
Katya Nigame7b69a82015-04-28 15:24:06 +05309844 if( VOS_MONITOR_MODE == hdd_get_conparam())
9845 {
9846 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
9847 {
9848 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
9849 goto err_free_hdd_context;
9850 }
9851 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
9852 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
9853 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9854 return VOS_STATUS_SUCCESS;
9855 }
9856
Jeff Johnson88ba7742013-02-27 14:36:02 -08009857 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009858 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9859 {
9860 status = vos_watchdog_open(pVosContext,
9861 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9862
9863 if(!VOS_IS_STATUS_SUCCESS( status ))
9864 {
9865 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309866 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009867 }
9868 }
9869
9870 pHddCtx->isLogpInProgress = FALSE;
9871 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9872
Amar Singhala49cbc52013-10-08 18:37:44 -07009873#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009874 /* initialize the NV module. This is required so that
9875 we can initialize the channel information in wiphy
9876 from the NV.bin data. The channel information in
9877 wiphy needs to be initialized before wiphy registration */
9878
9879 status = vos_nv_open();
9880 if (!VOS_IS_STATUS_SUCCESS(status))
9881 {
9882 /* NV module cannot be initialized */
9883 hddLog( VOS_TRACE_LEVEL_FATAL,
9884 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309885 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009886 }
9887
9888 status = vos_init_wiphy_from_nv_bin();
9889 if (!VOS_IS_STATUS_SUCCESS(status))
9890 {
9891 /* NV module cannot be initialized */
9892 hddLog( VOS_TRACE_LEVEL_FATAL,
9893 "%s: vos_init_wiphy failed", __func__);
9894 goto err_vos_nv_close;
9895 }
9896
Amar Singhala49cbc52013-10-08 18:37:44 -07009897#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309898 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309899 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009900 if ( !VOS_IS_STATUS_SUCCESS( status ))
9901 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009902 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309903 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009904 }
9905
Jeff Johnson295189b2012-06-20 16:38:30 -07009906 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9907
9908 if ( NULL == pHddCtx->hHal )
9909 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009910 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009911 goto err_vosclose;
9912 }
9913
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009914 status = vos_preStart( pHddCtx->pvosContext );
9915 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9916 {
9917 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309918 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009919 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009920
Arif Hussaineaf68602013-12-30 23:10:44 -08009921 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9922 {
9923 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9924 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9925 __func__, enable_dfs_chan_scan);
9926 }
9927 if (0 == enable_11d || 1 == enable_11d)
9928 {
9929 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9930 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9931 __func__, enable_11d);
9932 }
9933
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009934 /* Note that the vos_preStart() sequence triggers the cfg download.
9935 The cfg download must occur before we update the SME config
9936 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009937 status = hdd_set_sme_config( pHddCtx );
9938
9939 if ( VOS_STATUS_SUCCESS != status )
9940 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009941 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309942 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009943 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009944
Jeff Johnson295189b2012-06-20 16:38:30 -07009945 /* In the integrated architecture we update the configuration from
9946 the INI file and from NV before vOSS has been started so that
9947 the final contents are available to send down to the cCPU */
9948
9949 // Apply the cfg.ini to cfg.dat
9950 if (FALSE == hdd_update_config_dat(pHddCtx))
9951 {
9952 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309953 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009954 }
9955
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309956 // Get mac addr from platform driver
9957 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9958
9959 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009960 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309961 /* Store the mac addr for first interface */
9962 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9963
9964 hddLog(VOS_TRACE_LEVEL_ERROR,
9965 "%s: WLAN Mac Addr: "
9966 MAC_ADDRESS_STR, __func__,
9967 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9968
9969 /* Here, passing Arg2 as 1 because we do not want to change the
9970 last 3 bytes (means non OUI bytes) of first interface mac
9971 addr.
9972 */
9973 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9974 {
9975 hddLog(VOS_TRACE_LEVEL_ERROR,
9976 "%s: Failed to generate wlan interface mac addr "
9977 "using MAC from ini file ", __func__);
9978 }
9979 }
9980 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9981 {
9982 // Apply the NV to cfg.dat
9983 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009984#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9985 /* There was not a valid set of MAC Addresses in NV. See if the
9986 default addresses were modified by the cfg.ini settings. If so,
9987 we'll use them, but if not, we'll autogenerate a set of MAC
9988 addresses based upon the device serial number */
9989
9990 static const v_MACADDR_t default_address =
9991 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009992
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309993 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9994 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009995 {
9996 /* cfg.ini has the default address, invoke autogen logic */
9997
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309998 /* Here, passing Arg2 as 0 because we want to change the
9999 last 3 bytes (means non OUI bytes) of all the interfaces
10000 mac addr.
10001 */
10002 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
10003 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070010004 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010005 hddLog(VOS_TRACE_LEVEL_ERROR,
10006 "%s: Failed to generate wlan interface mac addr "
10007 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
10008 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070010009 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010010 }
10011 else
10012#endif //WLAN_AUTOGEN_MACADDR_FEATURE
10013 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010014 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010015 "%s: Invalid MAC address in NV, using MAC from ini file "
10016 MAC_ADDRESS_STR, __func__,
10017 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
10018 }
10019 }
10020 {
10021 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010022
10023 /* Set the MAC Address Currently this is used by HAL to
10024 * add self sta. Remove this once self sta is added as
10025 * part of session open.
10026 */
Jeff Johnson295189b2012-06-20 16:38:30 -070010027 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
10028 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
10029 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010030
Jeff Johnson295189b2012-06-20 16:38:30 -070010031 if (!HAL_STATUS_SUCCESS( halStatus ))
10032 {
10033 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
10034 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010035 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070010036 }
10037 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010038
10039 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
10040 Note: Firmware image will be read and downloaded inside vos_start API */
10041 status = vos_start( pHddCtx->pvosContext );
10042 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10043 {
10044 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulaa61d2452015-09-22 14:05:18 +053010045 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010046 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070010047 }
10048
Leo Chang6cec3e22014-01-21 15:33:49 -080010049#ifdef FEATURE_WLAN_CH_AVOID
10050 /* Plug in avoid channel notification callback
10051 * This should happen before ADD_SELF_STA
10052 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053010053
10054 /* check the Channel Avoidance is enabled */
10055 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
10056 {
10057 sme_AddChAvoidCallback(pHddCtx->hHal,
10058 hdd_hostapd_ch_avoid_cb);
10059 }
Leo Chang6cec3e22014-01-21 15:33:49 -080010060#endif /* FEATURE_WLAN_CH_AVOID */
10061
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010062 /* Exchange capability info between Host and FW and also get versioning info from FW */
10063 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010064
Agarwal Ashishad9281b2014-06-10 14:57:30 +053010065#ifdef CONFIG_ENABLE_LINUX_REG
10066 status = wlan_hdd_init_channels(pHddCtx);
10067 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10068 {
10069 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
10070 __func__);
10071 goto err_vosstop;
10072 }
10073#endif
10074
Jeff Johnson295189b2012-06-20 16:38:30 -070010075 status = hdd_post_voss_start_config( pHddCtx );
10076 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10077 {
10078 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
10079 __func__);
10080 goto err_vosstop;
10081 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010082
10083#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010084 wlan_hdd_cfg80211_update_reg_info( wiphy );
10085
10086 /* registration of wiphy dev with cfg80211 */
10087 if (0 > wlan_hdd_cfg80211_register(wiphy))
10088 {
10089 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
10090 goto err_vosstop;
10091 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010092#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010093
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010094#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010095 /* registration of wiphy dev with cfg80211 */
10096 if (0 > wlan_hdd_cfg80211_register(wiphy))
10097 {
10098 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
10099 goto err_vosstop;
10100 }
10101
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010102 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010103 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10104 {
10105 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
10106 __func__);
10107 goto err_unregister_wiphy;
10108 }
10109#endif
10110
c_hpothu4a298be2014-12-22 21:12:51 +053010111 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
10112
Jeff Johnson295189b2012-06-20 16:38:30 -070010113 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10114 {
10115 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
10116 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
10117 }
10118 else
10119 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010120 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
10121 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
10122 if (pAdapter != NULL)
10123 {
Katya Nigama7d81d72014-11-12 12:44:34 +053010124 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070010125 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053010126 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
10127 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
10128 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070010129
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053010130 /* Generate the P2P Device Address. This consists of the device's
10131 * primary MAC address with the locally administered bit set.
10132 */
10133 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070010134 }
10135 else
10136 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053010137 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
10138 if (p2p_dev_addr != NULL)
10139 {
10140 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
10141 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
10142 }
10143 else
10144 {
10145 hddLog(VOS_TRACE_LEVEL_FATAL,
10146 "%s: Failed to allocate mac_address for p2p_device",
10147 __func__);
10148 goto err_close_adapter;
10149 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010150 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010151
10152 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
10153 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
10154 if ( NULL == pP2pAdapter )
10155 {
10156 hddLog(VOS_TRACE_LEVEL_FATAL,
10157 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010158 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070010159 goto err_close_adapter;
10160 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010161 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010162 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010163
10164 if( pAdapter == NULL )
10165 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010166 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
10167 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010168 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010169
Arif Hussain66559122013-11-21 10:11:40 -080010170 if (country_code)
10171 {
10172 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080010173 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080010174 hdd_checkandupdate_dfssetting(pAdapter, country_code);
10175#ifndef CONFIG_ENABLE_LINUX_REG
10176 hdd_checkandupdate_phymode(pAdapter, country_code);
10177#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080010178 ret = sme_ChangeCountryCode(pHddCtx->hHal,
10179 (void *)(tSmeChangeCountryCallback)
10180 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080010181 country_code,
10182 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010183 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080010184 if (eHAL_STATUS_SUCCESS == ret)
10185 {
Arif Hussaincb607082013-12-20 11:57:42 -080010186 ret = wait_for_completion_interruptible_timeout(
10187 &pAdapter->change_country_code,
10188 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
10189
10190 if (0 >= ret)
10191 {
10192 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10193 "%s: SME while setting country code timed out", __func__);
10194 }
Arif Hussain66559122013-11-21 10:11:40 -080010195 }
10196 else
10197 {
Arif Hussaincb607082013-12-20 11:57:42 -080010198 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10199 "%s: SME Change Country code from module param fail ret=%d",
10200 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080010201 }
10202 }
10203
Jeff Johnson295189b2012-06-20 16:38:30 -070010204#ifdef WLAN_BTAMP_FEATURE
10205 vStatus = WLANBAP_Open(pVosContext);
10206 if(!VOS_IS_STATUS_SUCCESS(vStatus))
10207 {
10208 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10209 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070010210 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010211 }
10212
10213 vStatus = BSL_Init(pVosContext);
10214 if(!VOS_IS_STATUS_SUCCESS(vStatus))
10215 {
10216 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10217 "%s: Failed to Init BSL",__func__);
10218 goto err_bap_close;
10219 }
10220 vStatus = WLANBAP_Start(pVosContext);
10221 if (!VOS_IS_STATUS_SUCCESS(vStatus))
10222 {
10223 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10224 "%s: Failed to start TL",__func__);
10225 goto err_bap_close;
10226 }
10227
10228 pConfig = pHddCtx->cfg_ini;
10229 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
10230 status = WLANBAP_SetConfig(&btAmpConfig);
10231
10232#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070010233
Mihir Shete9c238772014-10-15 14:35:16 +053010234 /*
10235 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
10236 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
10237 * which is greater than 0xf. So the below check is safe to make
10238 * sure that there is no entry for UapsdMask in the ini
10239 */
10240 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
10241 {
10242 if(IS_DYNAMIC_WMM_PS_ENABLED)
10243 {
10244 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
10245 __func__);
10246 pHddCtx->cfg_ini->UapsdMask =
10247 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
10248 }
10249 else
10250 {
10251 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
10252 __func__);
10253 pHddCtx->cfg_ini->UapsdMask =
10254 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
10255 }
10256 }
10257
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070010258#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
10259 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
10260 {
10261 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
10262 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
10263 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
10264 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
10265 }
10266#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010267
Agarwal Ashish4b87f922014-06-18 03:03:21 +053010268 wlan_hdd_tdls_init(pHddCtx);
10269
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053010270 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
10271
Jeff Johnson295189b2012-06-20 16:38:30 -070010272 /* Register with platform driver as client for Suspend/Resume */
10273 status = hddRegisterPmOps(pHddCtx);
10274 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10275 {
10276 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
10277#ifdef WLAN_BTAMP_FEATURE
10278 goto err_bap_stop;
10279#else
Jeff Johnsone7245742012-09-05 17:12:55 -070010280 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010281#endif //WLAN_BTAMP_FEATURE
10282 }
10283
Yue Ma0d4891e2013-08-06 17:01:45 -070010284 /* Open debugfs interface */
10285 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
10286 {
10287 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10288 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070010289 }
10290
Jeff Johnson295189b2012-06-20 16:38:30 -070010291 /* Register TM level change handler function to the platform */
10292 status = hddDevTmRegisterNotifyCallback(pHddCtx);
10293 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10294 {
10295 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
10296 goto err_unregister_pmops;
10297 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010298
Jeff Johnson295189b2012-06-20 16:38:30 -070010299 // register net device notifier for device change notification
10300 ret = register_netdevice_notifier(&hdd_netdev_notifier);
10301
10302 if(ret < 0)
10303 {
10304 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhal6d195022015-06-29 12:25:40 +053010305 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070010306 }
10307
10308 //Initialize the nlink service
10309 if(nl_srv_init() != 0)
10310 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010311 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010312 goto err_reg_netdev;
10313 }
10314
Leo Chang4ce1cc52013-10-21 18:27:15 -070010315#ifdef WLAN_KD_READY_NOTIFIER
10316 pHddCtx->kd_nl_init = 1;
10317#endif /* WLAN_KD_READY_NOTIFIER */
10318
Jeff Johnson295189b2012-06-20 16:38:30 -070010319 //Initialize the BTC service
10320 if(btc_activate_service(pHddCtx) != 0)
10321 {
10322 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
10323 goto err_nl_srv;
10324 }
10325
10326#ifdef PTT_SOCK_SVC_ENABLE
10327 //Initialize the PTT service
10328 if(ptt_sock_activate_svc(pHddCtx) != 0)
10329 {
10330 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
10331 goto err_nl_srv;
10332 }
10333#endif
10334
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010335#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10336 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
10337 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053010338 if(wlan_logging_sock_activate_svc(
10339 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
10340 pHddCtx->cfg_ini->wlanLoggingNumBuf))
10341 {
10342 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
10343 " failed", __func__);
10344 goto err_nl_srv;
10345 }
10346 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
10347 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053010348 if (!pHddCtx->cfg_ini->gEnableDebugLog)
10349 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik554af062015-10-05 17:23:07 +053010350 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
10351 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010352 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010353
Siddharth Bhal55d9a252015-05-27 22:39:59 +053010354 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
10355 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhal41b8ea42015-06-25 19:34:35 +053010356 pHddCtx->cfg_ini->enableMgmtLogging ||
Siddharth Bhal55d9a252015-05-27 22:39:59 +053010357 pHddCtx->cfg_ini->enableContFWLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010358 {
Siddharth Bhal55d9a252015-05-27 22:39:59 +053010359 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010360 }
10361 else
10362 {
Siddharth Bhal55d9a252015-05-27 22:39:59 +053010363 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010364 }
10365
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010366#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010367
10368
Sushant Kaushik215778f2015-05-21 14:05:36 +053010369 if (vos_is_multicast_logging())
10370 wlan_logging_set_log_level();
10371
Jeff Johnson295189b2012-06-20 16:38:30 -070010372 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010373 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070010374 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070010375 /* Action frame registered in one adapter which will
10376 * applicable to all interfaces
10377 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053010378 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010379 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010380
10381 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053010382 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010383
Jeff Johnsone7245742012-09-05 17:12:55 -070010384#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10385 /* Initialize the wake lcok */
Sushant Kaushikd8a351d2015-05-05 17:44:40 +053010386 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070010387 "qcom_rx_wakelock");
Sushant Kaushikd8a351d2015-05-05 17:44:40 +053010388
Jeff Johnsone7245742012-09-05 17:12:55 -070010389#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010390 /* Initialize the wake lcok */
Sushant Kaushikd8a351d2015-05-05 17:44:40 +053010391 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010392 "qcom_sap_wakelock");
Sushant Kaushikd8a351d2015-05-05 17:44:40 +053010393
Jeff Johnsone7245742012-09-05 17:12:55 -070010394
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010395 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
10396 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010397
Katya Nigam5c306ea2014-06-19 15:39:54 +053010398 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010399 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushikd8a351d2015-05-05 17:44:40 +053010400 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053010401
10402#ifdef FEATURE_WLAN_SCAN_PNO
10403 /*SME must send channel update configuration to RIVA*/
10404 sme_UpdateChannelConfig(pHddCtx->hHal);
10405#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053010406 /* Send the update default channel list to the FW*/
10407 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053010408
10409 /* Fwr capabilities received, Set the Dot11 mode */
10410 sme_SetDefDot11Mode(pHddCtx->hHal);
10411
Abhishek Singha306a442013-11-07 18:39:01 +053010412#ifndef CONFIG_ENABLE_LINUX_REG
10413 /*updating wiphy so that regulatory user hints can be processed*/
10414 if (wiphy)
10415 {
10416 regulatory_hint(wiphy, "00");
10417 }
10418#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010419 // Initialize the restart logic
10420 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053010421
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010422 //Register the traffic monitor timer now
10423 if ( pHddCtx->cfg_ini->dynSplitscan)
10424 {
10425 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
10426 VOS_TIMER_TYPE_SW,
10427 hdd_tx_rx_pkt_cnt_stat_timer_handler,
10428 (void *)pHddCtx);
10429 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053010430 wlan_hdd_cfg80211_nan_init(pHddCtx);
10431
Dino Mycle6fb96c12014-06-10 11:52:40 +053010432#ifdef WLAN_FEATURE_EXTSCAN
10433 sme_EXTScanRegisterCallback(pHddCtx->hHal,
10434 wlan_hdd_cfg80211_extscan_callback,
10435 pHddCtx);
10436#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010437
10438#ifdef WLAN_NS_OFFLOAD
10439 // Register IPv6 notifier to notify if any change in IP
10440 // So that we can reconfigure the offload parameters
10441 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
10442 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10443 if (ret)
10444 {
Ratheesh S P8671ef02015-08-15 14:08:20 +053010445 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010446 }
10447 else
10448 {
Ratheesh S P8671ef02015-08-15 14:08:20 +053010449 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010450 }
10451#endif
10452
10453 // Register IPv4 notifier to notify if any change in IP
10454 // So that we can reconfigure the offload parameters
10455 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
10456 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10457 if (ret)
10458 {
Ratheesh S P8671ef02015-08-15 14:08:20 +053010459 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010460 }
10461 else
10462 {
Ratheesh S P8671ef02015-08-15 14:08:20 +053010463 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010464 }
Bhargav shahf60d68d2015-10-13 12:48:35 +053010465 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010466
Jeff Johnson295189b2012-06-20 16:38:30 -070010467 goto success;
10468
10469err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -070010470#ifdef WLAN_KD_READY_NOTIFIER
10471 nl_srv_exit(pHddCtx->ptt_pid);
10472#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010473 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -070010474#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -070010475err_reg_netdev:
10476 unregister_netdevice_notifier(&hdd_netdev_notifier);
10477
Jeff Johnson295189b2012-06-20 16:38:30 -070010478err_unregister_pmops:
10479 hddDevTmUnregisterNotifyCallback(pHddCtx);
10480 hddDeregisterPmOps(pHddCtx);
10481
Yue Ma0d4891e2013-08-06 17:01:45 -070010482 hdd_debugfs_exit(pHddCtx);
10483
Jeff Johnson295189b2012-06-20 16:38:30 -070010484#ifdef WLAN_BTAMP_FEATURE
10485err_bap_stop:
10486 WLANBAP_Stop(pVosContext);
10487#endif
10488
10489#ifdef WLAN_BTAMP_FEATURE
10490err_bap_close:
10491 WLANBAP_Close(pVosContext);
10492#endif
10493
Jeff Johnson295189b2012-06-20 16:38:30 -070010494err_close_adapter:
10495 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010496#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010497err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010498#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010499 wiphy_unregister(wiphy) ;
Agrawal Ashishd4232f02015-11-26 20:20:58 +053010500 hdd_wlan_free_wiphy_channels(wiphy);
10501
Jeff Johnson295189b2012-06-20 16:38:30 -070010502err_vosstop:
10503 vos_stop(pVosContext);
10504
Amar Singhala49cbc52013-10-08 18:37:44 -070010505err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070010506 status = vos_sched_close( pVosContext );
10507 if (!VOS_IS_STATUS_SUCCESS(status)) {
10508 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10509 "%s: Failed to close VOSS Scheduler", __func__);
10510 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
10511 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010512 vos_close(pVosContext );
10513
Amar Singhal0a402232013-10-11 20:57:16 -070010514err_vos_nv_close:
10515
c_hpothue6a36282014-03-19 12:27:38 +053010516#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070010517 vos_nv_close();
10518
c_hpothu70f8d812014-03-22 22:59:23 +053010519#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010520
10521err_wdclose:
10522 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10523 vos_watchdog_close(pVosContext);
10524
Jeff Johnson295189b2012-06-20 16:38:30 -070010525err_config:
10526 kfree(pHddCtx->cfg_ini);
10527 pHddCtx->cfg_ini= NULL;
10528
10529err_free_hdd_context:
Sushant Kaushikd8a351d2015-05-05 17:44:40 +053010530 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhal6d195022015-06-29 12:25:40 +053010531 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010532 wiphy_free(wiphy) ;
10533 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010534 VOS_BUG(1);
10535
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080010536 if (hdd_is_ssr_required())
10537 {
10538 /* WDI timeout had happened during load, so SSR is needed here */
10539 subsystem_restart("wcnss");
10540 msleep(5000);
10541 }
10542 hdd_set_ssr_required (VOS_FALSE);
10543
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010544 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010545
10546success:
10547 EXIT();
10548 return 0;
10549}
10550
10551/**---------------------------------------------------------------------------
10552
Jeff Johnson32d95a32012-09-10 13:15:23 -070010553 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070010554
Jeff Johnson32d95a32012-09-10 13:15:23 -070010555 This is the driver entry point - called in different timeline depending
10556 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070010557
10558 \param - None
10559
10560 \return - 0 for success, non zero for failure
10561
10562 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070010563static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010564{
10565 VOS_STATUS status;
10566 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010567 struct device *dev = NULL;
10568 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010569#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10570 int max_retries = 0;
10571#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010572#ifdef HAVE_CBC_DONE
10573 int max_cbc_retries = 0;
10574#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010575
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010576#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10577 wlan_logging_sock_init_svc();
10578#endif
10579
Jeff Johnson295189b2012-06-20 16:38:30 -070010580 ENTER();
10581
Sushant Kaushikd8a351d2015-05-05 17:44:40 +053010582 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010583
10584 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
10585 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
10586
Jeff Johnson295189b2012-06-20 16:38:30 -070010587#ifdef ANI_BUS_TYPE_PCI
10588
10589 dev = wcnss_wlan_get_device();
10590
10591#endif // ANI_BUS_TYPE_PCI
10592
10593#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010594
10595#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10596 /* wait until WCNSS driver downloads NV */
10597 while (!wcnss_device_ready() && 5 >= ++max_retries) {
10598 msleep(1000);
10599 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010600
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010601 if (max_retries >= 5) {
10602 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushikd8a351d2015-05-05 17:44:40 +053010603 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010604#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10605 wlan_logging_sock_deinit_svc();
10606#endif
10607
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010608 return -ENODEV;
10609 }
10610#endif
10611
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010612#ifdef HAVE_CBC_DONE
10613 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
10614 msleep(1000);
10615 }
10616 if (max_cbc_retries >= 10) {
10617 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
10618 }
10619#endif
10620
Jeff Johnson295189b2012-06-20 16:38:30 -070010621 dev = wcnss_wlan_get_device();
10622#endif // ANI_BUS_TYPE_PLATFORM
10623
10624
10625 do {
10626 if (NULL == dev) {
10627 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
10628 ret_status = -1;
10629 break;
10630 }
10631
Jeff Johnson295189b2012-06-20 16:38:30 -070010632#ifdef TIMER_MANAGER
10633 vos_timer_manager_init();
10634#endif
10635
10636 /* Preopen VOSS so that it is ready to start at least SAL */
10637 status = vos_preOpen(&pVosContext);
10638
10639 if (!VOS_IS_STATUS_SUCCESS(status))
10640 {
10641 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
10642 ret_status = -1;
10643 break;
10644 }
10645
Sushant Kaushik6f0f2b12015-06-04 15:15:01 +053010646 hddTraceInit();
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010647#ifndef MODULE
10648 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
10649 */
10650 hdd_set_conparam((v_UINT_t)con_mode);
10651#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010652
10653 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010654 if (hdd_wlan_startup(dev))
10655 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010656 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010657 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010658 vos_preClose( &pVosContext );
10659 ret_status = -1;
10660 break;
10661 }
10662
Jeff Johnson295189b2012-06-20 16:38:30 -070010663 } while (0);
10664
10665 if (0 != ret_status)
10666 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010667#ifdef TIMER_MANAGER
10668 vos_timer_exit();
10669#endif
10670#ifdef MEMORY_DEBUG
10671 vos_mem_exit();
10672#endif
Sushant Kaushikd8a351d2015-05-05 17:44:40 +053010673 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010674#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10675 wlan_logging_sock_deinit_svc();
10676#endif
10677
Jeff Johnson295189b2012-06-20 16:38:30 -070010678 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
10679 }
10680 else
10681 {
10682 //Send WLAN UP indication to Nlink Service
10683 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
10684
10685 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070010686 }
10687
10688 EXIT();
10689
10690 return ret_status;
10691}
10692
Jeff Johnson32d95a32012-09-10 13:15:23 -070010693/**---------------------------------------------------------------------------
10694
10695 \brief hdd_module_init() - Init Function
10696
10697 This is the driver entry point (invoked when module is loaded using insmod)
10698
10699 \param - None
10700
10701 \return - 0 for success, non zero for failure
10702
10703 --------------------------------------------------------------------------*/
10704#ifdef MODULE
10705static int __init hdd_module_init ( void)
10706{
10707 return hdd_driver_init();
10708}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010709#else /* #ifdef MODULE */
10710static int __init hdd_module_init ( void)
10711{
10712 /* Driver initialization is delayed to fwpath_changed_handler */
10713 return 0;
10714}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010715#endif /* #ifdef MODULE */
10716
Jeff Johnson295189b2012-06-20 16:38:30 -070010717
10718/**---------------------------------------------------------------------------
10719
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010720 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070010721
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010722 This is the driver exit point (invoked when module is unloaded using rmmod
10723 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070010724
10725 \param - None
10726
10727 \return - None
10728
10729 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010730static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010731{
10732 hdd_context_t *pHddCtx = NULL;
10733 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053010734 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053010735 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010736
10737 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
10738
10739 //Get the global vos context
10740 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10741
10742 if(!pVosContext)
10743 {
10744 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10745 goto done;
10746 }
10747
10748 //Get the HDD context.
10749 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10750
10751 if(!pHddCtx)
10752 {
10753 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10754 }
Katya Nigame7b69a82015-04-28 15:24:06 +053010755 else if (VOS_MONITOR_MODE == hdd_get_conparam())
10756 {
10757 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
10758 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10759 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
10760 hdd_wlan_exit(pHddCtx);
10761 vos_preClose( &pVosContext );
10762 goto done;
10763 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010764 else
10765 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053010766 /* We wait for active entry threads to exit from driver
10767 * by waiting until rtnl_lock is available.
10768 */
10769 rtnl_lock();
10770 rtnl_unlock();
10771
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010772 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10773 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10774 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10775 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010777 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010778 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10779 msecs_to_jiffies(30000));
10780 if(!rc)
10781 {
10782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10783 "%s:SSR timedout, fatal error", __func__);
10784 VOS_BUG(0);
10785 }
10786 }
10787
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010788 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10789 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010790
c_hpothu8adb97b2014-12-08 19:38:20 +053010791 /* Driver Need to send country code 00 in below condition
10792 * 1) If gCountryCodePriority is set to 1; and last country
10793 * code set is through 11d. This needs to be done in case
10794 * when NV country code is 00.
10795 * This Needs to be done as when kernel store last country
10796 * code and if stored country code is not through 11d,
10797 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10798 * in next load/unload as soon as we get any country through
10799 * 11d. In sme_HandleChangeCountryCodeByUser
10800 * pMsg->countryCode will be last countryCode and
10801 * pMac->scan.countryCode11d will be country through 11d so
10802 * due to mismatch driver will disable 11d.
10803 *
10804 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010805
c_hpothu8adb97b2014-12-08 19:38:20 +053010806 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010807 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010808 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010809 {
10810 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010811 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010812 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10813 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010814
c_hpothu8adb97b2014-12-08 19:38:20 +053010815 //Do all the cleanup before deregistering the driver
10816 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010817 }
10818
Jeff Johnson295189b2012-06-20 16:38:30 -070010819 vos_preClose( &pVosContext );
10820
10821#ifdef TIMER_MANAGER
10822 vos_timer_exit();
10823#endif
10824#ifdef MEMORY_DEBUG
10825 vos_mem_exit();
10826#endif
10827
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010828#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10829 wlan_logging_sock_deinit_svc();
10830#endif
10831
Jeff Johnson295189b2012-06-20 16:38:30 -070010832done:
Sushant Kaushikd8a351d2015-05-05 17:44:40 +053010833 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010834
Jeff Johnson295189b2012-06-20 16:38:30 -070010835 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10836}
10837
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010838/**---------------------------------------------------------------------------
10839
10840 \brief hdd_module_exit() - Exit function
10841
10842 This is the driver exit point (invoked when module is unloaded using rmmod)
10843
10844 \param - None
10845
10846 \return - None
10847
10848 --------------------------------------------------------------------------*/
10849static void __exit hdd_module_exit(void)
10850{
10851 hdd_driver_exit();
10852}
10853
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010854#ifdef MODULE
10855static int fwpath_changed_handler(const char *kmessage,
10856 struct kernel_param *kp)
10857{
Jeff Johnson76052702013-04-16 13:55:05 -070010858 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010859}
10860
10861static int con_mode_handler(const char *kmessage,
10862 struct kernel_param *kp)
10863{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010864 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010865}
10866#else /* #ifdef MODULE */
10867/**---------------------------------------------------------------------------
10868
Jeff Johnson76052702013-04-16 13:55:05 -070010869 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010870
Jeff Johnson76052702013-04-16 13:55:05 -070010871 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010872 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010873 - invoked when module parameter fwpath is modified from userspace to signal
10874 initializing the WLAN driver or when con_mode is modified from userspace
10875 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010876
10877 \return - 0 for success, non zero for failure
10878
10879 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010880static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010881{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010882 int ret_status;
10883
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010884 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010885 ret_status = hdd_driver_init();
10886 wlan_hdd_inited = ret_status ? 0 : 1;
10887 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010888 }
10889
10890 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010891
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010892 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010893
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010894 ret_status = hdd_driver_init();
10895 wlan_hdd_inited = ret_status ? 0 : 1;
10896 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010897}
10898
Jeff Johnson295189b2012-06-20 16:38:30 -070010899/**---------------------------------------------------------------------------
10900
Jeff Johnson76052702013-04-16 13:55:05 -070010901 \brief fwpath_changed_handler() - Handler Function
10902
10903 Handle changes to the fwpath parameter
10904
10905 \return - 0 for success, non zero for failure
10906
10907 --------------------------------------------------------------------------*/
10908static int fwpath_changed_handler(const char *kmessage,
10909 struct kernel_param *kp)
10910{
10911 int ret;
10912
10913 ret = param_set_copystring(kmessage, kp);
10914 if (0 == ret)
10915 ret = kickstart_driver();
10916 return ret;
10917}
10918
10919/**---------------------------------------------------------------------------
10920
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010921 \brief con_mode_handler() -
10922
10923 Handler function for module param con_mode when it is changed by userspace
10924 Dynamically linked - do nothing
10925 Statically linked - exit and init driver, as in rmmod and insmod
10926
Jeff Johnson76052702013-04-16 13:55:05 -070010927 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010928
Jeff Johnson76052702013-04-16 13:55:05 -070010929 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010930
10931 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010932static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010933{
Jeff Johnson76052702013-04-16 13:55:05 -070010934 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010935
Jeff Johnson76052702013-04-16 13:55:05 -070010936 ret = param_set_int(kmessage, kp);
10937 if (0 == ret)
10938 ret = kickstart_driver();
10939 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010940}
10941#endif /* #ifdef MODULE */
10942
10943/**---------------------------------------------------------------------------
10944
Jeff Johnson295189b2012-06-20 16:38:30 -070010945 \brief hdd_get_conparam() -
10946
10947 This is the driver exit point (invoked when module is unloaded using rmmod)
10948
10949 \param - None
10950
10951 \return - tVOS_CON_MODE
10952
10953 --------------------------------------------------------------------------*/
10954tVOS_CON_MODE hdd_get_conparam ( void )
10955{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010956#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010957 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010958#else
10959 return (tVOS_CON_MODE)curr_con_mode;
10960#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010961}
10962void hdd_set_conparam ( v_UINT_t newParam )
10963{
10964 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010965#ifndef MODULE
10966 curr_con_mode = con_mode;
10967#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010968}
10969/**---------------------------------------------------------------------------
10970
10971 \brief hdd_softap_sta_deauth() - function
10972
10973 This to take counter measure to handle deauth req from HDD
10974
10975 \param - pAdapter - Pointer to the HDD
10976
10977 \param - enable - boolean value
10978
10979 \return - None
10980
10981 --------------------------------------------------------------------------*/
10982
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010983VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10984 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010985{
Jeff Johnson295189b2012-06-20 16:38:30 -070010986 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010987 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010988
10989 ENTER();
10990
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010991 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10992 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010993
10994 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010995 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010996 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010997
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010998 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010999
11000 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011001 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070011002}
11003
11004/**---------------------------------------------------------------------------
11005
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011006 \brief hdd_del_all_sta() - function
11007
11008 This function removes all the stations associated on stopping AP/P2P GO.
11009
11010 \param - pAdapter - Pointer to the HDD
11011
11012 \return - None
11013
11014 --------------------------------------------------------------------------*/
11015
11016int hdd_del_all_sta(hdd_adapter_t *pAdapter)
11017{
11018 v_U16_t i;
11019 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011020 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11021 ptSapContext pSapCtx = NULL;
11022 pSapCtx = VOS_GET_SAP_CB(pVosContext);
11023 if(pSapCtx == NULL){
11024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11025 FL("psapCtx is NULL"));
11026 return 1;
11027 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011028 ENTER();
11029
11030 hddLog(VOS_TRACE_LEVEL_INFO,
11031 "%s: Delete all STAs associated.",__func__);
11032 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11033 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
11034 )
11035 {
11036 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
11037 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011038 if ((pSapCtx->aStaInfo[i].isUsed) &&
11039 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011040 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011041 struct tagCsrDelStaParams delStaParams;
11042
11043 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011044 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053011045 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
11046 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011047 &delStaParams);
11048 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011049 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011050 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011051 }
11052 }
11053 }
11054
11055 EXIT();
11056 return 0;
11057}
11058
11059/**---------------------------------------------------------------------------
11060
Jeff Johnson295189b2012-06-20 16:38:30 -070011061 \brief hdd_softap_sta_disassoc() - function
11062
11063 This to take counter measure to handle deauth req from HDD
11064
11065 \param - pAdapter - Pointer to the HDD
11066
11067 \param - enable - boolean value
11068
11069 \return - None
11070
11071 --------------------------------------------------------------------------*/
11072
11073void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
11074{
11075 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11076
11077 ENTER();
11078
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011079 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011080
11081 //Ignore request to disassoc bcmc station
11082 if( pDestMacAddress[0] & 0x1 )
11083 return;
11084
11085 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
11086}
11087
11088void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
11089{
11090 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11091
11092 ENTER();
11093
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011094 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011095
11096 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
11097}
11098
Jeff Johnson295189b2012-06-20 16:38:30 -070011099/**---------------------------------------------------------------------------
11100 *
11101 * \brief hdd_get__concurrency_mode() -
11102 *
11103 *
11104 * \param - None
11105 *
11106 * \return - CONCURRENCY MODE
11107 *
11108 * --------------------------------------------------------------------------*/
11109tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
11110{
11111 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
11112 hdd_context_t *pHddCtx;
11113
11114 if (NULL != pVosContext)
11115 {
11116 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
11117 if (NULL != pHddCtx)
11118 {
11119 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
11120 }
11121 }
11122
11123 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011124 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011125 return VOS_STA;
11126}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011127v_BOOL_t
11128wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
11129{
11130 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011131
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011132 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
11133 if (pAdapter == NULL)
11134 {
11135 hddLog(VOS_TRACE_LEVEL_INFO,
11136 FL("GO doesn't exist"));
11137 return TRUE;
11138 }
11139 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11140 {
11141 hddLog(VOS_TRACE_LEVEL_INFO,
11142 FL("GO started"));
11143 return TRUE;
11144 }
11145 else
11146 /* wait till GO changes its interface to p2p device */
11147 hddLog(VOS_TRACE_LEVEL_INFO,
11148 FL("Del_bss called, avoid apps suspend"));
11149 return FALSE;
11150
11151}
Jeff Johnson295189b2012-06-20 16:38:30 -070011152/* Decide whether to allow/not the apps power collapse.
11153 * Allow apps power collapse if we are in connected state.
11154 * if not, allow only if we are in IMPS */
11155v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
11156{
11157 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080011158 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080011159 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011160 hdd_config_t *pConfig = pHddCtx->cfg_ini;
11161 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11162 hdd_adapter_t *pAdapter = NULL;
11163 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080011164 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011165
Jeff Johnson295189b2012-06-20 16:38:30 -070011166 if (VOS_STA_SAP_MODE == hdd_get_conparam())
11167 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011168
Yathish9f22e662012-12-10 14:21:35 -080011169 concurrent_state = hdd_get_concurrency_mode();
11170
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011171 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
11172 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
11173 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080011174#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011175
Yathish9f22e662012-12-10 14:21:35 -080011176 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011177 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080011178 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
11179 return TRUE;
11180#endif
11181
Jeff Johnson295189b2012-06-20 16:38:30 -070011182 /*loop through all adapters. TBD fix for Concurrency */
11183 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11184 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11185 {
11186 pAdapter = pAdapterNode->pAdapter;
11187 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11188 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11189 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080011190 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053011191 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053011192 && pmcState != STOPPED && pmcState != STANDBY &&
11193 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080011194 (eANI_BOOLEAN_TRUE == scanRspPending) ||
11195 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070011196 {
Mukul Sharma4be88422015-03-09 20:29:07 +053011197 if(pmcState == FULL_POWER &&
11198 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
11199 {
11200 /*
11201 * When SCO indication comes from Coex module , host will
11202 * enter in to full power mode, but this should not prevent
11203 * apps processor power collapse.
11204 */
11205 hddLog(LOG1,
11206 FL("Allow apps power collapse"
11207 "even when sco indication is set"));
11208 return TRUE;
11209 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080011210 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080011211 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
11212 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070011213 return FALSE;
11214 }
11215 }
11216 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11217 pAdapterNode = pNext;
11218 }
11219 return TRUE;
11220}
11221
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080011222/* Decides whether to send suspend notification to Riva
11223 * if any adapter is in BMPS; then it is required */
11224v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
11225{
11226 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
11227 hdd_config_t *pConfig = pHddCtx->cfg_ini;
11228
11229 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
11230 {
11231 return TRUE;
11232 }
11233 return FALSE;
11234}
11235
Jeff Johnson295189b2012-06-20 16:38:30 -070011236void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11237{
11238 switch(mode)
11239 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011240 case VOS_STA_MODE:
11241 case VOS_P2P_CLIENT_MODE:
11242 case VOS_P2P_GO_MODE:
11243 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070011244 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011245 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070011246 break;
11247 default:
11248 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011249 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011250 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11251 "Number of open sessions for mode %d = %d"),
11252 pHddCtx->concurrency_mode, mode,
11253 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011254}
11255
11256
11257void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11258{
11259 switch(mode)
11260 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011261 case VOS_STA_MODE:
11262 case VOS_P2P_CLIENT_MODE:
11263 case VOS_P2P_GO_MODE:
11264 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053011265 pHddCtx->no_of_open_sessions[mode]--;
11266 if (!(pHddCtx->no_of_open_sessions[mode]))
11267 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070011268 break;
11269 default:
11270 break;
11271 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011272 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11273 "Number of open sessions for mode %d = %d"),
11274 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
11275
11276}
11277/**---------------------------------------------------------------------------
11278 *
11279 * \brief wlan_hdd_incr_active_session()
11280 *
11281 * This function increments the number of active sessions
11282 * maintained per device mode
11283 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
11284 * Incase of SAP/P2P GO upon bss start it is incremented
11285 *
11286 * \param pHddCtx - HDD Context
11287 * \param mode - device mode
11288 *
11289 * \return - None
11290 *
11291 * --------------------------------------------------------------------------*/
11292void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11293{
11294 switch (mode) {
11295 case VOS_STA_MODE:
11296 case VOS_P2P_CLIENT_MODE:
11297 case VOS_P2P_GO_MODE:
11298 case VOS_STA_SAP_MODE:
11299 pHddCtx->no_of_active_sessions[mode]++;
11300 break;
11301 default:
11302 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11303 break;
11304 }
11305 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11306 mode,
11307 pHddCtx->no_of_active_sessions[mode]);
11308}
11309
11310/**---------------------------------------------------------------------------
11311 *
11312 * \brief wlan_hdd_decr_active_session()
11313 *
11314 * This function decrements the number of active sessions
11315 * maintained per device mode
11316 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
11317 * Incase of SAP/P2P GO upon bss stop it is decremented
11318 *
11319 * \param pHddCtx - HDD Context
11320 * \param mode - device mode
11321 *
11322 * \return - None
11323 *
11324 * --------------------------------------------------------------------------*/
11325void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11326{
11327 switch (mode) {
11328 case VOS_STA_MODE:
11329 case VOS_P2P_CLIENT_MODE:
11330 case VOS_P2P_GO_MODE:
11331 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053011332 if (pHddCtx->no_of_active_sessions[mode] > 0)
11333 pHddCtx->no_of_active_sessions[mode]--;
11334 else
11335 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
11336 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053011337 break;
11338 default:
11339 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11340 break;
11341 }
11342 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11343 mode,
11344 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011345}
11346
Jeff Johnsone7245742012-09-05 17:12:55 -070011347/**---------------------------------------------------------------------------
11348 *
11349 * \brief wlan_hdd_restart_init
11350 *
11351 * This function initalizes restart timer/flag. An internal function.
11352 *
11353 * \param - pHddCtx
11354 *
11355 * \return - None
11356 *
11357 * --------------------------------------------------------------------------*/
11358
11359static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
11360{
11361 /* Initialize */
11362 pHddCtx->hdd_restart_retries = 0;
11363 atomic_set(&pHddCtx->isRestartInProgress, 0);
11364 vos_timer_init(&pHddCtx->hdd_restart_timer,
11365 VOS_TIMER_TYPE_SW,
11366 wlan_hdd_restart_timer_cb,
11367 pHddCtx);
11368}
11369/**---------------------------------------------------------------------------
11370 *
11371 * \brief wlan_hdd_restart_deinit
11372 *
11373 * This function cleans up the resources used. An internal function.
11374 *
11375 * \param - pHddCtx
11376 *
11377 * \return - None
11378 *
11379 * --------------------------------------------------------------------------*/
11380
11381static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
11382{
11383
11384 VOS_STATUS vos_status;
11385 /* Block any further calls */
11386 atomic_set(&pHddCtx->isRestartInProgress, 1);
11387 /* Cleanup */
11388 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
11389 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011390 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011391 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
11392 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011393 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011394
11395}
11396
11397/**---------------------------------------------------------------------------
11398 *
11399 * \brief wlan_hdd_framework_restart
11400 *
11401 * This function uses a cfg80211 API to start a framework initiated WLAN
11402 * driver module unload/load.
11403 *
11404 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
11405 *
11406 *
11407 * \param - pHddCtx
11408 *
11409 * \return - VOS_STATUS_SUCCESS: Success
11410 * VOS_STATUS_E_EMPTY: Adapter is Empty
11411 * VOS_STATUS_E_NOMEM: No memory
11412
11413 * --------------------------------------------------------------------------*/
11414
11415static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
11416{
11417 VOS_STATUS status = VOS_STATUS_SUCCESS;
11418 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011419 int len = (sizeof (struct ieee80211_mgmt));
11420 struct ieee80211_mgmt *mgmt = NULL;
11421
11422 /* Prepare the DEAUTH managment frame with reason code */
11423 mgmt = kzalloc(len, GFP_KERNEL);
11424 if(mgmt == NULL)
11425 {
11426 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11427 "%s: memory allocation failed (%d bytes)", __func__, len);
11428 return VOS_STATUS_E_NOMEM;
11429 }
11430 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070011431
11432 /* Iterate over all adapters/devices */
11433 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011434 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
11435 {
11436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11437 FL("fail to get adapter: %p %d"), pAdapterNode, status);
11438 goto end;
11439 }
11440
Jeff Johnsone7245742012-09-05 17:12:55 -070011441 do
11442 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011443 if(pAdapterNode->pAdapter &&
11444 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070011445 {
11446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11447 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
11448 pAdapterNode->pAdapter->dev->name,
11449 pAdapterNode->pAdapter->device_mode,
11450 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011451 /*
11452 * CFG80211 event to restart the driver
11453 *
11454 * 'cfg80211_send_unprot_deauth' sends a
11455 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
11456 * of SME(Linux Kernel) state machine.
11457 *
11458 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
11459 * the driver.
11460 *
11461 */
Anand N Sunkad3e9fe782015-07-29 09:56:45 +053011462#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
11463 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
11464#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011465 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkad3e9fe782015-07-29 09:56:45 +053011466#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011467 }
11468 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11469 pAdapterNode = pNext;
11470 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
11471
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011472 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011473 /* Free the allocated management frame */
11474 kfree(mgmt);
11475
Jeff Johnsone7245742012-09-05 17:12:55 -070011476 /* Retry until we unload or reach max count */
11477 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
11478 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
11479
11480 return status;
11481
11482}
11483/**---------------------------------------------------------------------------
11484 *
11485 * \brief wlan_hdd_restart_timer_cb
11486 *
11487 * Restart timer callback. An internal function.
11488 *
11489 * \param - User data:
11490 *
11491 * \return - None
11492 *
11493 * --------------------------------------------------------------------------*/
11494
11495void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
11496{
11497 hdd_context_t *pHddCtx = usrDataForCallback;
11498 wlan_hdd_framework_restart(pHddCtx);
11499 return;
11500
11501}
11502
11503
11504/**---------------------------------------------------------------------------
11505 *
11506 * \brief wlan_hdd_restart_driver
11507 *
11508 * This function sends an event to supplicant to restart the WLAN driver.
11509 *
11510 * This function is called from vos_wlanRestart.
11511 *
11512 * \param - pHddCtx
11513 *
11514 * \return - VOS_STATUS_SUCCESS: Success
11515 * VOS_STATUS_E_EMPTY: Adapter is Empty
11516 * VOS_STATUS_E_ALREADY: Request already in progress
11517
11518 * --------------------------------------------------------------------------*/
11519VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
11520{
11521 VOS_STATUS status = VOS_STATUS_SUCCESS;
11522
11523 /* A tight check to make sure reentrancy */
11524 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
11525 {
Mihir Shetefd528652014-06-23 19:07:50 +053011526 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070011527 "%s: WLAN restart is already in progress", __func__);
11528
11529 return VOS_STATUS_E_ALREADY;
11530 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070011531 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080011532#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053011533 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070011534#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011535
Jeff Johnsone7245742012-09-05 17:12:55 -070011536 return status;
11537}
11538
Mihir Shetee1093ba2014-01-21 20:13:32 +053011539/**---------------------------------------------------------------------------
11540 *
11541 * \brief wlan_hdd_init_channels
11542 *
11543 * This function is used to initialize the channel list in CSR
11544 *
11545 * This function is called from hdd_wlan_startup
11546 *
11547 * \param - pHddCtx: HDD context
11548 *
11549 * \return - VOS_STATUS_SUCCESS: Success
11550 * VOS_STATUS_E_FAULT: Failure reported by SME
11551
11552 * --------------------------------------------------------------------------*/
11553static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
11554{
11555 eHalStatus status;
11556
11557 status = sme_InitChannels(pHddCtx->hHal);
11558 if (HAL_STATUS_SUCCESS(status))
11559 {
11560 return VOS_STATUS_SUCCESS;
11561 }
11562 else
11563 {
11564 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
11565 __func__, status);
11566 return VOS_STATUS_E_FAULT;
11567 }
11568}
11569
Mihir Shete04206452014-11-20 17:50:58 +053011570#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011571VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011572{
11573 eHalStatus status;
11574
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011575 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011576 if (HAL_STATUS_SUCCESS(status))
11577 {
11578 return VOS_STATUS_SUCCESS;
11579 }
11580 else
11581 {
11582 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
11583 __func__, status);
11584 return VOS_STATUS_E_FAULT;
11585 }
11586}
Mihir Shete04206452014-11-20 17:50:58 +053011587#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070011588/*
11589 * API to find if there is any STA or P2P-Client is connected
11590 */
11591VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
11592{
11593 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
11594}
Jeff Johnsone7245742012-09-05 17:12:55 -070011595
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011596
11597/*
11598 * API to find if the firmware will send logs using DXE channel
11599 */
11600v_U8_t hdd_is_fw_logging_enabled(void)
11601{
11602 hdd_context_t *pHddCtx;
11603
11604 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11605 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11606
Sachin Ahuja084313e2015-05-21 17:57:10 +053011607 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011608}
11609
Agarwal Ashish57e84372014-12-05 18:26:53 +053011610/*
Mihir Shete21dd6e22015-05-26 12:07:14 +053011611 * API to find if the firmware will send trace logs using DXE channel
11612 */
11613v_U8_t hdd_is_fw_ev_logging_enabled(void)
11614{
11615 hdd_context_t *pHddCtx;
11616
11617 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11618 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11619
11620 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
11621}
11622/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053011623 * API to find if there is any session connected
11624 */
11625VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
11626{
11627 return sme_is_any_session_connected(pHddCtx->hHal);
11628}
11629
11630
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011631int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
11632{
11633 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11634 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053011635 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053011636 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011637
11638 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachurie0d270c2015-06-30 10:35:13 +053011639 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011640 if (pScanInfo->mScanPending)
11641 {
c_hpothua3d45d52015-01-05 14:11:17 +053011642 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
11643 eCSR_SCAN_ABORT_DEFAULT);
11644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11645 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011646
c_hpothua3d45d52015-01-05 14:11:17 +053011647 /* If there is active scan command lets wait for the completion else
11648 * there is no need to wait as scan command might be in the SME pending
11649 * command list.
11650 */
11651 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
11652 {
c_hpothua3d45d52015-01-05 14:11:17 +053011653 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011654 &pScanInfo->abortscan_event_var,
11655 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053011656 if (0 >= status)
11657 {
11658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053011659 "%s: Timeout or Interrupt occurred while waiting for abort"
11660 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053011661 return -ETIMEDOUT;
11662 }
11663 }
11664 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
11665 {
11666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11667 FL("hdd_abort_mac_scan failed"));
11668 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011669 }
11670 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053011671 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011672}
11673
Abhishek Singh93a21142015-11-30 14:29:27 +053011674/**
11675 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
11676 * user space
11677 * @frame_ind: Management frame data to be informed.
11678 *
11679 * This function is used to indicate management frame to
11680 * user space
11681 *
11682 * Return: None
11683 *
11684 */
11685void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
11686{
11687 hdd_context_t *hdd_ctx = NULL;
11688 hdd_adapter_t *adapter = NULL;
11689 v_CONTEXT_t vos_context = NULL;
11690
11691 /* Get the global VOSS context.*/
11692 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11693 if (!vos_context) {
11694 hddLog(LOGE, FL("Global VOS context is Null"));
11695 return;
11696 }
11697 /* Get the HDD context.*/
11698 hdd_ctx =
11699 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
11700
11701 if (0 != wlan_hdd_validate_context(hdd_ctx))
11702 {
11703 return;
11704 }
11705 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
11706 frame_ind->sessionId);
11707
11708 if ((NULL != adapter) &&
11709 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
11710 __hdd_indicate_mgmt_frame(adapter,
11711 frame_ind->frameLen,
11712 frame_ind->frameBuf,
11713 frame_ind->frameType,
11714 frame_ind->rxChan,
11715 frame_ind->rxRssi);
11716 return;
11717
11718}
11719
c_hpothu225aa7c2014-10-22 17:45:13 +053011720VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
11721{
11722 hdd_adapter_t *pAdapter;
11723 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11724 VOS_STATUS vosStatus;
11725
11726 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11727 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11728 {
11729 pAdapter = pAdapterNode->pAdapter;
11730 if (NULL != pAdapter)
11731 {
11732 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
11733 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
11734 WLAN_HDD_P2P_GO == pAdapter->device_mode)
11735 {
11736 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
11737 pAdapter->device_mode);
11738 if (VOS_STATUS_SUCCESS !=
11739 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
11740 {
11741 hddLog(LOGE, FL("failed to abort ROC"));
11742 return VOS_STATUS_E_FAILURE;
11743 }
11744 }
11745 }
11746 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11747 pAdapterNode = pNext;
11748 }
11749 return VOS_STATUS_SUCCESS;
11750}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053011751
Mihir Shete0be28772015-02-17 18:42:14 +053011752hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
11753{
11754 hdd_adapter_t *pAdapter;
11755 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11756 hdd_cfg80211_state_t *cfgState;
11757 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
11758 VOS_STATUS vosStatus;
11759
11760 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
11761 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11762 {
11763 pAdapter = pAdapterNode->pAdapter;
11764 if (NULL != pAdapter)
11765 {
11766 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
11767 pRemainChanCtx = cfgState->remain_on_chan_ctx;
11768 if (pRemainChanCtx)
11769 break;
11770 }
11771 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
11772 pAdapterNode = pNext;
11773 }
11774 return pRemainChanCtx;
11775}
11776
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053011777/**
11778 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
11779 *
11780 * @pHddCtx: HDD context within host driver
11781 * @dfsScanMode: dfsScanMode passed from ioctl
11782 *
11783 */
11784
11785VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
11786 tANI_U8 dfsScanMode)
11787{
11788 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11789 hdd_adapter_t *pAdapter;
11790 VOS_STATUS vosStatus;
11791 hdd_station_ctx_t *pHddStaCtx;
11792 eHalStatus status = eHAL_STATUS_SUCCESS;
11793
11794 if(!pHddCtx)
11795 {
11796 hddLog(LOGE, FL("HDD context is Null"));
11797 return eHAL_STATUS_FAILURE;
11798 }
11799
11800 if (pHddCtx->scan_info.mScanPending)
11801 {
11802 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
11803 pHddCtx->scan_info.sessionId);
11804 hdd_abort_mac_scan(pHddCtx,
11805 pHddCtx->scan_info.sessionId,
11806 eCSR_SCAN_ABORT_DEFAULT);
11807 }
11808
11809 if (!dfsScanMode)
11810 {
11811 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11812 while ((NULL != pAdapterNode) &&
11813 (VOS_STATUS_SUCCESS == vosStatus))
11814 {
11815 pAdapter = pAdapterNode->pAdapter;
11816
11817 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11818 {
11819 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11820
11821 if(!pHddStaCtx)
11822 {
11823 hddLog(LOGE, FL("HDD STA context is Null"));
11824 return eHAL_STATUS_FAILURE;
11825 }
11826
11827 /* if STA is already connected on DFS channel,
11828 disconnect immediately*/
11829 if (hdd_connIsConnected(pHddStaCtx) &&
11830 (NV_CHANNEL_DFS ==
11831 vos_nv_getChannelEnabledState(
11832 pHddStaCtx->conn_info.operationChannel)))
11833 {
11834 status = sme_RoamDisconnect(pHddCtx->hHal,
11835 pAdapter->sessionId,
11836 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11837 hddLog(LOG1, FL("Client connected on DFS channel %d,"
11838 "sme_RoamDisconnect returned with status: %d"
11839 "for sessionid: %d"), pHddStaCtx->conn_info.
11840 operationChannel, status, pAdapter->sessionId);
11841 }
11842 }
11843
11844 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
11845 &pNext);
11846 pAdapterNode = pNext;
11847 }
11848 }
11849
11850 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
11851 sme_UpdateDFSRoamMode(pHddCtx->hHal,
11852 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
11853
11854 status = sme_HandleDFSChanScan(pHddCtx->hHal);
11855 if (!HAL_STATUS_SUCCESS(status))
11856 {
11857 hddLog(LOGE,
11858 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
11859 return status;
11860 }
11861
11862 return status;
11863}
11864
Nirav Shaha7b2c952015-06-22 23:51:42 +053011865static int hdd_log2_ceil(unsigned value)
11866{
11867 /* need to switch to unsigned math so that negative values
11868 * will right-shift towards 0 instead of -1
11869 */
11870 unsigned tmp = value;
11871 int log2 = -1;
11872
11873 if (value == 0)
11874 return 0;
11875
11876 while (tmp) {
11877 log2++;
11878 tmp >>= 1;
11879 }
11880 if (1U << log2 != value)
11881 log2++;
11882
11883 return log2;
11884}
11885
11886/**
11887 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
11888 * @pAdapter: adapter handle
11889 *
11890 * Return: vos status
11891 */
11892VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
11893{
11894 int hash_elem, log2, i;
11895
11896 spin_lock_bh( &pAdapter->sta_hash_lock);
11897 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
11898 spin_unlock_bh( &pAdapter->sta_hash_lock);
11899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11900 "%s: hash already attached for session id %d",
11901 __func__, pAdapter->sessionId);
11902 return VOS_STATUS_SUCCESS;
11903 }
11904 spin_unlock_bh( &pAdapter->sta_hash_lock);
11905
11906 hash_elem = WLAN_MAX_STA_COUNT;
11907 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
11908 log2 = hdd_log2_ceil(hash_elem);
11909 hash_elem = 1 << log2;
11910
11911 pAdapter->sta_id_hash.mask = hash_elem - 1;
11912 pAdapter->sta_id_hash.idx_bits = log2;
11913 pAdapter->sta_id_hash.bins =
11914 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
11915 if (!pAdapter->sta_id_hash.bins) {
11916 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11917 "%s: malloc failed for session %d",
11918 __func__, pAdapter->sessionId);
11919 return VOS_STATUS_E_NOMEM;
11920 }
11921
11922 for (i = 0; i < hash_elem; i++)
11923 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
11924
11925 spin_lock_bh( &pAdapter->sta_hash_lock);
11926 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
11927 spin_unlock_bh( &pAdapter->sta_hash_lock);
11928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11929 "%s: Station ID Hash attached for session id %d",
11930 __func__, pAdapter->sessionId);
11931
11932 return VOS_STATUS_SUCCESS;
11933}
11934
11935/**
11936 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
11937 * @pAdapter: adapter handle
11938 *
11939 * Return: vos status
11940 */
11941VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
11942{
11943 int hash_elem, i;
11944 v_SIZE_t size;
11945
11946 spin_lock_bh( &pAdapter->sta_hash_lock);
11947 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11948 spin_unlock_bh( &pAdapter->sta_hash_lock);
11949 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11950 "%s: hash not initialized for session id %d",
11951 __func__, pAdapter->sessionId);
11952 return VOS_STATUS_SUCCESS;
11953 }
11954
11955 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
11956 spin_unlock_bh( &pAdapter->sta_hash_lock);
11957
11958 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
11959
11960 /* free all station info*/
11961 for (i = 0; i < hash_elem; i++) {
11962 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
11963 if (size != 0) {
11964 VOS_STATUS status;
11965 hdd_staid_hash_node_t *sta_info_node = NULL;
11966 hdd_staid_hash_node_t *next_node = NULL;
11967 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
11968 (hdd_list_node_t**) &sta_info_node );
11969
11970 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11971 {
11972 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
11973 &sta_info_node->node);
11974 vos_mem_free(sta_info_node);
11975
11976 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
11977 (hdd_list_node_t*)sta_info_node,
11978 (hdd_list_node_t**)&next_node);
11979 sta_info_node = next_node;
11980 }
11981 }
11982 }
11983
11984 vos_mem_free(pAdapter->sta_id_hash.bins);
11985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11986 "%s: Station ID Hash detached for session id %d",
11987 __func__, pAdapter->sessionId);
11988 return VOS_STATUS_SUCCESS;
11989}
11990
11991/**
11992 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
11993 * @pAdapter: adapter handle
11994 * @mac_addr_in: input mac address
11995 *
11996 * Return: index derived from mac address
11997 */
11998int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
11999 v_MACADDR_t *mac_addr_in)
12000{
12001 uint16 index;
12002 struct hdd_align_mac_addr_t * mac_addr =
12003 (struct hdd_align_mac_addr_t *)mac_addr_in;
12004
12005 index = mac_addr->bytes_ab ^
12006 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
12007 index ^= index >> pAdapter->sta_id_hash.idx_bits;
12008 index &= pAdapter->sta_id_hash.mask;
12009 return index;
12010}
12011
12012/**
12013 * hdd_sta_id_hash_add_entry() - add entry in hash
12014 * @pAdapter: adapter handle
12015 * @sta_id: station id
12016 * @mac_addr: mac address
12017 *
12018 * Return: vos status
12019 */
12020VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
12021 v_U8_t sta_id, v_MACADDR_t *mac_addr)
12022{
12023 uint16 index;
12024 hdd_staid_hash_node_t *sta_info_node = NULL;
12025
Nirav Shaha7b2c952015-06-22 23:51:42 +053012026 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
12027 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
12028 if (!sta_info_node) {
Nirav Shaha7b2c952015-06-22 23:51:42 +053012029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12030 "%s: malloc failed", __func__);
12031 return VOS_STATUS_E_NOMEM;
12032 }
12033
12034 sta_info_node->sta_id = sta_id;
12035 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
12036
Nirav Shah2482bfd2015-08-24 10:29:25 +053012037 spin_lock_bh( &pAdapter->sta_hash_lock);
12038 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
12039 spin_unlock_bh( &pAdapter->sta_hash_lock);
12040 vos_mem_free(sta_info_node);
12041 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12042 "%s: hash is not initialized for session id %d",
12043 __func__, pAdapter->sessionId);
12044 return VOS_STATUS_E_FAILURE;
12045 }
12046
Nirav Shaha7b2c952015-06-22 23:51:42 +053012047 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
12048 (hdd_list_node_t*) sta_info_node );
12049 spin_unlock_bh( &pAdapter->sta_hash_lock);
12050 return VOS_STATUS_SUCCESS;
12051}
12052
12053/**
12054 * hdd_sta_id_hash_remove_entry() - remove entry from hash
12055 * @pAdapter: adapter handle
12056 * @sta_id: station id
12057 * @mac_addr: mac address
12058 *
12059 * Return: vos status
12060 */
12061VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
12062 v_U8_t sta_id, v_MACADDR_t *mac_addr)
12063{
12064 uint16 index;
12065 VOS_STATUS status;
12066 hdd_staid_hash_node_t *sta_info_node = NULL;
12067 hdd_staid_hash_node_t *next_node = NULL;
12068
12069 spin_lock_bh( &pAdapter->sta_hash_lock);
12070 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
12071 spin_unlock_bh( &pAdapter->sta_hash_lock);
12072 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12073 "%s: hash is not initialized for session id %d",
12074 __func__, pAdapter->sessionId);
12075 return VOS_STATUS_E_FAILURE;
12076 }
12077
12078 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
12079 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
12080 (hdd_list_node_t**) &sta_info_node );
12081
12082 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
12083 {
12084 if (sta_info_node->sta_id == sta_id) {
12085 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
12086 &sta_info_node->node);
12087 vos_mem_free(sta_info_node);
12088 break;
12089 }
12090 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
12091 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
12092 sta_info_node = next_node;
12093 }
12094 spin_unlock_bh( &pAdapter->sta_hash_lock);
12095 return status;
12096}
12097
12098/**
12099 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
12100 * @pAdapter: adapter handle
12101 * @mac_addr_in: mac address
12102 *
12103 * Return: station id
12104 */
12105int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
12106 v_MACADDR_t *mac_addr_in)
12107{
12108 uint8 is_found = 0;
12109 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
12110 uint16 index;
12111 VOS_STATUS status;
12112 hdd_staid_hash_node_t *sta_info_node = NULL;
12113 hdd_staid_hash_node_t *next_node = NULL;
12114
12115 spin_lock_bh( &pAdapter->sta_hash_lock);
12116 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
12117 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shah4a6b74b2015-08-10 12:29:24 +053012118 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shaha7b2c952015-06-22 23:51:42 +053012119 FL("hash is not initialized for session id %d"),
12120 pAdapter->sessionId);
12121 return HDD_WLAN_INVALID_STA_ID;
12122 }
12123
12124 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
12125 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
12126 (hdd_list_node_t**) &sta_info_node );
12127
12128 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
12129 {
12130 if (vos_mem_compare(&sta_info_node->mac_addr,
12131 mac_addr_in, sizeof(v_MACADDR_t))) {
12132 is_found = 1;
12133 sta_id = sta_info_node->sta_id;
12134 break;
12135 }
12136 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
12137 (hdd_list_node_t*)sta_info_node,
12138 (hdd_list_node_t**)&next_node);
12139 sta_info_node = next_node;
12140 }
12141 spin_unlock_bh( &pAdapter->sta_hash_lock);
12142 return sta_id;
12143}
12144
Mahesh A Saptasagarcb5ccd52015-10-21 15:38:41 +053012145void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
12146{
12147 if (NULL == pAdapter)
12148 {
12149 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
12150 return;
12151 }
12152 init_completion(&pAdapter->session_open_comp_var);
12153 init_completion(&pAdapter->session_close_comp_var);
12154 init_completion(&pAdapter->disconnect_comp_var);
12155 init_completion(&pAdapter->linkup_event_var);
12156 init_completion(&pAdapter->cancel_rem_on_chan_var);
12157 init_completion(&pAdapter->rem_on_chan_ready_event);
12158 init_completion(&pAdapter->pno_comp_var);
12159#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12160 init_completion(&pAdapter->offchannel_tx_event);
12161#endif
12162 init_completion(&pAdapter->tx_action_cnf_event);
12163#ifdef FEATURE_WLAN_TDLS
12164 init_completion(&pAdapter->tdls_add_station_comp);
12165 init_completion(&pAdapter->tdls_del_station_comp);
12166 init_completion(&pAdapter->tdls_mgmt_comp);
12167 init_completion(&pAdapter->tdls_link_establish_req_comp);
12168#endif
12169
12170#ifdef WLAN_FEATURE_RMC
12171 init_completion(&pAdapter->ibss_peer_info_comp);
12172#endif /* WLAN_FEATURE_RMC */
12173 init_completion(&pAdapter->ula_complete);
12174 init_completion(&pAdapter->change_country_code);
12175
12176#ifdef FEATURE_WLAN_BATCH_SCAN
12177 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
12178 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
12179#endif
12180
12181 return;
12182}
12183
Jeff Johnson295189b2012-06-20 16:38:30 -070012184//Register the module init/exit functions
12185module_init(hdd_module_init);
12186module_exit(hdd_module_exit);
12187
12188MODULE_LICENSE("Dual BSD/GPL");
12189MODULE_AUTHOR("Qualcomm Atheros, Inc.");
12190MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
12191
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012192module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
12193 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070012194
Jeff Johnson76052702013-04-16 13:55:05 -070012195module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070012196 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080012197
12198module_param(enable_dfs_chan_scan, int,
12199 S_IRUSR | S_IRGRP | S_IROTH);
12200
12201module_param(enable_11d, int,
12202 S_IRUSR | S_IRGRP | S_IROTH);
12203
12204module_param(country_code, charp,
12205 S_IRUSR | S_IRGRP | S_IROTH);