blob: d45b07dcef10a2ff3215a6824cc84e8cfb0b8a18 [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 Kaushik83392fa2015-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 Sunkade9adb1b2015-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 Ashish8bd53ae2015-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 Saptasagarbeca12c2015-09-07 16:21:06 +05302230/**---------------------------------------------------------------------------
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302231
Mahesh A Saptasagarbeca12c2015-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 Sunkade9adb1b2015-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 Sunkad27354cf2015-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 Girigowda91719232015-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 Rachuria72ba112015-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 Rachuri2c9d6702015-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 Rachuri28693eb2015-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 Rachuri22a3b402015-07-17 13:21:49 +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 Rachuri52139592015-07-17 13:17:29 +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);
Sushant Kaushika08ca192015-09-16 15:52:04 +05302875 for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002876 {
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 Kaushikc9b8be52015-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 Kaushikf8abd352015-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 Kaushikbc2fb5c2015-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 Kaushik4da7ec92015-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 Kaushik231a4452015-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 Sunkade9adb1b2015-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 Sunkade9adb1b2015-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 Kaushikbb8c52c2015-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 Pacbfa932015-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 P728d7c62015-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 P2dd2a3e2015-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 Rachuri6da525d2015-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 Rachuri51a5ad12015-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);
Ratnam Rachuri8fe90c62015-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 P767224e2015-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 {
3730 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);
3737 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);
3746 return -EINVAL;
3747 }
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);
Ratnam Rachuri083ada82015-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);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05303998 len = VOS_MIN(priv_data.total_len, len + 1);
3999 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4001 "%s: failed to copy data to user buffer", __func__);
4002 ret = -EFAULT;
4003 goto exit;
4004 }
4005 ret = len;
4006 }
4007 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
4008 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05304009 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304010 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004011 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
4012 {
4013 tANI_U8 filterType = 0;
4014 tANI_U8 *value;
4015 value = command + 9;
4016
4017 /* Convert the value from ascii to integer */
4018 ret = kstrtou8(value, 10, &filterType);
4019 if (ret < 0)
4020 {
4021 /* If the input value is greater than max value of datatype,
4022 * then also kstrtou8 fails
4023 */
4024 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4025 "%s: kstrtou8 failed range ", __func__);
4026 ret = -EINVAL;
4027 goto exit;
4028 }
4029 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
4030 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
4031 {
4032 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4033 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
4034 " 2-Sink ", __func__);
4035 ret = -EINVAL;
4036 goto exit;
4037 }
4038 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
4039 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05304040 pScanInfo = &pHddCtx->scan_info;
4041 if (filterType && pScanInfo != NULL &&
4042 pHddCtx->scan_info.mScanPending)
4043 {
4044 /*Miracast Session started. Abort Scan */
4045 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4046 "%s, Aborting Scan For Miracast",__func__);
4047 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
4048 eCSR_SCAN_ABORT_DEFAULT);
4049 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004050 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05304051 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004052 }
Leo Chang614d2072013-08-22 14:59:44 -07004053 else if (strncmp(command, "SETMCRATE", 9) == 0)
4054 {
Leo Chang614d2072013-08-22 14:59:44 -07004055 tANI_U8 *value = command;
4056 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07004057 tSirRateUpdateInd *rateUpdate;
4058 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07004059
4060 /* Only valid for SAP mode */
4061 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
4062 {
4063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4064 "%s: SAP mode is not running", __func__);
4065 ret = -EFAULT;
4066 goto exit;
4067 }
4068
4069 /* Move pointer to ahead of SETMCRATE<delimiter> */
4070 /* input value is in units of hundred kbps */
4071 value = value + 10;
4072 /* Convert the value from ascii to integer, decimal base */
4073 ret = kstrtouint(value, 10, &targetRate);
4074
Leo Chang1f98cbd2013-10-17 15:03:52 -07004075 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
4076 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07004077 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07004078 hddLog(VOS_TRACE_LEVEL_ERROR,
4079 "%s: SETMCRATE indication alloc fail", __func__);
4080 ret = -EFAULT;
4081 goto exit;
4082 }
4083 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
4084
4085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4086 "MC Target rate %d", targetRate);
4087 /* Ignore unicast */
4088 rateUpdate->ucastDataRate = -1;
4089 rateUpdate->mcastDataRate24GHz = targetRate;
4090 rateUpdate->mcastDataRate5GHz = targetRate;
4091 rateUpdate->mcastDataRate24GHzTxFlag = 0;
4092 rateUpdate->mcastDataRate5GHzTxFlag = 0;
4093 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
4094 if (eHAL_STATUS_SUCCESS != status)
4095 {
4096 hddLog(VOS_TRACE_LEVEL_ERROR,
4097 "%s: SET_MC_RATE failed", __func__);
4098 vos_mem_free(rateUpdate);
4099 ret = -EFAULT;
4100 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07004101 }
4102 }
Rajeev79dbe4c2013-10-05 11:03:42 +05304103#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08004104 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05304105 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08004106 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05304107 }
4108#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004109#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004110 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
4111 {
4112 tANI_U8 *value = command;
4113 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4114 tANI_U8 numChannels = 0;
4115 eHalStatus status = eHAL_STATUS_SUCCESS;
4116
4117 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4118 if (eHAL_STATUS_SUCCESS != status)
4119 {
4120 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4121 "%s: Failed to parse channel list information", __func__);
4122 ret = -EINVAL;
4123 goto exit;
4124 }
4125
4126 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4127 {
4128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4129 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4130 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4131 ret = -EINVAL;
4132 goto exit;
4133 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004134 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004135 ChannelList,
4136 numChannels);
4137 if (eHAL_STATUS_SUCCESS != status)
4138 {
4139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4140 "%s: Failed to update channel list information", __func__);
4141 ret = -EINVAL;
4142 goto exit;
4143 }
4144 }
4145 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
4146 {
4147 tANI_U8 *value = command;
4148 char extra[128] = {0};
4149 int len = 0;
4150 tANI_U8 tid = 0;
4151 hdd_station_ctx_t *pHddStaCtx = NULL;
4152 tAniTrafStrmMetrics tsmMetrics;
4153 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4154
4155 /* if not associated, return error */
4156 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4157 {
4158 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
4159 ret = -EINVAL;
4160 goto exit;
4161 }
4162
4163 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
4164 value = value + 12;
4165 /* Convert the value from ascii to integer */
4166 ret = kstrtou8(value, 10, &tid);
4167 if (ret < 0)
4168 {
4169 /* If the input value is greater than max value of datatype, then also
4170 kstrtou8 fails */
4171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4172 "%s: kstrtou8 failed range [%d - %d]", __func__,
4173 TID_MIN_VALUE,
4174 TID_MAX_VALUE);
4175 ret = -EINVAL;
4176 goto exit;
4177 }
4178
4179 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4180 {
4181 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4182 "tid value %d is out of range"
4183 " (Min: %d Max: %d)", tid,
4184 TID_MIN_VALUE,
4185 TID_MAX_VALUE);
4186 ret = -EINVAL;
4187 goto exit;
4188 }
4189
4190 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4191 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4192
4193 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4194 {
4195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4196 "%s: failed to get tsm stats", __func__);
4197 ret = -EFAULT;
4198 goto exit;
4199 }
4200
4201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4202 "UplinkPktQueueDly(%d)\n"
4203 "UplinkPktQueueDlyHist[0](%d)\n"
4204 "UplinkPktQueueDlyHist[1](%d)\n"
4205 "UplinkPktQueueDlyHist[2](%d)\n"
4206 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304207 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004208 "UplinkPktLoss(%d)\n"
4209 "UplinkPktCount(%d)\n"
4210 "RoamingCount(%d)\n"
4211 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4212 tsmMetrics.UplinkPktQueueDlyHist[0],
4213 tsmMetrics.UplinkPktQueueDlyHist[1],
4214 tsmMetrics.UplinkPktQueueDlyHist[2],
4215 tsmMetrics.UplinkPktQueueDlyHist[3],
4216 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4217 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4218
4219 /* Output TSM stats is of the format
4220 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4221 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004222 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004223 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4224 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4225 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4226 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4227 tsmMetrics.RoamingDly);
4228
Ratnam Rachurid53009c2015-08-07 13:59:00 +05304229 len = VOS_MIN(priv_data.total_len, len + 1);
4230 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4232 "%s: failed to copy data to user buffer", __func__);
4233 ret = -EFAULT;
4234 goto exit;
4235 }
4236 }
4237 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4238 {
4239 tANI_U8 *value = command;
4240 tANI_U8 *cckmIe = NULL;
4241 tANI_U8 cckmIeLen = 0;
4242 eHalStatus status = eHAL_STATUS_SUCCESS;
4243
4244 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4245 if (eHAL_STATUS_SUCCESS != status)
4246 {
4247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4248 "%s: Failed to parse cckm ie data", __func__);
4249 ret = -EINVAL;
4250 goto exit;
4251 }
4252
4253 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4254 {
4255 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4256 "%s: CCKM Ie input length is more than max[%d]", __func__,
4257 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004258 vos_mem_free(cckmIe);
4259 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004260 ret = -EINVAL;
4261 goto exit;
4262 }
4263 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004264 vos_mem_free(cckmIe);
4265 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004266 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004267 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4268 {
4269 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004270 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004271 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004272
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004273 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004274 if (eHAL_STATUS_SUCCESS != status)
4275 {
4276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004277 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004278 ret = -EINVAL;
4279 goto exit;
4280 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004281 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4282 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4283 hdd_indicateEseBcnReportNoResults (pAdapter,
4284 eseBcnReq.bcnReq[0].measurementToken,
4285 0x02, //BIT(1) set for measurement done
4286 0); // no BSS
4287 goto exit;
4288 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004289
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004290 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4291 if (eHAL_STATUS_SUCCESS != status)
4292 {
4293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4294 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4295 ret = -EINVAL;
4296 goto exit;
4297 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004298 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004299#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304300 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4301 {
4302 eHalStatus status;
4303 char buf[32], len;
4304 long waitRet;
4305 bcnMissRateContext_t getBcnMissRateCtx;
4306
4307 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4308
4309 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4310 {
4311 hddLog(VOS_TRACE_LEVEL_WARN,
4312 FL("GETBCNMISSRATE: STA is not in connected state"));
4313 ret = -1;
4314 goto exit;
4315 }
4316
4317 init_completion(&(getBcnMissRateCtx.completion));
4318 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4319
4320 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4321 pAdapter->sessionId,
4322 (void *)getBcnMissRateCB,
4323 (void *)(&getBcnMissRateCtx));
4324 if( eHAL_STATUS_SUCCESS != status)
4325 {
4326 hddLog(VOS_TRACE_LEVEL_INFO,
4327 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4328 ret = -EINVAL;
4329 goto exit;
4330 }
4331
4332 waitRet = wait_for_completion_interruptible_timeout
4333 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4334 if(waitRet <= 0)
4335 {
4336 hddLog(VOS_TRACE_LEVEL_ERROR,
4337 FL("failed to wait on bcnMissRateComp %d"), ret);
4338
4339 //Make magic number to zero so that callback is not called.
4340 spin_lock(&hdd_context_lock);
4341 getBcnMissRateCtx.magic = 0x0;
4342 spin_unlock(&hdd_context_lock);
4343 ret = -EINVAL;
4344 goto exit;
4345 }
4346
4347 hddLog(VOS_TRACE_LEVEL_INFO,
4348 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4349
4350 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4351 if (copy_to_user(priv_data.buf, &buf, len + 1))
4352 {
4353 hddLog(VOS_TRACE_LEVEL_ERROR,
4354 "%s: failed to copy data to user buffer", __func__);
4355 ret = -EFAULT;
4356 goto exit;
4357 }
4358 ret = len;
4359 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304360#ifdef FEATURE_WLAN_TDLS
4361 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4362 tANI_U8 *value = command;
4363 int set_value;
4364 /* Move pointer to ahead of TDLSOFFCH*/
4365 value += 26;
4366 sscanf(value, "%d", &set_value);
4367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4368 "%s: Tdls offchannel offset:%d",
4369 __func__, set_value);
4370 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4371 if (ret < 0)
4372 {
4373 ret = -EINVAL;
4374 goto exit;
4375 }
4376
4377 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4378 tANI_U8 *value = command;
4379 int set_value;
4380 /* Move pointer to ahead of tdlsoffchnmode*/
4381 value += 18;
4382 sscanf(value, "%d", &set_value);
4383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4384 "%s: Tdls offchannel mode:%d",
4385 __func__, set_value);
4386 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4387 if (ret < 0)
4388 {
4389 ret = -EINVAL;
4390 goto exit;
4391 }
4392 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4393 tANI_U8 *value = command;
4394 int set_value;
4395 /* Move pointer to ahead of TDLSOFFCH*/
4396 value += 14;
4397 sscanf(value, "%d", &set_value);
4398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4399 "%s: Tdls offchannel num: %d",
4400 __func__, set_value);
4401 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4402 if (ret < 0)
4403 {
4404 ret = -EINVAL;
4405 goto exit;
4406 }
4407 }
4408#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304409 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4410 {
4411 eHalStatus status;
4412 char *buf = NULL;
4413 char len;
4414 long waitRet;
4415 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304416 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304417 tANI_U8 *ptr = command;
4418 int stats = *(ptr + 11) - '0';
4419
4420 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4421 if (!IS_FEATURE_FW_STATS_ENABLE)
4422 {
4423 hddLog(VOS_TRACE_LEVEL_INFO,
4424 FL("Get Firmware stats feature not supported"));
4425 ret = -EINVAL;
4426 goto exit;
4427 }
4428
4429 if (FW_STATS_MAX <= stats || 0 >= stats)
4430 {
4431 hddLog(VOS_TRACE_LEVEL_INFO,
4432 FL(" stats %d not supported"),stats);
4433 ret = -EINVAL;
4434 goto exit;
4435 }
4436
4437 init_completion(&(fwStatsCtx.completion));
4438 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4439 fwStatsCtx.pAdapter = pAdapter;
4440 fwStatsRsp->type = 0;
4441 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304442 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304443 if (eHAL_STATUS_SUCCESS != status)
4444 {
4445 hddLog(VOS_TRACE_LEVEL_ERROR,
4446 FL(" fail to post WDA cmd status = %d"), status);
4447 ret = -EINVAL;
4448 goto exit;
4449 }
4450 waitRet = wait_for_completion_timeout
4451 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4452 if (waitRet <= 0)
4453 {
4454 hddLog(VOS_TRACE_LEVEL_ERROR,
4455 FL("failed to wait on GwtFwstats"));
4456 //Make magic number to zero so that callback is not executed.
4457 spin_lock(&hdd_context_lock);
4458 fwStatsCtx.magic = 0x0;
4459 spin_unlock(&hdd_context_lock);
4460 ret = -EINVAL;
4461 goto exit;
4462 }
4463 if (fwStatsRsp->type)
4464 {
4465 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4466 if (!buf)
4467 {
4468 hddLog(VOS_TRACE_LEVEL_ERROR,
4469 FL(" failed to allocate memory"));
4470 ret = -ENOMEM;
4471 goto exit;
4472 }
4473 switch( fwStatsRsp->type )
4474 {
4475 case FW_UBSP_STATS:
4476 {
4477 len = snprintf(buf, FW_STATE_RSP_LEN,
4478 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304479 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4480 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304481 }
4482 break;
4483 default:
4484 {
4485 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4486 ret = -EFAULT;
4487 kfree(buf);
4488 goto exit;
4489 }
4490 }
4491 if (copy_to_user(priv_data.buf, buf, len + 1))
4492 {
4493 hddLog(VOS_TRACE_LEVEL_ERROR,
4494 FL(" failed to copy data to user buffer"));
4495 ret = -EFAULT;
4496 kfree(buf);
4497 goto exit;
4498 }
4499 ret = len;
4500 kfree(buf);
4501 }
4502 else
4503 {
4504 hddLog(VOS_TRACE_LEVEL_ERROR,
4505 FL("failed to fetch the stats"));
4506 ret = -EFAULT;
4507 goto exit;
4508 }
4509
4510 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05304511 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
4512 {
4513 /*
4514 * this command wld be called by user-space when it detects WLAN
4515 * ON after airplane mode is set. When APM is set, WLAN turns off.
4516 * But it can be turned back on. Otherwise; when APM is turned back
4517 * off, WLAN wld turn back on. So at that point the command is
4518 * expected to come down. 0 means disable, 1 means enable. The
4519 * constraint is removed when parameter 1 is set or different
4520 * country code is set
4521 */
4522 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
4523 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05304524 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
4525 {
4526 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
4527 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004528 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304529 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4530 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4531 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304532 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4533 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004534 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004535 }
4536exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304537 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004538 if (command)
4539 {
4540 kfree(command);
4541 }
4542 return ret;
4543}
4544
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004545#ifdef CONFIG_COMPAT
4546static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4547{
4548 struct {
4549 compat_uptr_t buf;
4550 int used_len;
4551 int total_len;
4552 } compat_priv_data;
4553 hdd_priv_data_t priv_data;
4554 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004555
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004556 /*
4557 * Note that pAdapter and ifr have already been verified by caller,
4558 * and HDD context has also been validated
4559 */
4560 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4561 sizeof(compat_priv_data))) {
4562 ret = -EFAULT;
4563 goto exit;
4564 }
4565 priv_data.buf = compat_ptr(compat_priv_data.buf);
4566 priv_data.used_len = compat_priv_data.used_len;
4567 priv_data.total_len = compat_priv_data.total_len;
4568 ret = hdd_driver_command(pAdapter, &priv_data);
4569 exit:
4570 return ret;
4571}
4572#else /* CONFIG_COMPAT */
4573static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4574{
4575 /* will never be invoked */
4576 return 0;
4577}
4578#endif /* CONFIG_COMPAT */
4579
4580static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4581{
4582 hdd_priv_data_t priv_data;
4583 int ret = 0;
4584
4585 /*
4586 * Note that pAdapter and ifr have already been verified by caller,
4587 * and HDD context has also been validated
4588 */
4589 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4590 ret = -EFAULT;
4591 } else {
4592 ret = hdd_driver_command(pAdapter, &priv_data);
4593 }
4594 return ret;
4595}
4596
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304597int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004598{
4599 hdd_adapter_t *pAdapter;
4600 hdd_context_t *pHddCtx;
4601 int ret;
4602
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304603 ENTER();
4604
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004605 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4606 if (NULL == pAdapter) {
4607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4608 "%s: HDD adapter context is Null", __func__);
4609 ret = -ENODEV;
4610 goto exit;
4611 }
4612 if (dev != pAdapter->dev) {
4613 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4614 "%s: HDD adapter/dev inconsistency", __func__);
4615 ret = -ENODEV;
4616 goto exit;
4617 }
4618
4619 if ((!ifr) || (!ifr->ifr_data)) {
4620 ret = -EINVAL;
4621 goto exit;
4622 }
4623
4624 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4625 ret = wlan_hdd_validate_context(pHddCtx);
4626 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004627 ret = -EBUSY;
4628 goto exit;
4629 }
4630
4631 switch (cmd) {
4632 case (SIOCDEVPRIVATE + 1):
4633 if (is_compat_task())
4634 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4635 else
4636 ret = hdd_driver_ioctl(pAdapter, ifr);
4637 break;
4638 default:
4639 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4640 __func__, cmd);
4641 ret = -EINVAL;
4642 break;
4643 }
4644 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304645 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004646 return ret;
4647}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004648
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304649int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4650{
4651 int ret;
4652
4653 vos_ssr_protect(__func__);
4654 ret = __hdd_ioctl(dev, ifr, cmd);
4655 vos_ssr_unprotect(__func__);
4656
4657 return ret;
4658}
4659
Katya Nigame7b69a82015-04-28 15:24:06 +05304660int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4661{
4662 return 0;
4663}
4664
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004665#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004666/**---------------------------------------------------------------------------
4667
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004668 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004669
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004670 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004671 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4672 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4673 <space>Scan Mode N<space>Meas Duration N
4674 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4675 then take N.
4676 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4677 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4678 This function does not take care of removing duplicate channels from the list
4679
4680 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004681 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004682
4683 \return - 0 for success non-zero for failure
4684
4685 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004686static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4687 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004688{
4689 tANI_U8 *inPtr = pValue;
4690 int tempInt = 0;
4691 int j = 0, i = 0, v = 0;
4692 char buf[32];
4693
4694 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4695 /*no argument after the command*/
4696 if (NULL == inPtr)
4697 {
4698 return -EINVAL;
4699 }
4700 /*no space after the command*/
4701 else if (SPACE_ASCII_VALUE != *inPtr)
4702 {
4703 return -EINVAL;
4704 }
4705
4706 /*removing empty spaces*/
4707 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4708
4709 /*no argument followed by spaces*/
4710 if ('\0' == *inPtr) return -EINVAL;
4711
4712 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004713 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004714 if (1 != v) return -EINVAL;
4715
4716 v = kstrtos32(buf, 10, &tempInt);
4717 if ( v < 0) return -EINVAL;
4718
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004719 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004720
4721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004722 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004723
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004724 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004725 {
4726 for (i = 0; i < 4; i++)
4727 {
4728 /*inPtr pointing to the beginning of first space after number of ie fields*/
4729 inPtr = strpbrk( inPtr, " " );
4730 /*no ie data after the number of ie fields argument*/
4731 if (NULL == inPtr) return -EINVAL;
4732
4733 /*removing empty space*/
4734 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4735
4736 /*no ie data after the number of ie fields argument and spaces*/
4737 if ( '\0' == *inPtr ) return -EINVAL;
4738
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004739 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004740 if (1 != v) return -EINVAL;
4741
4742 v = kstrtos32(buf, 10, &tempInt);
4743 if (v < 0) return -EINVAL;
4744
4745 switch (i)
4746 {
4747 case 0: /* Measurement token */
4748 if (tempInt <= 0)
4749 {
4750 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4751 "Invalid Measurement Token(%d)", tempInt);
4752 return -EINVAL;
4753 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004754 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004755 break;
4756
4757 case 1: /* Channel number */
4758 if ((tempInt <= 0) ||
4759 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4760 {
4761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4762 "Invalid Channel Number(%d)", tempInt);
4763 return -EINVAL;
4764 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004765 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004766 break;
4767
4768 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004769 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004770 {
4771 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4772 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4773 return -EINVAL;
4774 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004775 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004776 break;
4777
4778 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004779 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4780 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004781 {
4782 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4783 "Invalid Measurement Duration(%d)", tempInt);
4784 return -EINVAL;
4785 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004786 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004787 break;
4788 }
4789 }
4790 }
4791
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004792 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004793 {
4794 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304795 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004796 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004797 pEseBcnReq->bcnReq[j].measurementToken,
4798 pEseBcnReq->bcnReq[j].channel,
4799 pEseBcnReq->bcnReq[j].scanMode,
4800 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004801 }
4802
4803 return VOS_STATUS_SUCCESS;
4804}
4805
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004806static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4807{
4808 struct statsContext *pStatsContext = NULL;
4809 hdd_adapter_t *pAdapter = NULL;
4810
4811 if (NULL == pContext)
4812 {
4813 hddLog(VOS_TRACE_LEVEL_ERROR,
4814 "%s: Bad param, pContext [%p]",
4815 __func__, pContext);
4816 return;
4817 }
4818
Jeff Johnson72a40512013-12-19 10:14:15 -08004819 /* there is a race condition that exists between this callback
4820 function and the caller since the caller could time out either
4821 before or while this code is executing. we use a spinlock to
4822 serialize these actions */
4823 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004824
4825 pStatsContext = pContext;
4826 pAdapter = pStatsContext->pAdapter;
4827 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4828 {
4829 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004830 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004831 hddLog(VOS_TRACE_LEVEL_WARN,
4832 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4833 __func__, pAdapter, pStatsContext->magic);
4834 return;
4835 }
4836
Jeff Johnson72a40512013-12-19 10:14:15 -08004837 /* context is valid so caller is still waiting */
4838
4839 /* paranoia: invalidate the magic */
4840 pStatsContext->magic = 0;
4841
4842 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004843 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4844 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4845 tsmMetrics.UplinkPktQueueDlyHist,
4846 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4847 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4848 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4849 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4850 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4851 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4852 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4853
Jeff Johnson72a40512013-12-19 10:14:15 -08004854 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004855 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004856
4857 /* serialization is complete */
4858 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004859}
4860
4861
4862
4863static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4864 tAniTrafStrmMetrics* pTsmMetrics)
4865{
4866 hdd_station_ctx_t *pHddStaCtx = NULL;
4867 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004868 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004869 long lrc;
4870 struct statsContext context;
4871 hdd_context_t *pHddCtx = NULL;
4872
4873 if (NULL == pAdapter)
4874 {
4875 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4876 return VOS_STATUS_E_FAULT;
4877 }
4878
4879 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4880 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4881
4882 /* we are connected prepare our callback context */
4883 init_completion(&context.completion);
4884 context.pAdapter = pAdapter;
4885 context.magic = STATS_CONTEXT_MAGIC;
4886
4887 /* query tsm stats */
4888 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4889 pHddStaCtx->conn_info.staId[ 0 ],
4890 pHddStaCtx->conn_info.bssId,
4891 &context, pHddCtx->pvosContext, tid);
4892
4893 if (eHAL_STATUS_SUCCESS != hstatus)
4894 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004895 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4896 __func__);
4897 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004898 }
4899 else
4900 {
4901 /* request was sent -- wait for the response */
4902 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4903 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004904 if (lrc <= 0)
4905 {
4906 hddLog(VOS_TRACE_LEVEL_ERROR,
4907 "%s: SME %s while retrieving statistics",
4908 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004909 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004910 }
4911 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004912
Jeff Johnson72a40512013-12-19 10:14:15 -08004913 /* either we never sent a request, we sent a request and received a
4914 response or we sent a request and timed out. if we never sent a
4915 request or if we sent a request and got a response, we want to
4916 clear the magic out of paranoia. if we timed out there is a
4917 race condition such that the callback function could be
4918 executing at the same time we are. of primary concern is if the
4919 callback function had already verified the "magic" but had not
4920 yet set the completion variable when a timeout occurred. we
4921 serialize these activities by invalidating the magic while
4922 holding a shared spinlock which will cause us to block if the
4923 callback is currently executing */
4924 spin_lock(&hdd_context_lock);
4925 context.magic = 0;
4926 spin_unlock(&hdd_context_lock);
4927
4928 if (VOS_STATUS_SUCCESS == vstatus)
4929 {
4930 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4931 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4932 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4933 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4934 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4935 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4936 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4937 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4938 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4939 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4940 }
4941 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004942}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004943#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004944
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004945#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004946void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4947{
4948 eCsrBand band = -1;
4949 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4950 switch (band)
4951 {
4952 case eCSR_BAND_ALL:
4953 *pBand = WLAN_HDD_UI_BAND_AUTO;
4954 break;
4955
4956 case eCSR_BAND_24:
4957 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4958 break;
4959
4960 case eCSR_BAND_5G:
4961 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4962 break;
4963
4964 default:
4965 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4966 *pBand = -1;
4967 break;
4968 }
4969}
4970
4971/**---------------------------------------------------------------------------
4972
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004973 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4974
4975 This function parses the send action frame data passed in the format
4976 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4977
Srinivas Girigowda56076852013-08-20 14:00:50 -07004978 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004979 \param - pTargetApBssid Pointer to target Ap bssid
4980 \param - pChannel Pointer to the Target AP channel
4981 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4982 \param - pBuf Pointer to data
4983 \param - pBufLen Pointer to data length
4984
4985 \return - 0 for success non-zero for failure
4986
4987 --------------------------------------------------------------------------*/
4988VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4989 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4990{
4991 tANI_U8 *inPtr = pValue;
4992 tANI_U8 *dataEnd;
4993 int tempInt;
4994 int j = 0;
4995 int i = 0;
4996 int v = 0;
4997 tANI_U8 tempBuf[32];
4998 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004999 /* 12 hexa decimal digits, 5 ':' and '\0' */
5000 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005001
5002 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5003 /*no argument after the command*/
5004 if (NULL == inPtr)
5005 {
5006 return -EINVAL;
5007 }
5008
5009 /*no space after the command*/
5010 else if (SPACE_ASCII_VALUE != *inPtr)
5011 {
5012 return -EINVAL;
5013 }
5014
5015 /*removing empty spaces*/
5016 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5017
5018 /*no argument followed by spaces*/
5019 if ('\0' == *inPtr)
5020 {
5021 return -EINVAL;
5022 }
5023
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005024 v = sscanf(inPtr, "%17s", macAddress);
5025 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005026 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005027 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5028 "Invalid MAC address or All hex inputs are not read (%d)", v);
5029 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005030 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005031
5032 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5033 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5034 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5035 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5036 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5037 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005038
5039 /* point to the next argument */
5040 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5041 /*no argument after the command*/
5042 if (NULL == inPtr) return -EINVAL;
5043
5044 /*removing empty spaces*/
5045 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5046
5047 /*no argument followed by spaces*/
5048 if ('\0' == *inPtr)
5049 {
5050 return -EINVAL;
5051 }
5052
5053 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005054 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005055 if (1 != v) return -EINVAL;
5056
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005057 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05305058 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05305059 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005060
5061 *pChannel = tempInt;
5062
5063 /* point to the next argument */
5064 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5065 /*no argument after the command*/
5066 if (NULL == inPtr) return -EINVAL;
5067 /*removing empty spaces*/
5068 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5069
5070 /*no argument followed by spaces*/
5071 if ('\0' == *inPtr)
5072 {
5073 return -EINVAL;
5074 }
5075
5076 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005077 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005078 if (1 != v) return -EINVAL;
5079
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005080 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08005081 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005082
5083 *pDwellTime = tempInt;
5084
5085 /* point to the next argument */
5086 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5087 /*no argument after the command*/
5088 if (NULL == inPtr) return -EINVAL;
5089 /*removing empty spaces*/
5090 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5091
5092 /*no argument followed by spaces*/
5093 if ('\0' == *inPtr)
5094 {
5095 return -EINVAL;
5096 }
5097
5098 /* find the length of data */
5099 dataEnd = inPtr;
5100 while(('\0' != *dataEnd) )
5101 {
5102 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005103 }
Kiet Lambe150c22013-11-21 16:30:32 +05305104 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005105 if ( *pBufLen <= 0) return -EINVAL;
5106
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07005107 /* Allocate the number of bytes based on the number of input characters
5108 whether it is even or odd.
5109 if the number of input characters are even, then we need N/2 byte.
5110 if the number of input characters are odd, then we need do (N+1)/2 to
5111 compensate rounding off.
5112 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5113 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5114 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005115 if (NULL == *pBuf)
5116 {
5117 hddLog(VOS_TRACE_LEVEL_FATAL,
5118 "%s: vos_mem_alloc failed ", __func__);
5119 return -EINVAL;
5120 }
5121
5122 /* the buffer received from the upper layer is character buffer,
5123 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5124 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5125 and f0 in 3rd location */
5126 for (i = 0, j = 0; j < *pBufLen; j += 2)
5127 {
Kiet Lambe150c22013-11-21 16:30:32 +05305128 if( j+1 == *pBufLen)
5129 {
5130 tempByte = hdd_parse_hex(inPtr[j]);
5131 }
5132 else
5133 {
5134 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5135 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005136 (*pBuf)[i++] = tempByte;
5137 }
5138 *pBufLen = i;
5139 return VOS_STATUS_SUCCESS;
5140}
5141
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005142/**---------------------------------------------------------------------------
5143
Srinivas Girigowdade697412013-02-14 16:31:48 -08005144 \brief hdd_parse_channellist() - HDD Parse channel list
5145
5146 This function parses the channel list passed in the format
5147 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005148 if the Number of channels (N) does not match with the actual number of channels passed
5149 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
5150 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
5151 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
5152 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08005153
5154 \param - pValue Pointer to input channel list
5155 \param - ChannelList Pointer to local output array to record channel list
5156 \param - pNumChannels Pointer to number of roam scan channels
5157
5158 \return - 0 for success non-zero for failure
5159
5160 --------------------------------------------------------------------------*/
5161VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
5162{
5163 tANI_U8 *inPtr = pValue;
5164 int tempInt;
5165 int j = 0;
5166 int v = 0;
5167 char buf[32];
5168
5169 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5170 /*no argument after the command*/
5171 if (NULL == inPtr)
5172 {
5173 return -EINVAL;
5174 }
5175
5176 /*no space after the command*/
5177 else if (SPACE_ASCII_VALUE != *inPtr)
5178 {
5179 return -EINVAL;
5180 }
5181
5182 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005183 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005184
5185 /*no argument followed by spaces*/
5186 if ('\0' == *inPtr)
5187 {
5188 return -EINVAL;
5189 }
5190
5191 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005192 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005193 if (1 != v) return -EINVAL;
5194
Srinivas Girigowdade697412013-02-14 16:31:48 -08005195 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005196 if ((v < 0) ||
5197 (tempInt <= 0) ||
5198 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
5199 {
5200 return -EINVAL;
5201 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005202
5203 *pNumChannels = tempInt;
5204
5205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5206 "Number of channels are: %d", *pNumChannels);
5207
5208 for (j = 0; j < (*pNumChannels); j++)
5209 {
5210 /*inPtr pointing to the beginning of first space after number of channels*/
5211 inPtr = strpbrk( inPtr, " " );
5212 /*no channel list after the number of channels argument*/
5213 if (NULL == inPtr)
5214 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005215 if (0 != j)
5216 {
5217 *pNumChannels = j;
5218 return VOS_STATUS_SUCCESS;
5219 }
5220 else
5221 {
5222 return -EINVAL;
5223 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005224 }
5225
5226 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005227 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005228
5229 /*no channel list after the number of channels argument and spaces*/
5230 if ( '\0' == *inPtr )
5231 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005232 if (0 != j)
5233 {
5234 *pNumChannels = j;
5235 return VOS_STATUS_SUCCESS;
5236 }
5237 else
5238 {
5239 return -EINVAL;
5240 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005241 }
5242
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005243 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005244 if (1 != v) return -EINVAL;
5245
Srinivas Girigowdade697412013-02-14 16:31:48 -08005246 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005247 if ((v < 0) ||
5248 (tempInt <= 0) ||
5249 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5250 {
5251 return -EINVAL;
5252 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005253 pChannelList[j] = tempInt;
5254
5255 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5256 "Channel %d added to preferred channel list",
5257 pChannelList[j] );
5258 }
5259
Srinivas Girigowdade697412013-02-14 16:31:48 -08005260 return VOS_STATUS_SUCCESS;
5261}
5262
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005263
5264/**---------------------------------------------------------------------------
5265
5266 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5267
5268 This function parses the reasoc command data passed in the format
5269 REASSOC<space><bssid><space><channel>
5270
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005271 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005272 \param - pTargetApBssid Pointer to target Ap bssid
5273 \param - pChannel Pointer to the Target AP channel
5274
5275 \return - 0 for success non-zero for failure
5276
5277 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005278VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5279 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005280{
5281 tANI_U8 *inPtr = pValue;
5282 int tempInt;
5283 int v = 0;
5284 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005285 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005286 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005287
5288 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5289 /*no argument after the command*/
5290 if (NULL == inPtr)
5291 {
5292 return -EINVAL;
5293 }
5294
5295 /*no space after the command*/
5296 else if (SPACE_ASCII_VALUE != *inPtr)
5297 {
5298 return -EINVAL;
5299 }
5300
5301 /*removing empty spaces*/
5302 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5303
5304 /*no argument followed by spaces*/
5305 if ('\0' == *inPtr)
5306 {
5307 return -EINVAL;
5308 }
5309
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005310 v = sscanf(inPtr, "%17s", macAddress);
5311 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005312 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5314 "Invalid MAC address or All hex inputs are not read (%d)", v);
5315 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005316 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005317
5318 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5319 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5320 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5321 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5322 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5323 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005324
5325 /* point to the next argument */
5326 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5327 /*no argument after the command*/
5328 if (NULL == inPtr) return -EINVAL;
5329
5330 /*removing empty spaces*/
5331 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5332
5333 /*no argument followed by spaces*/
5334 if ('\0' == *inPtr)
5335 {
5336 return -EINVAL;
5337 }
5338
5339 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005340 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005341 if (1 != v) return -EINVAL;
5342
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005343 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005344 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305345 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005346 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5347 {
5348 return -EINVAL;
5349 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005350
5351 *pChannel = tempInt;
5352 return VOS_STATUS_SUCCESS;
5353}
5354
5355#endif
5356
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005357#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005358/**---------------------------------------------------------------------------
5359
5360 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5361
5362 This function parses the SETCCKM IE command
5363 SETCCKMIE<space><ie data>
5364
5365 \param - pValue Pointer to input data
5366 \param - pCckmIe Pointer to output cckm Ie
5367 \param - pCckmIeLen Pointer to output cckm ie length
5368
5369 \return - 0 for success non-zero for failure
5370
5371 --------------------------------------------------------------------------*/
5372VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5373 tANI_U8 *pCckmIeLen)
5374{
5375 tANI_U8 *inPtr = pValue;
5376 tANI_U8 *dataEnd;
5377 int j = 0;
5378 int i = 0;
5379 tANI_U8 tempByte = 0;
5380
5381 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5382 /*no argument after the command*/
5383 if (NULL == inPtr)
5384 {
5385 return -EINVAL;
5386 }
5387
5388 /*no space after the command*/
5389 else if (SPACE_ASCII_VALUE != *inPtr)
5390 {
5391 return -EINVAL;
5392 }
5393
5394 /*removing empty spaces*/
5395 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5396
5397 /*no argument followed by spaces*/
5398 if ('\0' == *inPtr)
5399 {
5400 return -EINVAL;
5401 }
5402
5403 /* find the length of data */
5404 dataEnd = inPtr;
5405 while(('\0' != *dataEnd) )
5406 {
5407 dataEnd++;
5408 ++(*pCckmIeLen);
5409 }
5410 if ( *pCckmIeLen <= 0) return -EINVAL;
5411
5412 /* Allocate the number of bytes based on the number of input characters
5413 whether it is even or odd.
5414 if the number of input characters are even, then we need N/2 byte.
5415 if the number of input characters are odd, then we need do (N+1)/2 to
5416 compensate rounding off.
5417 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5418 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5419 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5420 if (NULL == *pCckmIe)
5421 {
5422 hddLog(VOS_TRACE_LEVEL_FATAL,
5423 "%s: vos_mem_alloc failed ", __func__);
5424 return -EINVAL;
5425 }
5426 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5427 /* the buffer received from the upper layer is character buffer,
5428 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5429 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5430 and f0 in 3rd location */
5431 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5432 {
5433 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5434 (*pCckmIe)[i++] = tempByte;
5435 }
5436 *pCckmIeLen = i;
5437
5438 return VOS_STATUS_SUCCESS;
5439}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005440#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005441
Jeff Johnson295189b2012-06-20 16:38:30 -07005442/**---------------------------------------------------------------------------
5443
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005444 \brief hdd_is_valid_mac_address() - Validate MAC address
5445
5446 This function validates whether the given MAC address is valid or not
5447 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5448 where X is the hexa decimal digit character and separated by ':'
5449 This algorithm works even if MAC address is not separated by ':'
5450
5451 This code checks given input string mac contains exactly 12 hexadecimal digits.
5452 and a separator colon : appears in the input string only after
5453 an even number of hex digits.
5454
5455 \param - pMacAddr pointer to the input MAC address
5456 \return - 1 for valid and 0 for invalid
5457
5458 --------------------------------------------------------------------------*/
5459
5460v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5461{
5462 int xdigit = 0;
5463 int separator = 0;
5464 while (*pMacAddr)
5465 {
5466 if (isxdigit(*pMacAddr))
5467 {
5468 xdigit++;
5469 }
5470 else if (':' == *pMacAddr)
5471 {
5472 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5473 break;
5474
5475 ++separator;
5476 }
5477 else
5478 {
5479 separator = -1;
5480 /* Invalid MAC found */
5481 return 0;
5482 }
5483 ++pMacAddr;
5484 }
5485 return (xdigit == 12 && (separator == 5 || separator == 0));
5486}
5487
5488/**---------------------------------------------------------------------------
5489
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305490 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005491
5492 \param - dev Pointer to net_device structure
5493
5494 \return - 0 for success non-zero for failure
5495
5496 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305497int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005498{
5499 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5500 hdd_context_t *pHddCtx;
5501 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5502 VOS_STATUS status;
5503 v_BOOL_t in_standby = TRUE;
5504
5505 if (NULL == pAdapter)
5506 {
5507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305508 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005509 return -ENODEV;
5510 }
5511
5512 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305513 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5514 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005515 if (NULL == pHddCtx)
5516 {
5517 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005518 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005519 return -ENODEV;
5520 }
5521
5522 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5523 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5524 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005525 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5526 {
5527 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305528 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005529 in_standby = FALSE;
5530 break;
5531 }
5532 else
5533 {
5534 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5535 pAdapterNode = pNext;
5536 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005537 }
5538
5539 if (TRUE == in_standby)
5540 {
5541 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5542 {
5543 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5544 "wlan out of power save", __func__);
5545 return -EINVAL;
5546 }
5547 }
5548
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005549 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005550 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5551 {
5552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005553 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005554 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305555 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005556 netif_tx_start_all_queues(dev);
5557 }
5558
5559 return 0;
5560}
5561
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305562/**---------------------------------------------------------------------------
5563
5564 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5565
5566 This is called in response to ifconfig up
5567
5568 \param - dev Pointer to net_device structure
5569
5570 \return - 0 for success non-zero for failure
5571
5572 --------------------------------------------------------------------------*/
5573int hdd_open(struct net_device *dev)
5574{
5575 int ret;
5576
5577 vos_ssr_protect(__func__);
5578 ret = __hdd_open(dev);
5579 vos_ssr_unprotect(__func__);
5580
5581 return ret;
5582}
5583
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305584int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005585{
5586 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5587
5588 if(pAdapter == NULL) {
5589 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005590 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005591 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005592 }
5593
Jeff Johnson295189b2012-06-20 16:38:30 -07005594 return 0;
5595}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305596
5597int hdd_mon_open (struct net_device *dev)
5598{
5599 int ret;
5600
5601 vos_ssr_protect(__func__);
5602 ret = __hdd_mon_open(dev);
5603 vos_ssr_unprotect(__func__);
5604
5605 return ret;
5606}
5607
Katya Nigame7b69a82015-04-28 15:24:06 +05305608int hdd_mon_stop(struct net_device *dev)
5609{
5610 return 0;
5611}
5612
Jeff Johnson295189b2012-06-20 16:38:30 -07005613/**---------------------------------------------------------------------------
5614
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305615 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005616
5617 \param - dev Pointer to net_device structure
5618
5619 \return - 0 for success non-zero for failure
5620
5621 --------------------------------------------------------------------------*/
5622
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305623int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005624{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305625 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005626 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5627 hdd_context_t *pHddCtx;
5628 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5629 VOS_STATUS status;
5630 v_BOOL_t enter_standby = TRUE;
5631
5632 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005633 if (NULL == pAdapter)
5634 {
5635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305636 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005637 return -ENODEV;
5638 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305639 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305640 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305641
5642 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5643 ret = wlan_hdd_validate_context(pHddCtx);
5644 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005645 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305646 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005647 }
5648
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305649 /* Nothing to be done if the interface is not opened */
5650 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5651 {
5652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5653 "%s: NETDEV Interface is not OPENED", __func__);
5654 return -ENODEV;
5655 }
5656
5657 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005658 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005659 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305660
5661 /* Disable TX on the interface, after this hard_start_xmit() will not
5662 * be called on that interface
5663 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305664 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005665 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305666
5667 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005668 netif_carrier_off(pAdapter->dev);
5669
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305670 /* The interface is marked as down for outside world (aka kernel)
5671 * But the driver is pretty much alive inside. The driver needs to
5672 * tear down the existing connection on the netdev (session)
5673 * cleanup the data pipes and wait until the control plane is stabilized
5674 * for this interface. The call also needs to wait until the above
5675 * mentioned actions are completed before returning to the caller.
5676 * Notice that the hdd_stop_adapter is requested not to close the session
5677 * That is intentional to be able to scan if it is a STA/P2P interface
5678 */
5679 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305680#ifdef FEATURE_WLAN_TDLS
5681 mutex_lock(&pHddCtx->tdls_lock);
5682#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305683 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305684 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305685#ifdef FEATURE_WLAN_TDLS
5686 mutex_unlock(&pHddCtx->tdls_lock);
5687#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005688 /* SoftAP ifaces should never go in power save mode
5689 making sure same here. */
5690 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5691 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005692 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005693 )
5694 {
5695 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5697 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005698 EXIT();
5699 return 0;
5700 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305701 /* Find if any iface is up. If any iface is up then can't put device to
5702 * sleep/power save mode
5703 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005704 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5705 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5706 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005707 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5708 {
5709 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305710 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005711 enter_standby = FALSE;
5712 break;
5713 }
5714 else
5715 {
5716 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5717 pAdapterNode = pNext;
5718 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005719 }
5720
5721 if (TRUE == enter_standby)
5722 {
5723 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5724 "entering standby", __func__);
5725 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5726 {
5727 /*log and return success*/
5728 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5729 "wlan in power save", __func__);
5730 }
5731 }
5732
5733 EXIT();
5734 return 0;
5735}
5736
5737/**---------------------------------------------------------------------------
5738
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305739 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005740
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305741 This is called in response to ifconfig down
5742
5743 \param - dev Pointer to net_device structure
5744
5745 \return - 0 for success non-zero for failure
5746-----------------------------------------------------------------------------*/
5747int hdd_stop (struct net_device *dev)
5748{
5749 int ret;
5750
5751 vos_ssr_protect(__func__);
5752 ret = __hdd_stop(dev);
5753 vos_ssr_unprotect(__func__);
5754
5755 return ret;
5756}
5757
5758/**---------------------------------------------------------------------------
5759
5760 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005761
5762 \param - dev Pointer to net_device structure
5763
5764 \return - void
5765
5766 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305767static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005768{
5769 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305770 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005771 ENTER();
5772
5773 do
5774 {
5775 if (NULL == pAdapter)
5776 {
5777 hddLog(VOS_TRACE_LEVEL_FATAL,
5778 "%s: NULL pAdapter", __func__);
5779 break;
5780 }
5781
5782 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5783 {
5784 hddLog(VOS_TRACE_LEVEL_FATAL,
5785 "%s: Invalid magic", __func__);
5786 break;
5787 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305788 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5789 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005790 {
5791 hddLog(VOS_TRACE_LEVEL_FATAL,
5792 "%s: NULL pHddCtx", __func__);
5793 break;
5794 }
5795
5796 if (dev != pAdapter->dev)
5797 {
5798 hddLog(VOS_TRACE_LEVEL_FATAL,
5799 "%s: Invalid device reference", __func__);
5800 /* we haven't validated all cases so let this go for now */
5801 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305802#ifdef FEATURE_WLAN_TDLS
5803 mutex_lock(&pHddCtx->tdls_lock);
5804#endif
c_hpothu002231a2015-02-05 14:58:51 +05305805 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305806#ifdef FEATURE_WLAN_TDLS
5807 mutex_unlock(&pHddCtx->tdls_lock);
5808#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005809
5810 /* after uninit our adapter structure will no longer be valid */
5811 pAdapter->dev = NULL;
5812 pAdapter->magic = 0;
5813 } while (0);
5814
5815 EXIT();
5816}
5817
5818/**---------------------------------------------------------------------------
5819
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305820 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5821
5822 This is called during the netdev unregister to uninitialize all data
5823associated with the device
5824
5825 \param - dev Pointer to net_device structure
5826
5827 \return - void
5828
5829 --------------------------------------------------------------------------*/
5830static void hdd_uninit (struct net_device *dev)
5831{
5832 vos_ssr_protect(__func__);
5833 __hdd_uninit(dev);
5834 vos_ssr_unprotect(__func__);
5835}
5836
5837/**---------------------------------------------------------------------------
5838
Jeff Johnson295189b2012-06-20 16:38:30 -07005839 \brief hdd_release_firmware() -
5840
5841 This function calls the release firmware API to free the firmware buffer.
5842
5843 \param - pFileName Pointer to the File Name.
5844 pCtx - Pointer to the adapter .
5845
5846
5847 \return - 0 for success, non zero for failure
5848
5849 --------------------------------------------------------------------------*/
5850
5851VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5852{
5853 VOS_STATUS status = VOS_STATUS_SUCCESS;
5854 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5855 ENTER();
5856
5857
5858 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5859
5860 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5861
5862 if(pHddCtx->fw) {
5863 release_firmware(pHddCtx->fw);
5864 pHddCtx->fw = NULL;
5865 }
5866 else
5867 status = VOS_STATUS_E_FAILURE;
5868 }
5869 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5870 if(pHddCtx->nv) {
5871 release_firmware(pHddCtx->nv);
5872 pHddCtx->nv = NULL;
5873 }
5874 else
5875 status = VOS_STATUS_E_FAILURE;
5876
5877 }
5878
5879 EXIT();
5880 return status;
5881}
5882
5883/**---------------------------------------------------------------------------
5884
5885 \brief hdd_request_firmware() -
5886
5887 This function reads the firmware file using the request firmware
5888 API and returns the the firmware data and the firmware file size.
5889
5890 \param - pfileName - Pointer to the file name.
5891 - pCtx - Pointer to the adapter .
5892 - ppfw_data - Pointer to the pointer of the firmware data.
5893 - pSize - Pointer to the file size.
5894
5895 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5896
5897 --------------------------------------------------------------------------*/
5898
5899
5900VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5901{
5902 int status;
5903 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5904 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5905 ENTER();
5906
5907 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5908
5909 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5910
5911 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5912 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5913 __func__, pfileName);
5914 retval = VOS_STATUS_E_FAILURE;
5915 }
5916
5917 else {
5918 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5919 *pSize = pHddCtx->fw->size;
5920 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5921 __func__, *pSize);
5922 }
5923 }
5924 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5925
5926 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5927
5928 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5929 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5930 __func__, pfileName);
5931 retval = VOS_STATUS_E_FAILURE;
5932 }
5933
5934 else {
5935 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5936 *pSize = pHddCtx->nv->size;
5937 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5938 __func__, *pSize);
5939 }
5940 }
5941
5942 EXIT();
5943 return retval;
5944}
5945/**---------------------------------------------------------------------------
5946 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5947
5948 This is the function invoked by SME to inform the result of a full power
5949 request issued by HDD
5950
5951 \param - callbackcontext - Pointer to cookie
5952 status - result of request
5953
5954 \return - None
5955
5956--------------------------------------------------------------------------*/
5957void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5958{
5959 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5960
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005961 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005962 if(&pHddCtx->full_pwr_comp_var)
5963 {
5964 complete(&pHddCtx->full_pwr_comp_var);
5965 }
5966}
5967
5968/**---------------------------------------------------------------------------
5969
5970 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5971
5972 This is the function invoked by SME to inform the result of BMPS
5973 request issued by HDD
5974
5975 \param - callbackcontext - Pointer to cookie
5976 status - result of request
5977
5978 \return - None
5979
5980--------------------------------------------------------------------------*/
5981void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5982{
5983
5984 struct completion *completion_var = (struct completion*) callbackContext;
5985
Arif Hussain6d2a3322013-11-17 19:50:10 -08005986 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005987 if(completion_var != NULL)
5988 {
5989 complete(completion_var);
5990 }
5991}
5992
5993/**---------------------------------------------------------------------------
5994
5995 \brief hdd_get_cfg_file_size() -
5996
5997 This function reads the configuration file using the request firmware
5998 API and returns the configuration file size.
5999
6000 \param - pCtx - Pointer to the adapter .
6001 - pFileName - Pointer to the file name.
6002 - pBufSize - Pointer to the buffer size.
6003
6004 \return - 0 for success, non zero for failure
6005
6006 --------------------------------------------------------------------------*/
6007
6008VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
6009{
6010 int status;
6011 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
6012
6013 ENTER();
6014
6015 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
6016
6017 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
6018 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
6019 status = VOS_STATUS_E_FAILURE;
6020 }
6021 else {
6022 *pBufSize = pHddCtx->fw->size;
6023 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
6024 release_firmware(pHddCtx->fw);
6025 pHddCtx->fw = NULL;
6026 }
6027
6028 EXIT();
6029 return VOS_STATUS_SUCCESS;
6030}
6031
6032/**---------------------------------------------------------------------------
6033
6034 \brief hdd_read_cfg_file() -
6035
6036 This function reads the configuration file using the request firmware
6037 API and returns the cfg data and the buffer size of the configuration file.
6038
6039 \param - pCtx - Pointer to the adapter .
6040 - pFileName - Pointer to the file name.
6041 - pBuffer - Pointer to the data buffer.
6042 - pBufSize - Pointer to the buffer size.
6043
6044 \return - 0 for success, non zero for failure
6045
6046 --------------------------------------------------------------------------*/
6047
6048VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
6049 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
6050{
6051 int status;
6052 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
6053
6054 ENTER();
6055
6056 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
6057
6058 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
6059 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
6060 return VOS_STATUS_E_FAILURE;
6061 }
6062 else {
6063 if(*pBufSize != pHddCtx->fw->size) {
6064 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
6065 "file size", __func__);
6066 release_firmware(pHddCtx->fw);
6067 pHddCtx->fw = NULL;
6068 return VOS_STATUS_E_FAILURE;
6069 }
6070 else {
6071 if(pBuffer) {
6072 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
6073 }
6074 release_firmware(pHddCtx->fw);
6075 pHddCtx->fw = NULL;
6076 }
6077 }
6078
6079 EXIT();
6080
6081 return VOS_STATUS_SUCCESS;
6082}
6083
6084/**---------------------------------------------------------------------------
6085
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306086 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07006087
6088 This function sets the user specified mac address using
6089 the command ifconfig wlanX hw ether <mac adress>.
6090
6091 \param - dev - Pointer to the net device.
6092 - addr - Pointer to the sockaddr.
6093 \return - 0 for success, non zero for failure
6094
6095 --------------------------------------------------------------------------*/
6096
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306097static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07006098{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306099 hdd_adapter_t *pAdapter;
6100 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006101 struct sockaddr *psta_mac_addr = addr;
6102 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306103 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006104
6105 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306106 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6107 if (NULL == pAdapter)
6108 {
6109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6110 "%s: Adapter is NULL",__func__);
6111 return -EINVAL;
6112 }
6113 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6114 ret = wlan_hdd_validate_context(pHddCtx);
6115 if (0 != ret)
6116 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306117 return ret;
6118 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006119
6120 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07006121 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
6122
6123 EXIT();
6124 return halStatus;
6125}
6126
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306127/**---------------------------------------------------------------------------
6128
6129 \brief hdd_set_mac_address() -
6130
6131 Wrapper function to protect __hdd_set_mac_address() function from ssr
6132
6133 \param - dev - Pointer to the net device.
6134 - addr - Pointer to the sockaddr.
6135 \return - 0 for success, non zero for failure
6136
6137 --------------------------------------------------------------------------*/
6138static int hdd_set_mac_address(struct net_device *dev, void *addr)
6139{
6140 int ret;
6141
6142 vos_ssr_protect(__func__);
6143 ret = __hdd_set_mac_address(dev, addr);
6144 vos_ssr_unprotect(__func__);
6145
6146 return ret;
6147}
6148
Jeff Johnson295189b2012-06-20 16:38:30 -07006149tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
6150{
6151 int i;
6152 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6153 {
Abhishek Singheb183782014-02-06 13:37:21 +05306154 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006155 break;
6156 }
6157
6158 if( VOS_MAX_CONCURRENCY_PERSONA == i)
6159 return NULL;
6160
6161 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
6162 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
6163}
6164
6165void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
6166{
6167 int i;
6168 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6169 {
6170 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
6171 {
6172 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
6173 break;
6174 }
6175 }
6176 return;
6177}
6178
6179#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6180 static struct net_device_ops wlan_drv_ops = {
6181 .ndo_open = hdd_open,
6182 .ndo_stop = hdd_stop,
6183 .ndo_uninit = hdd_uninit,
6184 .ndo_start_xmit = hdd_hard_start_xmit,
6185 .ndo_tx_timeout = hdd_tx_timeout,
6186 .ndo_get_stats = hdd_stats,
6187 .ndo_do_ioctl = hdd_ioctl,
6188 .ndo_set_mac_address = hdd_set_mac_address,
6189 .ndo_select_queue = hdd_select_queue,
6190#ifdef WLAN_FEATURE_PACKET_FILTERING
6191#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
6192 .ndo_set_rx_mode = hdd_set_multicast_list,
6193#else
6194 .ndo_set_multicast_list = hdd_set_multicast_list,
6195#endif //LINUX_VERSION_CODE
6196#endif
6197 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006198 static struct net_device_ops wlan_mon_drv_ops = {
6199 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05306200 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07006201 .ndo_uninit = hdd_uninit,
6202 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6203 .ndo_tx_timeout = hdd_tx_timeout,
6204 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05306205 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07006206 .ndo_set_mac_address = hdd_set_mac_address,
6207 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306208
Jeff Johnson295189b2012-06-20 16:38:30 -07006209#endif
6210
6211void hdd_set_station_ops( struct net_device *pWlanDev )
6212{
6213#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006214 pWlanDev->netdev_ops = &wlan_drv_ops;
6215#else
6216 pWlanDev->open = hdd_open;
6217 pWlanDev->stop = hdd_stop;
6218 pWlanDev->uninit = hdd_uninit;
6219 pWlanDev->hard_start_xmit = NULL;
6220 pWlanDev->tx_timeout = hdd_tx_timeout;
6221 pWlanDev->get_stats = hdd_stats;
6222 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006223 pWlanDev->set_mac_address = hdd_set_mac_address;
6224#endif
6225}
6226
Katya Nigam1fd24402015-02-16 14:52:19 +05306227void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
6228{
6229 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6230 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
6231 #else
6232 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
6233 #endif
6234}
6235
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006236static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006237{
6238 struct net_device *pWlanDev = NULL;
6239 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006240 /*
6241 * cfg80211 initialization and registration....
6242 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05306243 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
6244#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
6245 NET_NAME_UNKNOWN,
6246#endif
6247 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07006248 if(pWlanDev != NULL)
6249 {
6250
6251 //Save the pointer to the net_device in the HDD adapter
6252 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6253
Jeff Johnson295189b2012-06-20 16:38:30 -07006254 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6255
6256 pAdapter->dev = pWlanDev;
6257 pAdapter->pHddCtx = pHddCtx;
6258 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306259 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006260
6261 init_completion(&pAdapter->session_open_comp_var);
6262 init_completion(&pAdapter->session_close_comp_var);
6263 init_completion(&pAdapter->disconnect_comp_var);
6264 init_completion(&pAdapter->linkup_event_var);
6265 init_completion(&pAdapter->cancel_rem_on_chan_var);
6266 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306267 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006268#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6269 init_completion(&pAdapter->offchannel_tx_event);
6270#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006271 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006272#ifdef FEATURE_WLAN_TDLS
6273 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006274 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006275 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306276 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006277#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006278 init_completion(&pHddCtx->mc_sus_event_var);
6279 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306280 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006281 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006282 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006283
Rajeev79dbe4c2013-10-05 11:03:42 +05306284#ifdef FEATURE_WLAN_BATCH_SCAN
6285 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6286 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6287 pAdapter->pBatchScanRsp = NULL;
6288 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006289 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006290 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306291 mutex_init(&pAdapter->hdd_batch_scan_lock);
6292#endif
6293
Jeff Johnson295189b2012-06-20 16:38:30 -07006294 pAdapter->isLinkUpSvcNeeded = FALSE;
6295 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6296 //Init the net_device structure
6297 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6298
6299 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6300 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6301 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6302 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6303
6304 hdd_set_station_ops( pAdapter->dev );
6305
6306 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006307 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6308 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6309 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006310 /* set pWlanDev's parent to underlying device */
6311 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006312
6313 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006314 }
6315
6316 return pAdapter;
6317}
6318
6319VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6320{
6321 struct net_device *pWlanDev = pAdapter->dev;
6322 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6323 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6324 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6325
6326 if( rtnl_lock_held )
6327 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006328 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006329 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6330 {
6331 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6332 return VOS_STATUS_E_FAILURE;
6333 }
6334 }
6335 if (register_netdevice(pWlanDev))
6336 {
6337 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6338 return VOS_STATUS_E_FAILURE;
6339 }
6340 }
6341 else
6342 {
6343 if(register_netdev(pWlanDev))
6344 {
6345 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6346 return VOS_STATUS_E_FAILURE;
6347 }
6348 }
6349 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6350
6351 return VOS_STATUS_SUCCESS;
6352}
6353
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006354static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006355{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006356 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006357
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006358 if (NULL == pAdapter)
6359 {
6360 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6361 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006362 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006363
6364 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6365 {
6366 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6367 return eHAL_STATUS_NOT_INITIALIZED;
6368 }
6369
6370 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6371
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006372#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006373 /* need to make sure all of our scheduled work has completed.
6374 * This callback is called from MC thread context, so it is safe to
6375 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006376 *
6377 * Even though this is called from MC thread context, if there is a faulty
6378 * work item in the system, that can hang this call forever. So flushing
6379 * this global work queue is not safe; and now we make sure that
6380 * individual work queues are stopped correctly. But the cancel work queue
6381 * is a GPL only API, so the proprietary version of the driver would still
6382 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006383 */
6384 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006385#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006386
6387 /* We can be blocked while waiting for scheduled work to be
6388 * flushed, and the adapter structure can potentially be freed, in
6389 * which case the magic will have been reset. So make sure the
6390 * magic is still good, and hence the adapter structure is still
6391 * valid, before signaling completion */
6392 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6393 {
6394 complete(&pAdapter->session_close_comp_var);
6395 }
6396
Jeff Johnson295189b2012-06-20 16:38:30 -07006397 return eHAL_STATUS_SUCCESS;
6398}
6399
6400VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6401{
6402 struct net_device *pWlanDev = pAdapter->dev;
6403 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6404 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6405 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6406 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306407 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006408
Nirav Shah7e3c8132015-06-22 23:51:42 +05306409 spin_lock_init( &pAdapter->sta_hash_lock);
6410 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
6411
Jeff Johnson295189b2012-06-20 16:38:30 -07006412 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006413 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006414 //Open a SME session for future operation
6415 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006416 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006417 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6418 {
6419 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006420 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006421 halStatus, halStatus );
6422 status = VOS_STATUS_E_FAILURE;
6423 goto error_sme_open;
6424 }
6425
6426 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306427 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006428 &pAdapter->session_open_comp_var,
6429 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306430 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006431 {
6432 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306433 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006434 status = VOS_STATUS_E_FAILURE;
6435 goto error_sme_open;
6436 }
6437
6438 // Register wireless extensions
6439 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6440 {
6441 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006442 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 halStatus, halStatus );
6444 status = VOS_STATUS_E_FAILURE;
6445 goto error_register_wext;
6446 }
Katya Nigam1fd24402015-02-16 14:52:19 +05306447
Jeff Johnson295189b2012-06-20 16:38:30 -07006448 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05306449 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6450 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6451 #else
6452 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6453 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006454
6455 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306456 hddLog(VOS_TRACE_LEVEL_INFO,
6457 "%s: Set HDD connState to eConnectionState_NotConnected",
6458 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006459 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6460
6461 //Set the default operation channel
6462 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6463
6464 /* Make the default Auth Type as OPEN*/
6465 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6466
6467 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6468 {
6469 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006470 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006471 status, status );
6472 goto error_init_txrx;
6473 }
6474
6475 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6476
6477 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6478 {
6479 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006480 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006481 status, status );
6482 goto error_wmm_init;
6483 }
6484
6485 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6486
6487 return VOS_STATUS_SUCCESS;
6488
6489error_wmm_init:
6490 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6491 hdd_deinit_tx_rx(pAdapter);
6492error_init_txrx:
6493 hdd_UnregisterWext(pWlanDev);
6494error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006495 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006496 {
6497 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006498 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
mukul sharmabab477d2015-06-11 17:14:55 +05306499 pAdapter->sessionId, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006500 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006501 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306502 unsigned long rc;
6503
Jeff Johnson295189b2012-06-20 16:38:30 -07006504 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306505 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006506 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006507 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306508 if (rc <= 0)
6509 hddLog(VOS_TRACE_LEVEL_ERROR,
6510 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006511 }
6512}
6513error_sme_open:
6514 return status;
6515}
6516
Jeff Johnson295189b2012-06-20 16:38:30 -07006517void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6518{
6519 hdd_cfg80211_state_t *cfgState;
6520
6521 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6522
6523 if( NULL != cfgState->buf )
6524 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306525 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006526 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6527 rc = wait_for_completion_interruptible_timeout(
6528 &pAdapter->tx_action_cnf_event,
6529 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306530 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006531 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05306532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6533 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6534 , __func__, rc);
6535
6536 // Inform tx status as FAILURE to upper layer and free cfgState->buf
6537 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006538 }
6539 }
6540 return;
6541}
Jeff Johnson295189b2012-06-20 16:38:30 -07006542
c_hpothu002231a2015-02-05 14:58:51 +05306543void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006544{
6545 ENTER();
6546 switch ( pAdapter->device_mode )
6547 {
Katya Nigam1fd24402015-02-16 14:52:19 +05306548 case WLAN_HDD_IBSS:
6549 {
6550 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6551 {
6552 hdd_ibss_deinit_tx_rx( pAdapter );
6553 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6554 }
6555 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006556 case WLAN_HDD_INFRA_STATION:
6557 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006558 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006559 {
6560 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6561 {
6562 hdd_deinit_tx_rx( pAdapter );
6563 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6564 }
6565
6566 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6567 {
6568 hdd_wmm_adapter_close( pAdapter );
6569 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6570 }
6571
Jeff Johnson295189b2012-06-20 16:38:30 -07006572 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006573 break;
6574 }
6575
6576 case WLAN_HDD_SOFTAP:
6577 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006578 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306579
6580 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6581 {
6582 hdd_wmm_adapter_close( pAdapter );
6583 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6584 }
6585
Jeff Johnson295189b2012-06-20 16:38:30 -07006586 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006587
c_hpothu002231a2015-02-05 14:58:51 +05306588 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006589 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006590 break;
6591 }
6592
6593 case WLAN_HDD_MONITOR:
6594 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006595 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6596 {
6597 hdd_deinit_tx_rx( pAdapter );
6598 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6599 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006600 break;
6601 }
6602
6603
6604 default:
6605 break;
6606 }
6607
6608 EXIT();
6609}
6610
6611void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6612{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006613 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306614
6615 ENTER();
6616 if (NULL == pAdapter)
6617 {
6618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6619 "%s: HDD adapter is Null", __func__);
6620 return;
6621 }
6622
6623 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006624
Rajeev79dbe4c2013-10-05 11:03:42 +05306625#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306626 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6627 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006628 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306629 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6630 )
6631 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006632 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306633 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006634 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6635 {
6636 hdd_deinit_batch_scan(pAdapter);
6637 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306638 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006639 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306640#endif
6641
Jeff Johnson295189b2012-06-20 16:38:30 -07006642 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6643 if( rtnl_held )
6644 {
6645 unregister_netdevice(pWlanDev);
6646 }
6647 else
6648 {
6649 unregister_netdev(pWlanDev);
6650 }
6651 // note that the pAdapter is no longer valid at this point
6652 // since the memory has been reclaimed
6653 }
6654
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306655 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006656}
6657
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006658void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6659{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306660 VOS_STATUS status;
6661 hdd_adapter_t *pAdapter = NULL;
6662 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006663
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306664 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006665
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306666 /*loop through all adapters.*/
6667 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006668 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306669 pAdapter = pAdapterNode->pAdapter;
6670 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6671 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006672
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306673 { // we skip this registration for modes other than STA and P2P client modes.
6674 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6675 pAdapterNode = pNext;
6676 continue;
6677 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006678
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306679 //Apply Dynamic DTIM For P2P
6680 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6681 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6682 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6683 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6684 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6685 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6686 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6687 (eConnectionState_Associated ==
6688 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6689 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6690 {
6691 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006692
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306693 powerRequest.uIgnoreDTIM = 1;
6694 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6695
6696 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6697 {
6698 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6699 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6700 }
6701 else
6702 {
6703 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6704 }
6705
6706 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6707 * specified during Enter/Exit BMPS when LCD off*/
6708 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6709 NULL, eANI_BOOLEAN_FALSE);
6710 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6711 NULL, eANI_BOOLEAN_FALSE);
6712
6713 /* switch to the DTIM specified in cfg.ini */
6714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6715 "Switch to DTIM %d", powerRequest.uListenInterval);
6716 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6717 break;
6718
6719 }
6720
6721 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6722 pAdapterNode = pNext;
6723 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006724}
6725
6726void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6727{
6728 /*Switch back to DTIM 1*/
6729 tSirSetPowerParamsReq powerRequest = { 0 };
6730
6731 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6732 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006733 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006734
6735 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6736 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6737 NULL, eANI_BOOLEAN_FALSE);
6738 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6739 NULL, eANI_BOOLEAN_FALSE);
6740
6741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6742 "Switch to DTIM%d",powerRequest.uListenInterval);
6743 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6744
6745}
6746
Jeff Johnson295189b2012-06-20 16:38:30 -07006747VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6748{
6749 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306750 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6751 {
6752 hddLog( LOGE, FL("Wlan Unload in progress"));
6753 return VOS_STATUS_E_PERM;
6754 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006755 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6756 {
6757 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6758 }
6759
6760 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6761 {
6762 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6763 }
6764
6765 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6766 {
6767 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6768 }
6769
6770 return status;
6771}
6772
6773VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6774{
6775 hdd_adapter_t *pAdapter = NULL;
6776 eHalStatus halStatus;
6777 VOS_STATUS status = VOS_STATUS_E_INVAL;
6778 v_BOOL_t disableBmps = FALSE;
6779 v_BOOL_t disableImps = FALSE;
6780
6781 switch(session_type)
6782 {
6783 case WLAN_HDD_INFRA_STATION:
6784 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006785 case WLAN_HDD_P2P_CLIENT:
6786 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006787 //Exit BMPS -> Is Sta/P2P Client is already connected
6788 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6789 if((NULL != pAdapter)&&
6790 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6791 {
6792 disableBmps = TRUE;
6793 }
6794
6795 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6796 if((NULL != pAdapter)&&
6797 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6798 {
6799 disableBmps = TRUE;
6800 }
6801
6802 //Exit both Bmps and Imps incase of Go/SAP Mode
6803 if((WLAN_HDD_SOFTAP == session_type) ||
6804 (WLAN_HDD_P2P_GO == session_type))
6805 {
6806 disableBmps = TRUE;
6807 disableImps = TRUE;
6808 }
6809
6810 if(TRUE == disableImps)
6811 {
6812 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6813 {
6814 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6815 }
6816 }
6817
6818 if(TRUE == disableBmps)
6819 {
6820 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6821 {
6822 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6823
6824 if(eHAL_STATUS_SUCCESS != halStatus)
6825 {
6826 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006827 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006828 VOS_ASSERT(0);
6829 return status;
6830 }
6831 }
6832
6833 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6834 {
6835 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6836
6837 if(eHAL_STATUS_SUCCESS != halStatus)
6838 {
6839 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006840 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006841 VOS_ASSERT(0);
6842 return status;
6843 }
6844 }
6845 }
6846
6847 if((TRUE == disableBmps) ||
6848 (TRUE == disableImps))
6849 {
6850 /* Now, get the chip into Full Power now */
6851 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6852 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6853 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6854
6855 if(halStatus != eHAL_STATUS_SUCCESS)
6856 {
6857 if(halStatus == eHAL_STATUS_PMC_PENDING)
6858 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306859 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006860 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306861 ret = wait_for_completion_interruptible_timeout(
6862 &pHddCtx->full_pwr_comp_var,
6863 msecs_to_jiffies(1000));
6864 if (ret <= 0)
6865 {
6866 hddLog(VOS_TRACE_LEVEL_ERROR,
6867 "%s: wait on full_pwr_comp_var failed %ld",
6868 __func__, ret);
6869 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006870 }
6871 else
6872 {
6873 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006874 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006875 VOS_ASSERT(0);
6876 return status;
6877 }
6878 }
6879
6880 status = VOS_STATUS_SUCCESS;
6881 }
6882
6883 break;
6884 }
6885 return status;
6886}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05306887
6888void hdd_monPostMsgCb(tANI_U32 *magic, struct completion *cmpVar)
6889{
6890 if (magic == NULL || cmpVar == NULL) {
6891 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6892 FL("invalid arguments %p %p"), magic, cmpVar);
6893 return;
6894 }
6895 if (*magic != MON_MODE_MSG_MAGIC) {
6896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6897 FL("maic: %x"), *magic);
6898 return;
6899 }
6900
6901 complete(cmpVar);
6902 return;
6903}
6904
Katya Nigame7b69a82015-04-28 15:24:06 +05306905void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
6906 {
6907 hdd_mon_ctx_t *pMonCtx = NULL;
6908 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
6909
6910 pMonCtx->state = 0;
6911 pMonCtx->ChannelNo = 1;
6912 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05306913 pMonCtx->crcCheckEnabled = 1;
6914 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
6915 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05306916 pMonCtx->numOfMacFilters = 0;
6917 }
6918
Jeff Johnson295189b2012-06-20 16:38:30 -07006919
6920hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006921 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006922 tANI_U8 rtnl_held )
6923{
6924 hdd_adapter_t *pAdapter = NULL;
6925 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6926 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6927 VOS_STATUS exitbmpsStatus;
6928
Arif Hussain6d2a3322013-11-17 19:50:10 -08006929 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006930
Nirav Shah436658f2014-02-28 17:05:45 +05306931 if(macAddr == NULL)
6932 {
6933 /* Not received valid macAddr */
6934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6935 "%s:Unable to add virtual intf: Not able to get"
6936 "valid mac address",__func__);
6937 return NULL;
6938 }
6939
Jeff Johnson295189b2012-06-20 16:38:30 -07006940 //Disable BMPS incase of Concurrency
6941 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6942
6943 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6944 {
6945 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306946 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006947 VOS_ASSERT(0);
6948 return NULL;
6949 }
6950
6951 switch(session_type)
6952 {
6953 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006954 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006955 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006956 {
6957 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6958
6959 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306960 {
6961 hddLog(VOS_TRACE_LEVEL_FATAL,
6962 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006963 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306964 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006965
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306966#ifdef FEATURE_WLAN_TDLS
6967 /* A Mutex Lock is introduced while changing/initializing the mode to
6968 * protect the concurrent access for the Adapters by TDLS module.
6969 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306970 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306971#endif
6972
Jeff Johnsone7245742012-09-05 17:12:55 -07006973 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6974 NL80211_IFTYPE_P2P_CLIENT:
6975 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006976
Jeff Johnson295189b2012-06-20 16:38:30 -07006977 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306978#ifdef FEATURE_WLAN_TDLS
6979 mutex_unlock(&pHddCtx->tdls_lock);
6980#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306981
6982 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006983 if( VOS_STATUS_SUCCESS != status )
6984 goto err_free_netdev;
6985
6986 status = hdd_register_interface( pAdapter, rtnl_held );
6987 if( VOS_STATUS_SUCCESS != status )
6988 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306989#ifdef FEATURE_WLAN_TDLS
6990 mutex_lock(&pHddCtx->tdls_lock);
6991#endif
c_hpothu002231a2015-02-05 14:58:51 +05306992 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306993#ifdef FEATURE_WLAN_TDLS
6994 mutex_unlock(&pHddCtx->tdls_lock);
6995#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006996 goto err_free_netdev;
6997 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306998
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306999 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307000 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05307001
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307002#ifdef WLAN_NS_OFFLOAD
7003 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307004 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307005#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007006 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307007 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007008 netif_tx_disable(pAdapter->dev);
7009 //netif_tx_disable(pWlanDev);
7010 netif_carrier_off(pAdapter->dev);
7011
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307012 if (WLAN_HDD_P2P_CLIENT == session_type ||
7013 WLAN_HDD_P2P_DEVICE == session_type)
7014 {
7015 /* Initialize the work queue to defer the
7016 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307017 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307018 hdd_p2p_roc_work_queue);
7019 }
7020
Jeff Johnson295189b2012-06-20 16:38:30 -07007021 break;
7022 }
7023
Jeff Johnson295189b2012-06-20 16:38:30 -07007024 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007025 case WLAN_HDD_SOFTAP:
7026 {
7027 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
7028 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307029 {
7030 hddLog(VOS_TRACE_LEVEL_FATAL,
7031 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007032 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307033 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007034
Jeff Johnson295189b2012-06-20 16:38:30 -07007035 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
7036 NL80211_IFTYPE_AP:
7037 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007038 pAdapter->device_mode = session_type;
7039
7040 status = hdd_init_ap_mode(pAdapter);
7041 if( VOS_STATUS_SUCCESS != status )
7042 goto err_free_netdev;
7043
Nirav Shah7e3c8132015-06-22 23:51:42 +05307044 status = hdd_sta_id_hash_attach(pAdapter);
7045 if (VOS_STATUS_SUCCESS != status)
7046 {
7047 hddLog(VOS_TRACE_LEVEL_FATAL,
7048 FL("failed to attach hash for session %d"), session_type);
7049 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
7050 goto err_free_netdev;
7051 }
7052
Jeff Johnson295189b2012-06-20 16:38:30 -07007053 status = hdd_register_hostapd( pAdapter, rtnl_held );
7054 if( VOS_STATUS_SUCCESS != status )
7055 {
c_hpothu002231a2015-02-05 14:58:51 +05307056 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07007057 goto err_free_netdev;
7058 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307059 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007060 netif_tx_disable(pAdapter->dev);
7061 netif_carrier_off(pAdapter->dev);
7062
7063 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307064
7065 if (WLAN_HDD_P2P_GO == session_type)
7066 {
7067 /* Initialize the work queue to
7068 * defer the back to back RoC request */
7069 INIT_DELAYED_WORK(&pAdapter->roc_work,
7070 hdd_p2p_roc_work_queue);
7071 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007072 break;
7073 }
7074 case WLAN_HDD_MONITOR:
7075 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007076 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7077 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307078 {
7079 hddLog(VOS_TRACE_LEVEL_FATAL,
7080 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007081 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307082 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007083
Katya Nigame7b69a82015-04-28 15:24:06 +05307084 // Register wireless extensions
7085 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
7086 {
7087 hddLog(VOS_TRACE_LEVEL_FATAL,
7088 "hdd_register_wext() failed with status code %08d [x%08x]",
7089 status, status );
7090 status = VOS_STATUS_E_FAILURE;
7091 }
7092
Jeff Johnson295189b2012-06-20 16:38:30 -07007093 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
7094 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007095#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
7096 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
7097#else
7098 pAdapter->dev->open = hdd_mon_open;
7099 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05307100 pAdapter->dev->stop = hdd_mon_stop;
7101 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07007102#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05307103 status = hdd_register_interface( pAdapter, rtnl_held );
7104 hdd_init_mon_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007105 hdd_init_tx_rx( pAdapter );
7106 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05307107 //Stop the Interface TX queue.
7108 netif_tx_disable(pAdapter->dev);
7109 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007110 }
7111 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007112 case WLAN_HDD_FTM:
7113 {
7114 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7115
7116 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307117 {
7118 hddLog(VOS_TRACE_LEVEL_FATAL,
7119 FL("failed to allocate adapter for session %d"), session_type);
7120 return NULL;
7121 }
7122
Jeff Johnson295189b2012-06-20 16:38:30 -07007123 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
7124 * message while loading driver in FTM mode. */
7125 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
7126 pAdapter->device_mode = session_type;
7127 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307128
7129 hdd_init_tx_rx( pAdapter );
7130
7131 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307132 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307133 netif_tx_disable(pAdapter->dev);
7134 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007135 }
7136 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007137 default:
7138 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307139 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
7140 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007141 VOS_ASSERT(0);
7142 return NULL;
7143 }
7144 }
7145
Jeff Johnson295189b2012-06-20 16:38:30 -07007146 if( VOS_STATUS_SUCCESS == status )
7147 {
7148 //Add it to the hdd's session list.
7149 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
7150 if( NULL == pHddAdapterNode )
7151 {
7152 status = VOS_STATUS_E_NOMEM;
7153 }
7154 else
7155 {
7156 pHddAdapterNode->pAdapter = pAdapter;
7157 status = hdd_add_adapter_back ( pHddCtx,
7158 pHddAdapterNode );
7159 }
7160 }
7161
7162 if( VOS_STATUS_SUCCESS != status )
7163 {
7164 if( NULL != pAdapter )
7165 {
7166 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
7167 pAdapter = NULL;
7168 }
7169 if( NULL != pHddAdapterNode )
7170 {
7171 vos_mem_free( pHddAdapterNode );
7172 }
7173
7174 goto resume_bmps;
7175 }
7176
7177 if(VOS_STATUS_SUCCESS == status)
7178 {
7179 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
7180
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07007181 //Initialize the WoWL service
7182 if(!hdd_init_wowl(pAdapter))
7183 {
7184 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
7185 goto err_free_netdev;
7186 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007187 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007188 return pAdapter;
7189
7190err_free_netdev:
7191 free_netdev(pAdapter->dev);
7192 wlan_hdd_release_intf_addr( pHddCtx,
7193 pAdapter->macAddressCurrent.bytes );
7194
7195resume_bmps:
7196 //If bmps disabled enable it
7197 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
7198 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307199 if (pHddCtx->hdd_wlan_suspended)
7200 {
7201 hdd_set_pwrparams(pHddCtx);
7202 }
7203 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007204 }
7205 return NULL;
7206}
7207
7208VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7209 tANI_U8 rtnl_held )
7210{
7211 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
7212 VOS_STATUS status;
7213
7214 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
7215 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307216 {
7217 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
7218 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007219 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307220 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007221
7222 while ( pCurrent->pAdapter != pAdapter )
7223 {
7224 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
7225 if( VOS_STATUS_SUCCESS != status )
7226 break;
7227
7228 pCurrent = pNext;
7229 }
7230 pAdapterNode = pCurrent;
7231 if( VOS_STATUS_SUCCESS == status )
7232 {
7233 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7234 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307235
7236#ifdef FEATURE_WLAN_TDLS
7237
7238 /* A Mutex Lock is introduced while changing/initializing the mode to
7239 * protect the concurrent access for the Adapters by TDLS module.
7240 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307241 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307242#endif
7243
Jeff Johnson295189b2012-06-20 16:38:30 -07007244 hdd_remove_adapter( pHddCtx, pAdapterNode );
7245 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007246 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007247
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307248#ifdef FEATURE_WLAN_TDLS
7249 mutex_unlock(&pHddCtx->tdls_lock);
7250#endif
7251
Jeff Johnson295189b2012-06-20 16:38:30 -07007252
7253 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307254 if ((!vos_concurrent_open_sessions_running()) &&
7255 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7256 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007257 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307258 if (pHddCtx->hdd_wlan_suspended)
7259 {
7260 hdd_set_pwrparams(pHddCtx);
7261 }
7262 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007263 }
7264
7265 return VOS_STATUS_SUCCESS;
7266 }
7267
7268 return VOS_STATUS_E_FAILURE;
7269}
7270
7271VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7272{
7273 hdd_adapter_list_node_t *pHddAdapterNode;
7274 VOS_STATUS status;
7275
7276 ENTER();
7277
7278 do
7279 {
7280 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7281 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7282 {
7283 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7284 vos_mem_free( pHddAdapterNode );
7285 }
7286 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7287
7288 EXIT();
7289
7290 return VOS_STATUS_SUCCESS;
7291}
7292
7293void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7294{
7295 v_U8_t addIE[1] = {0};
7296
7297 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7298 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7299 eANI_BOOLEAN_FALSE) )
7300 {
7301 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007302 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007303 }
7304
7305 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7306 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7307 eANI_BOOLEAN_FALSE) )
7308 {
7309 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007310 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007311 }
7312
7313 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7314 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7315 eANI_BOOLEAN_FALSE) )
7316 {
7317 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007318 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007319 }
7320}
7321
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307322VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7323 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007324{
7325 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7326 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307327 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007328 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307329 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307330 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05307331 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007332
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307333 if (pHddCtx->isLogpInProgress) {
7334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7335 "%s:LOGP in Progress. Ignore!!!",__func__);
7336 return VOS_STATUS_E_FAILURE;
7337 }
7338
Jeff Johnson295189b2012-06-20 16:38:30 -07007339 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307340
Bhargav Shah784e6a52015-07-22 16:52:35 +05307341 if ( VOS_TRUE == bCloseSession )
7342 {
7343 status = hdd_sta_id_hash_detach(pAdapter);
7344 if (status != VOS_STATUS_SUCCESS)
7345 hddLog(VOS_TRACE_LEVEL_ERROR,
7346 FL("sta id hash detach failed"));
7347 }
Nirav Shah7e3c8132015-06-22 23:51:42 +05307348
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307349 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007350 switch(pAdapter->device_mode)
7351 {
7352 case WLAN_HDD_INFRA_STATION:
7353 case WLAN_HDD_P2P_CLIENT:
Abhishek Singh3ac179b2015-09-21 10:01:34 +05307354 case WLAN_HDD_IBSS:
Jeff Johnsone7245742012-09-05 17:12:55 -07007355 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307356 {
7357 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05307358#ifdef FEATURE_WLAN_TDLS
7359 mutex_lock(&pHddCtx->tdls_lock);
7360 wlan_hdd_tdls_exit(pAdapter, TRUE);
7361 mutex_unlock(&pHddCtx->tdls_lock);
7362#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307363 if( hdd_connIsConnected(pstation) ||
7364 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007365 {
7366 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7367 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7368 pAdapter->sessionId,
7369 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7370 else
7371 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7372 pAdapter->sessionId,
7373 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7374 //success implies disconnect command got queued up successfully
7375 if(halStatus == eHAL_STATUS_SUCCESS)
7376 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307377 ret = wait_for_completion_interruptible_timeout(
7378 &pAdapter->disconnect_comp_var,
7379 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7380 if (ret <= 0)
7381 {
7382 hddLog(VOS_TRACE_LEVEL_ERROR,
7383 "%s: wait on disconnect_comp_var failed %ld",
7384 __func__, ret);
7385 }
7386 }
7387 else
7388 {
7389 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7390 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007391 }
7392 memset(&wrqu, '\0', sizeof(wrqu));
7393 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7394 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7395 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7396 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307397 else if(pstation->conn_info.connState ==
7398 eConnectionState_Disconnecting)
7399 {
7400 ret = wait_for_completion_interruptible_timeout(
7401 &pAdapter->disconnect_comp_var,
7402 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7403 if (ret <= 0)
7404 {
7405 hddLog(VOS_TRACE_LEVEL_ERROR,
7406 FL("wait on disconnect_comp_var failed %ld"), ret);
7407 }
7408 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307409 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007410 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307411 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307412 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007413 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +05307414 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
7415 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307416 {
7417 while (pAdapter->is_roc_inprogress)
7418 {
7419 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7420 "%s: ROC in progress for session %d!!!",
7421 __func__, pAdapter->sessionId);
7422 // waiting for ROC to expire
7423 msleep(500);
7424 /* In GO present case , if retry exceeds 3,
7425 it means something went wrong. */
7426 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7427 {
7428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7429 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307430 if (eHAL_STATUS_SUCCESS !=
7431 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7432 pAdapter->sessionId ))
7433 {
7434 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7435 FL("Failed to Cancel Remain on Channel"));
7436 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307437 wait_for_completion_interruptible_timeout(
7438 &pAdapter->cancel_rem_on_chan_var,
7439 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7440 break;
7441 }
7442 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307443 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307444 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307445#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307446 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307447#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307448
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307449 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307450
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307451 /* It is possible that the caller of this function does not
7452 * wish to close the session
7453 */
7454 if (VOS_TRUE == bCloseSession &&
7455 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007456 {
7457 INIT_COMPLETION(pAdapter->session_close_comp_var);
7458 if (eHAL_STATUS_SUCCESS ==
mukul sharmabab477d2015-06-11 17:14:55 +05307459 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, VOS_FALSE,
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307460 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007461 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307462 unsigned long ret;
7463
Jeff Johnson295189b2012-06-20 16:38:30 -07007464 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307465 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307466 &pAdapter->session_close_comp_var,
7467 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307468 if ( 0 >= ret)
7469 {
7470 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307471 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307472 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007473 }
7474 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307475 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007476 break;
7477
7478 case WLAN_HDD_SOFTAP:
7479 case WLAN_HDD_P2P_GO:
7480 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307481 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7482 while (pAdapter->is_roc_inprogress) {
7483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7484 "%s: ROC in progress for session %d!!!",
7485 __func__, pAdapter->sessionId);
7486 msleep(500);
7487 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7489 "%s: ROC completion is not received.!!!", __func__);
7490 WLANSAP_CancelRemainOnChannel(
7491 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7492 wait_for_completion_interruptible_timeout(
7493 &pAdapter->cancel_rem_on_chan_var,
7494 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7495 break;
7496 }
7497 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307498
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307499 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307500 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007501 mutex_lock(&pHddCtx->sap_lock);
7502 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7503 {
7504 VOS_STATUS status;
7505 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7506
7507 //Stop Bss.
7508 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7509 if (VOS_IS_STATUS_SUCCESS(status))
7510 {
7511 hdd_hostapd_state_t *pHostapdState =
7512 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7513
7514 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7515
7516 if (!VOS_IS_STATUS_SUCCESS(status))
7517 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307518 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7519 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007520 }
7521 }
7522 else
7523 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007524 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007525 }
7526 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307527 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007528
7529 if (eHAL_STATUS_FAILURE ==
7530 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7531 0, NULL, eANI_BOOLEAN_FALSE))
7532 {
7533 hddLog(LOGE,
7534 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007535 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007536 }
7537
7538 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7539 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7540 eANI_BOOLEAN_FALSE) )
7541 {
7542 hddLog(LOGE,
7543 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7544 }
7545
7546 // Reset WNI_CFG_PROBE_RSP Flags
7547 wlan_hdd_reset_prob_rspies(pAdapter);
7548 kfree(pAdapter->sessionCtx.ap.beacon);
7549 pAdapter->sessionCtx.ap.beacon = NULL;
7550 }
7551 mutex_unlock(&pHddCtx->sap_lock);
7552 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007553
Jeff Johnson295189b2012-06-20 16:38:30 -07007554 case WLAN_HDD_MONITOR:
7555 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007556
Jeff Johnson295189b2012-06-20 16:38:30 -07007557 default:
7558 break;
7559 }
7560
7561 EXIT();
7562 return VOS_STATUS_SUCCESS;
7563}
7564
7565VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7566{
7567 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7568 VOS_STATUS status;
7569 hdd_adapter_t *pAdapter;
7570
7571 ENTER();
7572
7573 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7574
7575 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7576 {
7577 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007578
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307579 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007580
7581 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7582 pAdapterNode = pNext;
7583 }
7584
7585 EXIT();
7586
7587 return VOS_STATUS_SUCCESS;
7588}
7589
Rajeev Kumarf999e582014-01-09 17:33:29 -08007590
7591#ifdef FEATURE_WLAN_BATCH_SCAN
7592/**---------------------------------------------------------------------------
7593
7594 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7595 structures
7596
7597 \param - pAdapter Pointer to HDD adapter
7598
7599 \return - None
7600
7601 --------------------------------------------------------------------------*/
7602void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7603{
7604 tHddBatchScanRsp *pNode;
7605 tHddBatchScanRsp *pPrev;
7606
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307607 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007608 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307609 hddLog(VOS_TRACE_LEVEL_ERROR,
7610 "%s: Adapter context is Null", __func__);
7611 return;
7612 }
7613
7614 pNode = pAdapter->pBatchScanRsp;
7615 while (pNode)
7616 {
7617 pPrev = pNode;
7618 pNode = pNode->pNext;
7619 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007620 }
7621
7622 pAdapter->pBatchScanRsp = NULL;
7623 pAdapter->numScanList = 0;
7624 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7625 pAdapter->prev_batch_id = 0;
7626
7627 return;
7628}
7629#endif
7630
7631
Jeff Johnson295189b2012-06-20 16:38:30 -07007632VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7633{
7634 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7635 VOS_STATUS status;
7636 hdd_adapter_t *pAdapter;
7637
7638 ENTER();
7639
7640 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7641
7642 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7643 {
7644 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307645 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007646 netif_tx_disable(pAdapter->dev);
7647 netif_carrier_off(pAdapter->dev);
7648
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007649 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7650
Jeff Johnson295189b2012-06-20 16:38:30 -07007651 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307652
Katya Nigam1fd24402015-02-16 14:52:19 +05307653 if(pAdapter->device_mode == WLAN_HDD_IBSS )
7654 hdd_ibss_deinit_tx_rx(pAdapter);
7655
Nirav Shah7e3c8132015-06-22 23:51:42 +05307656 status = hdd_sta_id_hash_detach(pAdapter);
7657 if (status != VOS_STATUS_SUCCESS)
7658 hddLog(VOS_TRACE_LEVEL_ERROR,
7659 FL("sta id hash detach failed for session id %d"),
7660 pAdapter->sessionId);
7661
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307662 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7663
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307664 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7665 {
7666 hdd_wmm_adapter_close( pAdapter );
7667 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7668 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007669
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307670 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7671 {
7672 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7673 }
7674
Rajeev Kumarf999e582014-01-09 17:33:29 -08007675#ifdef FEATURE_WLAN_BATCH_SCAN
7676 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7677 {
7678 hdd_deinit_batch_scan(pAdapter);
7679 }
7680#endif
7681
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307682#ifdef FEATURE_WLAN_TDLS
7683 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307684 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307685 mutex_unlock(&pHddCtx->tdls_lock);
7686#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007687 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7688 pAdapterNode = pNext;
7689 }
7690
7691 EXIT();
7692
7693 return VOS_STATUS_SUCCESS;
7694}
7695
7696VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7697{
7698 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7699 VOS_STATUS status;
7700 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307701 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007702
7703 ENTER();
7704
7705 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7706
7707 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7708 {
7709 pAdapter = pAdapterNode->pAdapter;
7710
Kumar Anand82c009f2014-05-29 00:29:42 -07007711 hdd_wmm_init( pAdapter );
7712
Jeff Johnson295189b2012-06-20 16:38:30 -07007713 switch(pAdapter->device_mode)
7714 {
7715 case WLAN_HDD_INFRA_STATION:
7716 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007717 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307718
7719 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7720
Jeff Johnson295189b2012-06-20 16:38:30 -07007721 hdd_init_station_mode(pAdapter);
7722 /* Open the gates for HDD to receive Wext commands */
7723 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007724 pHddCtx->scan_info.mScanPending = FALSE;
7725 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007726
7727 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +05307728 if (!pHddCtx->isLogpInProgress)
7729 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007730
7731 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307732 if (eConnectionState_Associated == connState ||
7733 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007734 {
7735 union iwreq_data wrqu;
7736 memset(&wrqu, '\0', sizeof(wrqu));
7737 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7738 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7739 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007740 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007741
Jeff Johnson295189b2012-06-20 16:38:30 -07007742 /* indicate disconnected event to nl80211 */
7743 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7744 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007745 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307746 else if (eConnectionState_Connecting == connState)
7747 {
7748 /*
7749 * Indicate connect failure to supplicant if we were in the
7750 * process of connecting
7751 */
7752 cfg80211_connect_result(pAdapter->dev, NULL,
7753 NULL, 0, NULL, 0,
7754 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7755 GFP_KERNEL);
7756 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007757 break;
7758
7759 case WLAN_HDD_SOFTAP:
7760 /* softAP can handle SSR */
7761 break;
7762
7763 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007764 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007765 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007766 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007767 break;
7768
7769 case WLAN_HDD_MONITOR:
7770 /* monitor interface start */
7771 break;
7772 default:
7773 break;
7774 }
7775
7776 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7777 pAdapterNode = pNext;
7778 }
7779
7780 EXIT();
7781
7782 return VOS_STATUS_SUCCESS;
7783}
7784
7785VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7786{
7787 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7788 hdd_adapter_t *pAdapter;
7789 VOS_STATUS status;
7790 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307791 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007792
7793 ENTER();
7794
7795 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7796
7797 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7798 {
7799 pAdapter = pAdapterNode->pAdapter;
7800
7801 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7802 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7803 {
7804 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7805 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7806
Abhishek Singhf4669da2014-05-26 15:07:49 +05307807 hddLog(VOS_TRACE_LEVEL_INFO,
7808 "%s: Set HDD connState to eConnectionState_NotConnected",
7809 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +05307810 spin_lock_bh(&pAdapter->lock_for_active_session);
7811 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
7812 {
7813 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7814 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007815 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +05307816 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07007817 init_completion(&pAdapter->disconnect_comp_var);
7818 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7819 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7820
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307821 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007822 &pAdapter->disconnect_comp_var,
7823 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307824 if (0 >= ret)
7825 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7826 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007827
7828 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7829 pHddCtx->isAmpAllowed = VOS_FALSE;
7830 sme_RoamConnect(pHddCtx->hHal,
7831 pAdapter->sessionId, &(pWextState->roamProfile),
7832 &roamId);
7833 }
7834
7835 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7836 pAdapterNode = pNext;
7837 }
7838
7839 EXIT();
7840
7841 return VOS_STATUS_SUCCESS;
7842}
7843
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007844void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7845{
7846 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7847 VOS_STATUS status;
7848 hdd_adapter_t *pAdapter;
7849 hdd_station_ctx_t *pHddStaCtx;
7850 hdd_ap_ctx_t *pHddApCtx;
7851 hdd_hostapd_state_t * pHostapdState;
7852 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7853 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7854 const char *p2pMode = "DEV";
7855 const char *ccMode = "Standalone";
7856 int n;
7857
7858 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7859 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7860 {
7861 pAdapter = pAdapterNode->pAdapter;
7862 switch (pAdapter->device_mode) {
7863 case WLAN_HDD_INFRA_STATION:
7864 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7865 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7866 staChannel = pHddStaCtx->conn_info.operationChannel;
7867 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7868 }
7869 break;
7870 case WLAN_HDD_P2P_CLIENT:
7871 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7872 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7873 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7874 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7875 p2pMode = "CLI";
7876 }
7877 break;
7878 case WLAN_HDD_P2P_GO:
7879 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7880 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7881 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7882 p2pChannel = pHddApCtx->operatingChannel;
7883 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7884 }
7885 p2pMode = "GO";
7886 break;
7887 case WLAN_HDD_SOFTAP:
7888 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7889 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7890 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7891 apChannel = pHddApCtx->operatingChannel;
7892 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7893 }
7894 break;
7895 default:
7896 break;
7897 }
7898 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7899 pAdapterNode = pNext;
7900 }
7901 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7902 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7903 }
7904 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7905 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7906 if (p2pChannel > 0) {
7907 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7908 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7909 }
7910 if (apChannel > 0) {
7911 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7912 apChannel, MAC_ADDR_ARRAY(apBssid));
7913 }
7914
7915 if (p2pChannel > 0 && apChannel > 0) {
7916 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7917 }
7918}
7919
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007920bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007921{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007922 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007923}
7924
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007925/* Once SSR is disabled then it cannot be set. */
7926void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007927{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007928 if (HDD_SSR_DISABLED == isSsrRequired)
7929 return;
7930
Jeff Johnson295189b2012-06-20 16:38:30 -07007931 isSsrRequired = value;
7932}
7933
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05307934void hdd_set_pre_close( hdd_context_t *pHddCtx)
7935{
7936 sme_PreClose(pHddCtx->hHal);
7937}
7938
Jeff Johnson295189b2012-06-20 16:38:30 -07007939VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7940 hdd_adapter_list_node_t** ppAdapterNode)
7941{
7942 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307943 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007944 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7945 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307946 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007947 return status;
7948}
7949
7950VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7951 hdd_adapter_list_node_t* pAdapterNode,
7952 hdd_adapter_list_node_t** pNextAdapterNode)
7953{
7954 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307955 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007956 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7957 (hdd_list_node_t*) pAdapterNode,
7958 (hdd_list_node_t**)pNextAdapterNode );
7959
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307960 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007961 return status;
7962}
7963
7964VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7965 hdd_adapter_list_node_t* pAdapterNode)
7966{
7967 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307968 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007969 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7970 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307971 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007972 return status;
7973}
7974
7975VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7976 hdd_adapter_list_node_t** ppAdapterNode)
7977{
7978 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307979 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007980 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7981 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307982 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007983 return status;
7984}
7985
7986VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7987 hdd_adapter_list_node_t* pAdapterNode)
7988{
7989 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307990 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007991 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7992 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307993 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007994 return status;
7995}
7996
7997VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7998 hdd_adapter_list_node_t* pAdapterNode)
7999{
8000 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308001 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008002 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
8003 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308004 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008005 return status;
8006}
8007
8008hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
8009 tSirMacAddr macAddr )
8010{
8011 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8012 hdd_adapter_t *pAdapter;
8013 VOS_STATUS status;
8014
8015 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8016
8017 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8018 {
8019 pAdapter = pAdapterNode->pAdapter;
8020
8021 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
8022 macAddr, sizeof(tSirMacAddr) ) )
8023 {
8024 return pAdapter;
8025 }
8026 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8027 pAdapterNode = pNext;
8028 }
8029
8030 return NULL;
8031
8032}
8033
8034hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
8035{
8036 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8037 hdd_adapter_t *pAdapter;
8038 VOS_STATUS status;
8039
8040 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8041
8042 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8043 {
8044 pAdapter = pAdapterNode->pAdapter;
8045
8046 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
8047 IFNAMSIZ ) )
8048 {
8049 return pAdapter;
8050 }
8051 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8052 pAdapterNode = pNext;
8053 }
8054
8055 return NULL;
8056
8057}
8058
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +05308059hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
8060 tANI_U32 sme_session_id )
8061{
8062 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8063 hdd_adapter_t *pAdapter;
8064 VOS_STATUS vos_status;
8065
8066
8067 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
8068
8069 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
8070 {
8071 pAdapter = pAdapterNode->pAdapter;
8072
8073 if (pAdapter->sessionId == sme_session_id)
8074 return pAdapter;
8075
8076 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
8077 pAdapterNode = pNext;
8078 }
8079
8080 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8081 "%s: sme_session_id %d does not exist with host",
8082 __func__, sme_session_id);
8083
8084 return NULL;
8085}
8086
Jeff Johnson295189b2012-06-20 16:38:30 -07008087hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
8088{
8089 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8090 hdd_adapter_t *pAdapter;
8091 VOS_STATUS status;
8092
8093 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8094
8095 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8096 {
8097 pAdapter = pAdapterNode->pAdapter;
8098
8099 if( pAdapter && (mode == pAdapter->device_mode) )
8100 {
8101 return pAdapter;
8102 }
8103 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8104 pAdapterNode = pNext;
8105 }
8106
8107 return NULL;
8108
8109}
8110
8111//Remove this function later
8112hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
8113{
8114 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8115 hdd_adapter_t *pAdapter;
8116 VOS_STATUS status;
8117
8118 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8119
8120 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8121 {
8122 pAdapter = pAdapterNode->pAdapter;
8123
8124 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
8125 {
8126 return pAdapter;
8127 }
8128
8129 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8130 pAdapterNode = pNext;
8131 }
8132
8133 return NULL;
8134
8135}
8136
Jeff Johnson295189b2012-06-20 16:38:30 -07008137/**---------------------------------------------------------------------------
8138
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308139 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008140
8141 This API returns the operating channel of the requested device mode
8142
8143 \param - pHddCtx - Pointer to the HDD context.
8144 - mode - Device mode for which operating channel is required
8145 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
8146 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
8147 \return - channel number. "0" id the requested device is not found OR it is not connected.
8148 --------------------------------------------------------------------------*/
8149v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
8150{
8151 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8152 VOS_STATUS status;
8153 hdd_adapter_t *pAdapter;
8154 v_U8_t operatingChannel = 0;
8155
8156 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8157
8158 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8159 {
8160 pAdapter = pAdapterNode->pAdapter;
8161
8162 if( mode == pAdapter->device_mode )
8163 {
8164 switch(pAdapter->device_mode)
8165 {
8166 case WLAN_HDD_INFRA_STATION:
8167 case WLAN_HDD_P2P_CLIENT:
8168 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
8169 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
8170 break;
8171 case WLAN_HDD_SOFTAP:
8172 case WLAN_HDD_P2P_GO:
8173 /*softap connection info */
8174 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8175 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
8176 break;
8177 default:
8178 break;
8179 }
8180
8181 break; //Found the device of interest. break the loop
8182 }
8183
8184 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8185 pAdapterNode = pNext;
8186 }
8187 return operatingChannel;
8188}
8189
8190#ifdef WLAN_FEATURE_PACKET_FILTERING
8191/**---------------------------------------------------------------------------
8192
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308193 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008194
8195 This used to set the multicast address list.
8196
8197 \param - dev - Pointer to the WLAN device.
8198 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308199 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07008200
8201 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308202static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008203{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308204 hdd_adapter_t *pAdapter;
8205 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008206 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308207 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008208 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308209
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308210 ENTER();
8211
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308212 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308213 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008214 {
8215 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308216 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008217 return;
8218 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308219 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8220 ret = wlan_hdd_validate_context(pHddCtx);
8221 if (0 != ret)
8222 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308223 return;
8224 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008225 if (dev->flags & IFF_ALLMULTI)
8226 {
8227 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008228 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308229 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008230 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308231 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008232 {
8233 mc_count = netdev_mc_count(dev);
8234 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008235 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07008236 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
8237 {
8238 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008239 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308240 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008241 return;
8242 }
8243
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308244 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07008245
8246 netdev_for_each_mc_addr(ha, dev) {
8247 if (i == mc_count)
8248 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308249 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
8250 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008251 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308252 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308253 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07008254 i++;
8255 }
8256 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308257
8258 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008259 return;
8260}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308261
8262static void hdd_set_multicast_list(struct net_device *dev)
8263{
8264 vos_ssr_protect(__func__);
8265 __hdd_set_multicast_list(dev);
8266 vos_ssr_unprotect(__func__);
8267}
Jeff Johnson295189b2012-06-20 16:38:30 -07008268#endif
8269
8270/**---------------------------------------------------------------------------
8271
8272 \brief hdd_select_queue() -
8273
8274 This function is registered with the Linux OS for network
8275 core to decide which queue to use first.
8276
8277 \param - dev - Pointer to the WLAN device.
8278 - skb - Pointer to OS packet (sk_buff).
8279 \return - ac, Queue Index/access category corresponding to UP in IP header
8280
8281 --------------------------------------------------------------------------*/
8282v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308283 struct sk_buff *skb
8284#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
8285 , void *accel_priv
8286#endif
8287#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8288 , select_queue_fallback_t fallback
8289#endif
8290)
Jeff Johnson295189b2012-06-20 16:38:30 -07008291{
8292 return hdd_wmm_select_queue(dev, skb);
8293}
8294
8295
8296/**---------------------------------------------------------------------------
8297
8298 \brief hdd_wlan_initial_scan() -
8299
8300 This function triggers the initial scan
8301
8302 \param - pAdapter - Pointer to the HDD adapter.
8303
8304 --------------------------------------------------------------------------*/
8305void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8306{
8307 tCsrScanRequest scanReq;
8308 tCsrChannelInfo channelInfo;
8309 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008310 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008311 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8312
8313 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8314 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8315 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8316
8317 if(sme_Is11dSupported(pHddCtx->hHal))
8318 {
8319 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8320 if ( HAL_STATUS_SUCCESS( halStatus ) )
8321 {
8322 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8323 if( !scanReq.ChannelInfo.ChannelList )
8324 {
8325 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8326 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008327 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008328 return;
8329 }
8330 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8331 channelInfo.numOfChannels);
8332 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8333 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008334 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008335 }
8336
8337 scanReq.scanType = eSIR_PASSIVE_SCAN;
8338 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8339 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8340 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8341 }
8342 else
8343 {
8344 scanReq.scanType = eSIR_ACTIVE_SCAN;
8345 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8346 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8347 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8348 }
8349
8350 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8351 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8352 {
8353 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8354 __func__, halStatus );
8355 }
8356
8357 if(sme_Is11dSupported(pHddCtx->hHal))
8358 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8359}
8360
mukul sharmabab477d2015-06-11 17:14:55 +05308361void hdd_purge_cmd_list_all_adapters( hdd_context_t *pHddCtx )
8362{
8363 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8364 VOS_STATUS status;
8365 hdd_adapter_t *pAdapter;
8366
8367 ENTER();
8368
8369 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8370
8371 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8372 {
8373 pAdapter = pAdapterNode->pAdapter;
8374
8375 status = sme_PurgeCmdList(pHddCtx->hHal, pAdapter->sessionId);
8376 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8377 pAdapterNode = pNext;
8378 }
8379
8380 EXIT();
8381}
Jeff Johnson295189b2012-06-20 16:38:30 -07008382/**---------------------------------------------------------------------------
8383
8384 \brief hdd_full_power_callback() - HDD full power callback function
8385
8386 This is the function invoked by SME to inform the result of a full power
8387 request issued by HDD
8388
8389 \param - callbackcontext - Pointer to cookie
8390 \param - status - result of request
8391
8392 \return - None
8393
8394 --------------------------------------------------------------------------*/
8395static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8396{
Jeff Johnson72a40512013-12-19 10:14:15 -08008397 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008398
8399 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308400 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008401
8402 if (NULL == callbackContext)
8403 {
8404 hddLog(VOS_TRACE_LEVEL_ERROR,
8405 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008406 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008407 return;
8408 }
8409
Jeff Johnson72a40512013-12-19 10:14:15 -08008410 /* there is a race condition that exists between this callback
8411 function and the caller since the caller could time out either
8412 before or while this code is executing. we use a spinlock to
8413 serialize these actions */
8414 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008415
8416 if (POWER_CONTEXT_MAGIC != pContext->magic)
8417 {
8418 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008419 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008420 hddLog(VOS_TRACE_LEVEL_WARN,
8421 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008422 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008423 return;
8424 }
8425
Jeff Johnson72a40512013-12-19 10:14:15 -08008426 /* context is valid so caller is still waiting */
8427
8428 /* paranoia: invalidate the magic */
8429 pContext->magic = 0;
8430
8431 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008432 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008433
8434 /* serialization is complete */
8435 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008436}
8437
Katya Nigamf0511f62015-05-05 16:40:57 +05308438void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
8439{
8440 pMonCtx->typeSubtypeBitmap = 0;
8441 if( type%10 ) /* Management Packets */
8442 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
8443 type/=10;
8444 if( type%10 ) /* Control Packets */
8445 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
8446 type/=10;
8447 if( type%10 ) /* Data Packets */
8448 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
8449}
8450
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308451VOS_STATUS wlan_hdd_mon_postMsg(tANI_U32 *magic, struct completion *cmpVar,
8452 hdd_mon_ctx_t *pMonCtx , void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +05308453{
8454 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308455 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +05308456
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308457 if (MON_MODE_START == pMonCtx->state)
8458 monMsg.type = WDA_MON_START_REQ;
8459 else if (MON_MODE_STOP == pMonCtx->state)
8460 monMsg.type = WDA_MON_STOP_REQ;
8461 else {
8462 hddLog(VOS_TRACE_LEVEL_ERROR,
8463 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +05308464 return VOS_STATUS_E_FAILURE;
8465 }
8466
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308467 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
8468 if (pMonModeReq == NULL) {
8469 hddLog(VOS_TRACE_LEVEL_ERROR,
8470 FL("fail to allocate memory for monitor mode req"));
8471 return VOS_STATUS_E_FAILURE;
8472 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308473
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308474 pMonModeReq->magic = magic;
8475 pMonModeReq->cmpVar = cmpVar;
8476 pMonModeReq->data = pMonCtx;
8477 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +05308478
Katya Nigamf0511f62015-05-05 16:40:57 +05308479 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308480 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +05308481 monMsg.bodyval = 0;
8482
8483 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8484 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8485 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308486 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +05308487 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308488 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +05308489}
8490
Katya Nigame7b69a82015-04-28 15:24:06 +05308491void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
8492{
8493 VOS_STATUS vosStatus;
8494 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308495 long ret;
8496 hdd_mon_ctx_t *pMonCtx = NULL;
8497 v_U32_t magic;
8498 struct completion cmpVar;
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +05308499
Katya Nigame7b69a82015-04-28 15:24:06 +05308500 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
8501 if(pAdapter == NULL || pVosContext == NULL)
8502 {
8503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
8504 return ;
8505 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308506
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308507 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
8508 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
8509 pMonCtx->state = MON_MODE_STOP;
8510 magic = MON_MODE_MSG_MAGIC;
8511 init_completion(&cmpVar);
8512 if (VOS_STATUS_SUCCESS !=
8513 wlan_hdd_mon_postMsg(&magic, &cmpVar,
8514 pMonCtx, hdd_monPostMsgCb)) {
8515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8516 FL("failed to post MON MODE REQ"));
8517 pMonCtx->state = MON_MODE_START;
8518 magic = 0;
8519 return;
8520 }
8521 ret = wait_for_completion_timeout(&cmpVar, MON_MODE_MSG_TIMEOUT);
8522 magic = 0;
8523 if (ret <= 0 ) {
8524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8525 FL("timeout on monitor mode completion %ld"), ret);
8526 }
8527 }
8528
Katya Nigame7b69a82015-04-28 15:24:06 +05308529 hdd_UnregisterWext(pAdapter->dev);
8530
8531 vos_mon_stop( pVosContext );
8532
8533 vosStatus = vos_sched_close( pVosContext );
8534 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8535 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8536 "%s: Failed to close VOSS Scheduler",__func__);
8537 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8538 }
8539
8540 vosStatus = vos_nv_close();
8541 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8542 {
8543 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8544 "%s: Failed to close NV", __func__);
8545 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8546 }
8547
8548 vos_close(pVosContext);
8549
8550 #ifdef WLAN_KD_READY_NOTIFIER
8551 nl_srv_exit(pHddCtx->ptt_pid);
8552 #else
8553 nl_srv_exit();
8554 #endif
8555
Katya Nigame7b69a82015-04-28 15:24:06 +05308556 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +05308557}
Jeff Johnson295189b2012-06-20 16:38:30 -07008558/**---------------------------------------------------------------------------
8559
8560 \brief hdd_wlan_exit() - HDD WLAN exit function
8561
8562 This is the driver exit point (invoked during rmmod)
8563
8564 \param - pHddCtx - Pointer to the HDD Context
8565
8566 \return - None
8567
8568 --------------------------------------------------------------------------*/
8569void hdd_wlan_exit(hdd_context_t *pHddCtx)
8570{
8571 eHalStatus halStatus;
8572 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8573 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308574 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008575 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008576 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008577 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308578 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008579
8580 ENTER();
8581
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308582
Katya Nigame7b69a82015-04-28 15:24:06 +05308583 if (VOS_MONITOR_MODE == hdd_get_conparam())
8584 {
8585 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
8586 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +05308587 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +05308588 }
8589 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08008590 {
8591 // Unloading, restart logic is no more required.
8592 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008593
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308594#ifdef FEATURE_WLAN_TDLS
8595 /* At the time of driver unloading; if tdls connection is present;
8596 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8597 * wlan_hdd_tdls_find_peer always checks for valid context;
8598 * as load/unload in progress there can be a race condition.
8599 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8600 * when tdls state is enabled.
8601 * As soon as driver set load/unload flag; tdls flag also needs
8602 * to be disabled so that hdd_rx_packet_cbk won't call
8603 * wlan_hdd_tdls_find_peer.
8604 */
8605 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8606#endif
8607
c_hpothu5ab05e92014-06-13 17:34:05 +05308608 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8609 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008610 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308611 pAdapter = pAdapterNode->pAdapter;
8612 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008613 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308614 /* Disable TX on the interface, after this hard_start_xmit() will
8615 * not be called on that interface
8616 */
8617 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8618 netif_tx_disable(pAdapter->dev);
8619
8620 /* Mark the interface status as "down" for outside world */
8621 netif_carrier_off(pAdapter->dev);
8622
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308623 /* DeInit the adapter. This ensures that all data packets
8624 * are freed.
8625 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308626#ifdef FEATURE_WLAN_TDLS
8627 mutex_lock(&pHddCtx->tdls_lock);
8628#endif
c_hpothu002231a2015-02-05 14:58:51 +05308629 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308630#ifdef FEATURE_WLAN_TDLS
8631 mutex_unlock(&pHddCtx->tdls_lock);
8632#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308633
c_hpothu5ab05e92014-06-13 17:34:05 +05308634 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8635 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8636 {
8637 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8638 hdd_UnregisterWext(pAdapter->dev);
8639 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308640
Jeff Johnson295189b2012-06-20 16:38:30 -07008641 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308642 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8643 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008644 }
mukul sharmabab477d2015-06-11 17:14:55 +05308645
8646 //Purge all sme cmd's for all interface
8647 hdd_purge_cmd_list_all_adapters(pHddCtx);
8648
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308649 // Cancel any outstanding scan requests. We are about to close all
8650 // of our adapters, but an adapter structure is what SME passes back
8651 // to our callback function. Hence if there are any outstanding scan
8652 // requests then there is a race condition between when the adapter
8653 // is closed and when the callback is invoked.We try to resolve that
8654 // race condition here by canceling any outstanding scans before we
8655 // close the adapters.
8656 // Note that the scans may be cancelled in an asynchronous manner,
8657 // so ideally there needs to be some kind of synchronization. Rather
8658 // than introduce a new synchronization here, we will utilize the
8659 // fact that we are about to Request Full Power, and since that is
8660 // synchronized, the expectation is that by the time Request Full
8661 // Power has completed all scans will be cancelled.
8662 if (pHddCtx->scan_info.mScanPending)
8663 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308664 if(NULL != pAdapter)
8665 {
8666 hddLog(VOS_TRACE_LEVEL_INFO,
8667 FL("abort scan mode: %d sessionId: %d"),
8668 pAdapter->device_mode,
8669 pAdapter->sessionId);
8670 }
8671 hdd_abort_mac_scan(pHddCtx,
8672 pHddCtx->scan_info.sessionId,
8673 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308674 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008675 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308676 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008677 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308678 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308679 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8680 {
8681 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8683 "%s: in middle of FTM START", __func__);
8684 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8685 msecs_to_jiffies(20000));
8686 if(!lrc)
8687 {
8688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8689 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8690 }
8691 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008692 wlan_hdd_ftm_close(pHddCtx);
8693 goto free_hdd_ctx;
8694 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308695
Jeff Johnson295189b2012-06-20 16:38:30 -07008696 /* DeRegister with platform driver as client for Suspend/Resume */
8697 vosStatus = hddDeregisterPmOps(pHddCtx);
8698 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8699 {
8700 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8701 VOS_ASSERT(0);
8702 }
8703
8704 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8705 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8706 {
8707 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8708 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008709
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008710 //Stop the traffic monitor timer
8711 if ( VOS_TIMER_STATE_RUNNING ==
8712 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8713 {
8714 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8715 }
8716
8717 // Destroy the traffic monitor timer
8718 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8719 &pHddCtx->tx_rx_trafficTmr)))
8720 {
8721 hddLog(VOS_TRACE_LEVEL_ERROR,
8722 "%s: Cannot deallocate Traffic monitor timer", __func__);
8723 }
8724
Jeff Johnson295189b2012-06-20 16:38:30 -07008725 //Disable IMPS/BMPS as we do not want the device to enter any power
8726 //save mode during shutdown
8727 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8728 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8729 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8730
8731 //Ensure that device is in full power as we will touch H/W during vos_Stop
8732 init_completion(&powerContext.completion);
8733 powerContext.magic = POWER_CONTEXT_MAGIC;
8734
8735 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8736 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8737
8738 if (eHAL_STATUS_SUCCESS != halStatus)
8739 {
8740 if (eHAL_STATUS_PMC_PENDING == halStatus)
8741 {
8742 /* request was sent -- wait for the response */
8743 lrc = wait_for_completion_interruptible_timeout(
8744 &powerContext.completion,
8745 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008746 if (lrc <= 0)
8747 {
8748 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008749 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008750 }
8751 }
8752 else
8753 {
8754 hddLog(VOS_TRACE_LEVEL_ERROR,
8755 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008756 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008757 /* continue -- need to clean up as much as possible */
8758 }
8759 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +05308760 if ((eHAL_STATUS_SUCCESS == halStatus) ||
8761 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
8762 {
8763 /* This will issue a dump command which will clean up
8764 BTQM queues and unblock MC thread */
8765 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
8766 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008767
Jeff Johnson72a40512013-12-19 10:14:15 -08008768 /* either we never sent a request, we sent a request and received a
8769 response or we sent a request and timed out. if we never sent a
8770 request or if we sent a request and got a response, we want to
8771 clear the magic out of paranoia. if we timed out there is a
8772 race condition such that the callback function could be
8773 executing at the same time we are. of primary concern is if the
8774 callback function had already verified the "magic" but had not
8775 yet set the completion variable when a timeout occurred. we
8776 serialize these activities by invalidating the magic while
8777 holding a shared spinlock which will cause us to block if the
8778 callback is currently executing */
8779 spin_lock(&hdd_context_lock);
8780 powerContext.magic = 0;
8781 spin_unlock(&hdd_context_lock);
8782
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +05308783 /* If Device is shutdown, no point for SME to wait for responses
8784 from device. Pre Close SME */
8785 if(wcnss_device_is_shutdown())
8786 {
8787 sme_PreClose(pHddCtx->hHal);
8788 }
Yue Ma0d4891e2013-08-06 17:01:45 -07008789 hdd_debugfs_exit(pHddCtx);
8790
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308791#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +05308792 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308793 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8794#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +05308795 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308796 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8797
Jeff Johnson295189b2012-06-20 16:38:30 -07008798 // Unregister the Net Device Notifier
8799 unregister_netdevice_notifier(&hdd_netdev_notifier);
8800
Jeff Johnson295189b2012-06-20 16:38:30 -07008801 hdd_stop_all_adapters( pHddCtx );
8802
Jeff Johnson295189b2012-06-20 16:38:30 -07008803#ifdef WLAN_BTAMP_FEATURE
8804 vosStatus = WLANBAP_Stop(pVosContext);
8805 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8806 {
8807 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8808 "%s: Failed to stop BAP",__func__);
8809 }
8810#endif //WLAN_BTAMP_FEATURE
8811
8812 //Stop all the modules
8813 vosStatus = vos_stop( pVosContext );
8814 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8815 {
8816 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8817 "%s: Failed to stop VOSS",__func__);
8818 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothula013bb412015-09-22 14:05:18 +05308819 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07008820 }
8821
Jeff Johnson295189b2012-06-20 16:38:30 -07008822 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008823 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008824
8825 //Close the scheduler before calling vos_close to make sure no thread is
8826 // scheduled after the each module close is called i.e after all the data
8827 // structures are freed.
8828 vosStatus = vos_sched_close( pVosContext );
8829 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8830 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8831 "%s: Failed to close VOSS Scheduler",__func__);
8832 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8833 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008834#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8835 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308836 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008837#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008838 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308839 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008840
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308841#ifdef CONFIG_ENABLE_LINUX_REG
8842 vosStatus = vos_nv_close();
8843 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8844 {
8845 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8846 "%s: Failed to close NV", __func__);
8847 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8848 }
8849#endif
8850
Jeff Johnson295189b2012-06-20 16:38:30 -07008851 //Close VOSS
8852 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8853 vos_close(pVosContext);
8854
Jeff Johnson295189b2012-06-20 16:38:30 -07008855 //Close Watchdog
8856 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8857 vos_watchdog_close(pVosContext);
8858
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308859 //Clean up HDD Nlink Service
8860 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308861
c_manjeecfd1efb2015-09-25 19:32:34 +05308862 wlan_free_fwr_mem_dump_buffer();
8863 memdump_deinit();
8864
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308865#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308866 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308867 {
8868 wlan_logging_sock_deactivate_svc();
8869 }
8870#endif
8871
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308872#ifdef WLAN_KD_READY_NOTIFIER
8873 nl_srv_exit(pHddCtx->ptt_pid);
8874#else
8875 nl_srv_exit();
8876#endif /* WLAN_KD_READY_NOTIFIER */
8877
8878
Jeff Johnson295189b2012-06-20 16:38:30 -07008879 hdd_close_all_adapters( pHddCtx );
8880
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +05308881free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -07008882 /* free the power on lock from platform driver */
8883 if (free_riva_power_on_lock("wlan"))
8884 {
8885 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8886 __func__);
8887 }
8888
c_hpothu78c7b602014-05-17 17:35:49 +05308889 //Free up dynamically allocated members inside HDD Adapter
8890 if (pHddCtx->cfg_ini)
8891 {
8892 kfree(pHddCtx->cfg_ini);
8893 pHddCtx->cfg_ini= NULL;
8894 }
8895
Leo Changf04ddad2013-09-18 13:46:38 -07008896 /* FTM mode, WIPHY did not registered
8897 If un-register here, system crash will happen */
8898 if (VOS_FTM_MODE != hdd_get_conparam())
8899 {
8900 wiphy_unregister(wiphy) ;
8901 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008902 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008903 if (hdd_is_ssr_required())
8904 {
8905 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008906 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008907 msleep(5000);
8908 }
8909 hdd_set_ssr_required (VOS_FALSE);
8910}
8911
8912
8913/**---------------------------------------------------------------------------
8914
8915 \brief hdd_update_config_from_nv() - Function to update the contents of
8916 the running configuration with parameters taken from NV storage
8917
8918 \param - pHddCtx - Pointer to the HDD global context
8919
8920 \return - VOS_STATUS_SUCCESS if successful
8921
8922 --------------------------------------------------------------------------*/
8923static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8924{
Jeff Johnson295189b2012-06-20 16:38:30 -07008925 v_BOOL_t itemIsValid = VOS_FALSE;
8926 VOS_STATUS status;
8927 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8928 v_U8_t macLoop;
8929
8930 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8931 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8932 if(status != VOS_STATUS_SUCCESS)
8933 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008934 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008935 return VOS_STATUS_E_FAILURE;
8936 }
8937
8938 if (itemIsValid == VOS_TRUE)
8939 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008940 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008941 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8942 VOS_MAX_CONCURRENCY_PERSONA);
8943 if(status != VOS_STATUS_SUCCESS)
8944 {
8945 /* Get MAC from NV fail, not update CFG info
8946 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008947 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008948 return VOS_STATUS_E_FAILURE;
8949 }
8950
8951 /* If first MAC is not valid, treat all others are not valid
8952 * Then all MACs will be got from ini file */
8953 if(vos_is_macaddr_zero(&macFromNV[0]))
8954 {
8955 /* MAC address in NV file is not configured yet */
8956 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8957 return VOS_STATUS_E_INVAL;
8958 }
8959
8960 /* Get MAC address from NV, update CFG info */
8961 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8962 {
8963 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8964 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308965 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008966 /* This MAC is not valid, skip it
8967 * This MAC will be got from ini file */
8968 }
8969 else
8970 {
8971 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8972 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8973 VOS_MAC_ADDR_SIZE);
8974 }
8975 }
8976 }
8977 else
8978 {
8979 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8980 return VOS_STATUS_E_FAILURE;
8981 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008982
Jeff Johnson295189b2012-06-20 16:38:30 -07008983
8984 return VOS_STATUS_SUCCESS;
8985}
8986
8987/**---------------------------------------------------------------------------
8988
8989 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8990
8991 \param - pAdapter - Pointer to the HDD
8992
8993 \return - None
8994
8995 --------------------------------------------------------------------------*/
8996VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8997{
8998 eHalStatus halStatus;
8999 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309000 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07009001
Jeff Johnson295189b2012-06-20 16:38:30 -07009002
9003 // Send ready indication to the HDD. This will kick off the MAC
9004 // into a 'running' state and should kick off an initial scan.
9005 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
9006 if ( !HAL_STATUS_SUCCESS( halStatus ) )
9007 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309008 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07009009 "code %08d [x%08x]",__func__, halStatus, halStatus );
9010 return VOS_STATUS_E_FAILURE;
9011 }
9012
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309013 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07009014 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
9015 // And RIVA will crash
9016 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
9017 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309018 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
9019 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
9020
9021
Jeff Johnson295189b2012-06-20 16:38:30 -07009022 return VOS_STATUS_SUCCESS;
9023}
9024
Jeff Johnson295189b2012-06-20 16:38:30 -07009025/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309026void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07009027{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309028
9029 vos_wake_lock_acquire(&wlan_wake_lock, reason);
9030
Jeff Johnson295189b2012-06-20 16:38:30 -07009031}
9032
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309033void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07009034{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309035
9036 vos_wake_lock_release(&wlan_wake_lock, reason);
9037
Jeff Johnson295189b2012-06-20 16:38:30 -07009038}
9039
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309040void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009041{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309042
9043 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
9044 reason);
9045
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009046}
9047
Jeff Johnson295189b2012-06-20 16:38:30 -07009048/**---------------------------------------------------------------------------
9049
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009050 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
9051 information between Host and Riva
9052
9053 This function gets reported version of FW
9054 It also finds the version of Riva headers used to compile the host
9055 It compares the above two and prints a warning if they are different
9056 It gets the SW and HW version string
9057 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
9058 indicating the features they support through a bitmap
9059
9060 \param - pHddCtx - Pointer to HDD context
9061
9062 \return - void
9063
9064 --------------------------------------------------------------------------*/
9065
9066void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
9067{
9068
9069 tSirVersionType versionCompiled;
9070 tSirVersionType versionReported;
9071 tSirVersionString versionString;
9072 tANI_U8 fwFeatCapsMsgSupported = 0;
9073 VOS_STATUS vstatus;
9074
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08009075 memset(&versionCompiled, 0, sizeof(versionCompiled));
9076 memset(&versionReported, 0, sizeof(versionReported));
9077
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009078 /* retrieve and display WCNSS version information */
9079 do {
9080
9081 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
9082 &versionCompiled);
9083 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9084 {
9085 hddLog(VOS_TRACE_LEVEL_FATAL,
9086 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009087 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009088 break;
9089 }
9090
9091 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
9092 &versionReported);
9093 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9094 {
9095 hddLog(VOS_TRACE_LEVEL_FATAL,
9096 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009097 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009098 break;
9099 }
9100
9101 if ((versionCompiled.major != versionReported.major) ||
9102 (versionCompiled.minor != versionReported.minor) ||
9103 (versionCompiled.version != versionReported.version) ||
9104 (versionCompiled.revision != versionReported.revision))
9105 {
9106 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
9107 "Host expected %u.%u.%u.%u\n",
9108 WLAN_MODULE_NAME,
9109 (int)versionReported.major,
9110 (int)versionReported.minor,
9111 (int)versionReported.version,
9112 (int)versionReported.revision,
9113 (int)versionCompiled.major,
9114 (int)versionCompiled.minor,
9115 (int)versionCompiled.version,
9116 (int)versionCompiled.revision);
9117 }
9118 else
9119 {
9120 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
9121 WLAN_MODULE_NAME,
9122 (int)versionReported.major,
9123 (int)versionReported.minor,
9124 (int)versionReported.version,
9125 (int)versionReported.revision);
9126 }
9127
9128 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
9129 versionString,
9130 sizeof(versionString));
9131 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9132 {
9133 hddLog(VOS_TRACE_LEVEL_FATAL,
9134 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009135 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009136 break;
9137 }
9138
9139 pr_info("%s: WCNSS software version %s\n",
9140 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +05309141 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009142
9143 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
9144 versionString,
9145 sizeof(versionString));
9146 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9147 {
9148 hddLog(VOS_TRACE_LEVEL_FATAL,
9149 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009150 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009151 break;
9152 }
9153
9154 pr_info("%s: WCNSS hardware version %s\n",
9155 WLAN_MODULE_NAME, versionString);
9156
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009157 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
9158 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009159 send the message only if it the riva is 1.1
9160 minor numbers for different riva branches:
9161 0 -> (1.0)Mainline Build
9162 1 -> (1.1)Mainline Build
9163 2->(1.04) Stability Build
9164 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009165 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009166 ((versionReported.minor>=1) && (versionReported.version>=1)))
9167 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
9168 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009169
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009170 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08009171 {
9172#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9173 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
9174 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
9175#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07009176 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
9177 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
9178 {
9179 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
9180 }
9181
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009182 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08009183 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009184
9185 } while (0);
9186
9187}
Neelansh Mittaledafed22014-09-04 18:54:39 +05309188void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
9189{
9190 struct sk_buff *skb;
9191 struct nlmsghdr *nlh;
9192 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309193 int flags = GFP_KERNEL;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309194
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309195 if (in_interrupt() || irqs_disabled() || in_atomic())
9196 flags = GFP_ATOMIC;
9197
9198 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +05309199
9200 if(skb == NULL) {
9201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9202 "%s: alloc_skb failed", __func__);
9203 return;
9204 }
9205
9206 nlh = (struct nlmsghdr *)skb->data;
9207 nlh->nlmsg_pid = 0; /* from kernel */
9208 nlh->nlmsg_flags = 0;
9209 nlh->nlmsg_seq = 0;
9210 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
9211
9212 ani_hdr = NLMSG_DATA(nlh);
9213 ani_hdr->type = type;
9214
9215 switch(type) {
9216 case WLAN_SVC_SAP_RESTART_IND:
9217 ani_hdr->length = 0;
9218 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
9219 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
9220 break;
9221 default:
9222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9223 "Attempt to send unknown nlink message %d", type);
9224 kfree_skb(skb);
9225 return;
9226 }
9227
9228 nl_srv_bcast(skb);
9229
9230 return;
9231}
9232
9233
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009234
9235/**---------------------------------------------------------------------------
9236
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309237 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
9238
9239 \param - pHddCtx - Pointer to the hdd context
9240
9241 \return - true if hardware supports 5GHz
9242
9243 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309244boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309245{
9246 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
9247 * then hardware support 5Ghz.
9248 */
9249 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
9250 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309251 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309252 return true;
9253 }
9254 else
9255 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309256 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309257 __func__);
9258 return false;
9259 }
9260}
9261
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309262/**---------------------------------------------------------------------------
9263
9264 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
9265 generate function
9266
9267 This is generate the random mac address for WLAN interface
9268
9269 \param - pHddCtx - Pointer to HDD context
9270 idx - Start interface index to get auto
9271 generated mac addr.
9272 mac_addr - Mac address
9273
9274 \return - 0 for success, < 0 for failure
9275
9276 --------------------------------------------------------------------------*/
9277
9278static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
9279 int idx, v_MACADDR_t mac_addr)
9280{
9281 int i;
9282 unsigned int serialno;
9283 serialno = wcnss_get_serial_number();
9284
9285 if (0 != serialno)
9286 {
9287 /* MAC address has 3 bytes of OUI so we have a maximum of 3
9288 bytes of the serial number that can be used to generate
9289 the other 3 bytes of the MAC address. Mask off all but
9290 the lower 3 bytes (this will also make sure we don't
9291 overflow in the next step) */
9292 serialno &= 0x00FFFFFF;
9293
9294 /* we need a unique address for each session */
9295 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
9296
9297 /* autogen other Mac addresses */
9298 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
9299 {
9300 /* start with the entire default address */
9301 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
9302 /* then replace the lower 3 bytes */
9303 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
9304 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
9305 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
9306
9307 serialno++;
9308 hddLog(VOS_TRACE_LEVEL_ERROR,
9309 "%s: Derived Mac Addr: "
9310 MAC_ADDRESS_STR, __func__,
9311 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
9312 }
9313
9314 }
9315 else
9316 {
9317 hddLog(LOGE, FL("Failed to Get Serial NO"));
9318 return -1;
9319 }
9320 return 0;
9321}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309322
Katya Nigame7b69a82015-04-28 15:24:06 +05309323int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
9324{
9325 VOS_STATUS status;
9326 v_CONTEXT_t pVosContext= NULL;
9327 hdd_adapter_t *pAdapter= NULL;
9328
9329 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9330
9331 if (NULL == pVosContext)
9332 {
9333 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9334 "%s: Trying to open VOSS without a PreOpen", __func__);
9335 VOS_ASSERT(0);
9336 return VOS_STATUS_E_FAILURE;
9337 }
9338
9339 status = vos_nv_open();
9340 if (!VOS_IS_STATUS_SUCCESS(status))
9341 {
9342 /* NV module cannot be initialized */
9343 hddLog( VOS_TRACE_LEVEL_FATAL,
9344 "%s: vos_nv_open failed", __func__);
9345 return VOS_STATUS_E_FAILURE;
9346 }
9347
9348 status = vos_init_wiphy_from_nv_bin();
9349 if (!VOS_IS_STATUS_SUCCESS(status))
9350 {
9351 /* NV module cannot be initialized */
9352 hddLog( VOS_TRACE_LEVEL_FATAL,
9353 "%s: vos_init_wiphy failed", __func__);
9354 goto err_vos_nv_close;
9355 }
9356
9357 status = vos_open( &pVosContext, pHddCtx->parent_dev);
9358 if ( !VOS_IS_STATUS_SUCCESS( status ))
9359 {
9360 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
9361 goto err_vos_nv_close;
9362 }
9363
9364 status = vos_mon_start( pVosContext );
9365 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9366 {
9367 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
9368 goto err_vosclose;
9369 }
9370
9371 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9372 WDA_featureCapsExchange(pVosContext);
9373 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9374
9375 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
9376 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9377 if( pAdapter == NULL )
9378 {
9379 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9380 goto err_close_adapter;
9381 }
9382
9383 //Initialize the nlink service
9384 if(nl_srv_init() != 0)
9385 {
9386 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
9387 goto err_close_adapter;
9388 }
9389 return VOS_STATUS_SUCCESS;
9390
9391err_close_adapter:
9392 hdd_close_all_adapters( pHddCtx );
9393 vos_mon_stop( pVosContext );
9394err_vosclose:
9395 status = vos_sched_close( pVosContext );
9396 if (!VOS_IS_STATUS_SUCCESS(status)) {
9397 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9398 "%s: Failed to close VOSS Scheduler", __func__);
9399 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9400 }
9401 vos_close(pVosContext );
9402
9403err_vos_nv_close:
9404 vos_nv_close();
9405
9406return status;
9407}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309408/**---------------------------------------------------------------------------
9409
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309410 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
9411 completed to flush out the scan results
9412
9413 11d scan is done during driver load and is a passive scan on all
9414 channels supported by the device, 11d scans may find some APs on
9415 frequencies which are forbidden to be used in the regulatory domain
9416 the device is operating in. If these APs are notified to the supplicant
9417 it may try to connect to these APs, thus flush out all the scan results
9418 which are present in SME after 11d scan is done.
9419
9420 \return - eHalStatus
9421
9422 --------------------------------------------------------------------------*/
9423static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
9424 tANI_U32 scanId, eCsrScanStatus status)
9425{
9426 ENTER();
9427
9428 sme_ScanFlushResult(halHandle, 0);
9429
9430 EXIT();
9431
9432 return eHAL_STATUS_SUCCESS;
9433}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309434/**---------------------------------------------------------------------------
9435
9436 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
9437 logging is completed successfully.
9438
9439 \return - None
9440
9441 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +05309442void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309443{
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309444 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309445
9446 if (NULL == pHddCtx)
9447 {
9448 hddLog(VOS_TRACE_LEVEL_ERROR,
9449 "%s: HDD context is NULL",__func__);
9450 return;
9451 }
9452
c_manjeecfd1efb2015-09-25 19:32:34 +05309453 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +05309454 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309455 {
9456 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
9457 pHddCtx->mgmt_frame_logging = TRUE;
9458 }
9459 else
9460 {
9461 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
9462 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +05309463 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309464 }
9465
c_manjeecfd1efb2015-09-25 19:32:34 +05309466 /*Check feature supported by FW*/
9467 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
9468 {
9469 //Store fwr mem dump size given by firmware.
9470 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
9471 }
9472 else
9473 {
9474 wlan_store_fwr_mem_dump_size(0);
9475 }
9476
9477
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309478}
9479/**---------------------------------------------------------------------------
9480
9481 \brief hdd_init_frame_logging - function to initialize frame logging.
9482 Currently only Mgmt Frames are logged in both TX
9483 and Rx direction and are sent to userspace
9484 application using logger thread when queried.
9485
9486 \return - None
9487
9488 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309489void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309490{
9491 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309492 tpSirFWLoggingInitParam wlanFWLoggingInitParam;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309493
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309494 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
9495 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309496 {
9497 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
9498 return;
9499 }
9500
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309501 wlanFWLoggingInitParam = vos_mem_malloc(sizeof(tSirFWLoggingInitParam));
9502 if(NULL == wlanFWLoggingInitParam)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309503 {
9504 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed ", __func__);
9505 return;
9506 }
9507
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309508 vos_mem_set(wlanFWLoggingInitParam, sizeof(tSirFWLoggingInitParam), 0);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309509
c_manjeecfd1efb2015-09-25 19:32:34 +05309510 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309511 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
9512 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +05309513 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
9514 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309515
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309516 if (pHddCtx->cfg_ini->enableFWLogging ||
9517 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309518 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309519 wlanFWLoggingInitParam->enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309520 }
9521
Sushant Kaushik46804902015-07-08 14:46:03 +05309522 if (pHddCtx->cfg_ini->enableMgmtLogging)
9523 {
9524 wlanFWLoggingInitParam->enableFlag |= WLAN_FRAME_LOG_EN;
9525 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309526 if (pHddCtx->cfg_ini->enableBMUHWtracing)
9527 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309528 wlanFWLoggingInitParam->enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309529 }
c_manjeecfd1efb2015-09-25 19:32:34 +05309530 if(pHddCtx->cfg_ini->enableFwrMemDump &&
9531 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
9532 {
9533 wlanFWLoggingInitParam->enableFlag |= WLAN_FW_MEM_DUMP_EN;
9534 }
9535 if( wlanFWLoggingInitParam->enableFlag == 0 )
9536 {
9537 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
9538 return;
9539 }
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309540 wlanFWLoggingInitParam->frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
9541 wlanFWLoggingInitParam->frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
9542 wlanFWLoggingInitParam->bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
9543 wlanFWLoggingInitParam->continuousFrameLogging =
9544 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309545
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309546 wlanFWLoggingInitParam->enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309547
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309548 wlanFWLoggingInitParam->minLogBufferSize =
9549 pHddCtx->cfg_ini->minLoggingBufferSize;
9550 wlanFWLoggingInitParam->maxLogBufferSize =
9551 pHddCtx->cfg_ini->maxLoggingBufferSize;
9552 wlanFWLoggingInitParam->fwlogInitCallback = hdd_init_frame_logging_done;
9553 wlanFWLoggingInitParam->fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309554
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309555 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309556
9557 if (eHAL_STATUS_SUCCESS != halStatus)
9558 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309559 vos_mem_free(wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309560 }
9561
9562 return;
9563}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309564
9565/**---------------------------------------------------------------------------
9566
Jeff Johnson295189b2012-06-20 16:38:30 -07009567 \brief hdd_wlan_startup() - HDD init function
9568
9569 This is the driver startup code executed once a WLAN device has been detected
9570
9571 \param - dev - Pointer to the underlying device
9572
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009573 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07009574
9575 --------------------------------------------------------------------------*/
9576
9577int hdd_wlan_startup(struct device *dev )
9578{
9579 VOS_STATUS status;
9580 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009581 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009582 hdd_context_t *pHddCtx = NULL;
9583 v_CONTEXT_t pVosContext= NULL;
9584#ifdef WLAN_BTAMP_FEATURE
9585 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
9586 WLANBAP_ConfigType btAmpConfig;
9587 hdd_config_t *pConfig;
9588#endif
9589 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009590 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309591 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009592
9593 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009594 /*
9595 * cfg80211: wiphy allocation
9596 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309597 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009598
9599 if(wiphy == NULL)
9600 {
9601 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009602 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009603 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009604 pHddCtx = wiphy_priv(wiphy);
9605
Jeff Johnson295189b2012-06-20 16:38:30 -07009606 //Initialize the adapter context to zeros.
9607 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
9608
Jeff Johnson295189b2012-06-20 16:38:30 -07009609 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309610 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +05309611 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009612
9613 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05309614 pHddCtx->wifi_turn_on_time_since_boot = vos_get_monotonic_boottime();
Jeff Johnson295189b2012-06-20 16:38:30 -07009615
Siddharth Bhalcd92b782015-06-29 12:25:40 +05309616 /* register for riva power on lock to platform driver
9617 * Locking power early to ensure FW doesn't reset by kernel while
9618 * host driver is busy initializing itself */
9619 if (req_riva_power_on_lock("wlan"))
9620 {
9621 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9622 __func__);
9623 goto err_free_hdd_context;
9624 }
9625
Jeff Johnson295189b2012-06-20 16:38:30 -07009626 /*Get vos context here bcoz vos_open requires it*/
9627 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9628
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08009629 if(pVosContext == NULL)
9630 {
9631 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
9632 goto err_free_hdd_context;
9633 }
9634
Jeff Johnson295189b2012-06-20 16:38:30 -07009635 //Save the Global VOSS context in adapter context for future.
9636 pHddCtx->pvosContext = pVosContext;
9637
9638 //Save the adapter context in global context for future.
9639 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
9640
Jeff Johnson295189b2012-06-20 16:38:30 -07009641 pHddCtx->parent_dev = dev;
9642
9643 init_completion(&pHddCtx->full_pwr_comp_var);
9644 init_completion(&pHddCtx->standby_comp_var);
9645 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009646 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009647 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05309648 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309649 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07009650
mukul sharma4bd8d2e2015-08-13 20:33:25 +05309651 hdd_init_ll_stats_ctx(pHddCtx);
9652
Amar Singhala49cbc52013-10-08 18:37:44 -07009653#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07009654 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07009655#else
9656 init_completion(&pHddCtx->driver_crda_req);
9657#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009658
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05309659#ifdef WLAN_FEATURE_EXTSCAN
9660 init_completion(&pHddCtx->ext_scan_context.response_event);
9661#endif /* WLAN_FEATURE_EXTSCAN */
9662
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309663 spin_lock_init(&pHddCtx->schedScan_lock);
9664
Jeff Johnson295189b2012-06-20 16:38:30 -07009665 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
9666
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309667#ifdef FEATURE_WLAN_TDLS
9668 /* tdls_lock is initialized before an hdd_open_adapter ( which is
9669 * invoked by other instances also) to protect the concurrent
9670 * access for the Adapters by TDLS module.
9671 */
9672 mutex_init(&pHddCtx->tdls_lock);
9673#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05309674 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05309675 mutex_init(&pHddCtx->wmmLock);
9676
Agarwal Ashish1f422872014-07-22 00:11:55 +05309677 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309678
Agarwal Ashish1f422872014-07-22 00:11:55 +05309679 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009680 // Load all config first as TL config is needed during vos_open
9681 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9682 if(pHddCtx->cfg_ini == NULL)
9683 {
9684 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9685 goto err_free_hdd_context;
9686 }
9687
9688 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9689
9690 // Read and parse the qcom_cfg.ini file
9691 status = hdd_parse_config_ini( pHddCtx );
9692 if ( VOS_STATUS_SUCCESS != status )
9693 {
9694 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9695 __func__, WLAN_INI_FILE);
9696 goto err_config;
9697 }
Arif Hussaind5218912013-12-05 01:10:55 -08009698#ifdef MEMORY_DEBUG
9699 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9700 vos_mem_init();
9701
9702 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9703 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9704#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009705
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309706 /* INI has been read, initialise the configuredMcastBcastFilter with
9707 * INI value as this will serve as the default value
9708 */
9709 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9710 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9711 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309712
9713 if (false == hdd_is_5g_supported(pHddCtx))
9714 {
9715 //5Ghz is not supported.
9716 if (1 != pHddCtx->cfg_ini->nBandCapability)
9717 {
9718 hddLog(VOS_TRACE_LEVEL_INFO,
9719 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9720 pHddCtx->cfg_ini->nBandCapability = 1;
9721 }
9722 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309723
9724 /* If SNR Monitoring is enabled, FW has to parse all beacons
9725 * for calcaluting and storing the average SNR, so set Nth beacon
9726 * filter to 1 to enable FW to parse all the beaocons
9727 */
9728 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9729 {
9730 /* The log level is deliberately set to WARN as overriding
9731 * nthBeaconFilter to 1 will increase power cosumption and this
9732 * might just prove helpful to detect the power issue.
9733 */
9734 hddLog(VOS_TRACE_LEVEL_WARN,
9735 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9736 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9737 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009738 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309739 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009740 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009741 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009742 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009743 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9744 {
9745 hddLog(VOS_TRACE_LEVEL_FATAL,
9746 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9747 goto err_config;
9748 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009749 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009750
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009751 // Update VOS trace levels based upon the cfg.ini
9752 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9753 pHddCtx->cfg_ini->vosTraceEnableBAP);
9754 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9755 pHddCtx->cfg_ini->vosTraceEnableTL);
9756 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9757 pHddCtx->cfg_ini->vosTraceEnableWDI);
9758 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9759 pHddCtx->cfg_ini->vosTraceEnableHDD);
9760 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9761 pHddCtx->cfg_ini->vosTraceEnableSME);
9762 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9763 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309764 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9765 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009766 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9767 pHddCtx->cfg_ini->vosTraceEnableWDA);
9768 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9769 pHddCtx->cfg_ini->vosTraceEnableSYS);
9770 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9771 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009772 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9773 pHddCtx->cfg_ini->vosTraceEnableSAP);
9774 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9775 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009776
Jeff Johnson295189b2012-06-20 16:38:30 -07009777 // Update WDI trace levels based upon the cfg.ini
9778 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9779 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9780 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9781 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9782 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9783 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9784 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9785 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009786
Jeff Johnson88ba7742013-02-27 14:36:02 -08009787 if (VOS_FTM_MODE == hdd_get_conparam())
9788 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009789 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9790 {
9791 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9792 goto err_free_hdd_context;
9793 }
9794 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +05309795 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +05309796 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009797 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009798 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009799
Katya Nigame7b69a82015-04-28 15:24:06 +05309800 if( VOS_MONITOR_MODE == hdd_get_conparam())
9801 {
9802 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
9803 {
9804 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
9805 goto err_free_hdd_context;
9806 }
9807 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
9808 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
9809 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9810 return VOS_STATUS_SUCCESS;
9811 }
9812
Jeff Johnson88ba7742013-02-27 14:36:02 -08009813 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009814 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9815 {
9816 status = vos_watchdog_open(pVosContext,
9817 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9818
9819 if(!VOS_IS_STATUS_SUCCESS( status ))
9820 {
9821 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309822 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009823 }
9824 }
9825
9826 pHddCtx->isLogpInProgress = FALSE;
9827 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9828
Amar Singhala49cbc52013-10-08 18:37:44 -07009829#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009830 /* initialize the NV module. This is required so that
9831 we can initialize the channel information in wiphy
9832 from the NV.bin data. The channel information in
9833 wiphy needs to be initialized before wiphy registration */
9834
9835 status = vos_nv_open();
9836 if (!VOS_IS_STATUS_SUCCESS(status))
9837 {
9838 /* NV module cannot be initialized */
9839 hddLog( VOS_TRACE_LEVEL_FATAL,
9840 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309841 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009842 }
9843
9844 status = vos_init_wiphy_from_nv_bin();
9845 if (!VOS_IS_STATUS_SUCCESS(status))
9846 {
9847 /* NV module cannot be initialized */
9848 hddLog( VOS_TRACE_LEVEL_FATAL,
9849 "%s: vos_init_wiphy failed", __func__);
9850 goto err_vos_nv_close;
9851 }
9852
Amar Singhala49cbc52013-10-08 18:37:44 -07009853#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309854 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309855 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009856 if ( !VOS_IS_STATUS_SUCCESS( status ))
9857 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009858 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309859 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009860 }
9861
Jeff Johnson295189b2012-06-20 16:38:30 -07009862 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9863
9864 if ( NULL == pHddCtx->hHal )
9865 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009866 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009867 goto err_vosclose;
9868 }
9869
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009870 status = vos_preStart( pHddCtx->pvosContext );
9871 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9872 {
9873 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309874 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009875 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009876
Arif Hussaineaf68602013-12-30 23:10:44 -08009877 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9878 {
9879 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9880 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9881 __func__, enable_dfs_chan_scan);
9882 }
9883 if (0 == enable_11d || 1 == enable_11d)
9884 {
9885 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9886 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9887 __func__, enable_11d);
9888 }
9889
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009890 /* Note that the vos_preStart() sequence triggers the cfg download.
9891 The cfg download must occur before we update the SME config
9892 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009893 status = hdd_set_sme_config( pHddCtx );
9894
9895 if ( VOS_STATUS_SUCCESS != status )
9896 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009897 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309898 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009899 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009900
Jeff Johnson295189b2012-06-20 16:38:30 -07009901 /* In the integrated architecture we update the configuration from
9902 the INI file and from NV before vOSS has been started so that
9903 the final contents are available to send down to the cCPU */
9904
9905 // Apply the cfg.ini to cfg.dat
9906 if (FALSE == hdd_update_config_dat(pHddCtx))
9907 {
9908 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309909 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009910 }
9911
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309912 // Get mac addr from platform driver
9913 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9914
9915 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009916 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309917 /* Store the mac addr for first interface */
9918 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9919
9920 hddLog(VOS_TRACE_LEVEL_ERROR,
9921 "%s: WLAN Mac Addr: "
9922 MAC_ADDRESS_STR, __func__,
9923 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9924
9925 /* Here, passing Arg2 as 1 because we do not want to change the
9926 last 3 bytes (means non OUI bytes) of first interface mac
9927 addr.
9928 */
9929 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9930 {
9931 hddLog(VOS_TRACE_LEVEL_ERROR,
9932 "%s: Failed to generate wlan interface mac addr "
9933 "using MAC from ini file ", __func__);
9934 }
9935 }
9936 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9937 {
9938 // Apply the NV to cfg.dat
9939 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009940#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9941 /* There was not a valid set of MAC Addresses in NV. See if the
9942 default addresses were modified by the cfg.ini settings. If so,
9943 we'll use them, but if not, we'll autogenerate a set of MAC
9944 addresses based upon the device serial number */
9945
9946 static const v_MACADDR_t default_address =
9947 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009948
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309949 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9950 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009951 {
9952 /* cfg.ini has the default address, invoke autogen logic */
9953
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309954 /* Here, passing Arg2 as 0 because we want to change the
9955 last 3 bytes (means non OUI bytes) of all the interfaces
9956 mac addr.
9957 */
9958 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9959 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009960 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309961 hddLog(VOS_TRACE_LEVEL_ERROR,
9962 "%s: Failed to generate wlan interface mac addr "
9963 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9964 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009965 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009966 }
9967 else
9968#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9969 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009970 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009971 "%s: Invalid MAC address in NV, using MAC from ini file "
9972 MAC_ADDRESS_STR, __func__,
9973 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9974 }
9975 }
9976 {
9977 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309978
9979 /* Set the MAC Address Currently this is used by HAL to
9980 * add self sta. Remove this once self sta is added as
9981 * part of session open.
9982 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009983 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9984 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9985 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309986
Jeff Johnson295189b2012-06-20 16:38:30 -07009987 if (!HAL_STATUS_SUCCESS( halStatus ))
9988 {
9989 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9990 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309991 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009992 }
9993 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009994
9995 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9996 Note: Firmware image will be read and downloaded inside vos_start API */
9997 status = vos_start( pHddCtx->pvosContext );
9998 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9999 {
10000 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothula013bb412015-09-22 14:05:18 +053010001 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010002 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070010003 }
10004
Leo Chang6cec3e22014-01-21 15:33:49 -080010005#ifdef FEATURE_WLAN_CH_AVOID
10006 /* Plug in avoid channel notification callback
10007 * This should happen before ADD_SELF_STA
10008 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053010009
10010 /* check the Channel Avoidance is enabled */
10011 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
10012 {
10013 sme_AddChAvoidCallback(pHddCtx->hHal,
10014 hdd_hostapd_ch_avoid_cb);
10015 }
Leo Chang6cec3e22014-01-21 15:33:49 -080010016#endif /* FEATURE_WLAN_CH_AVOID */
10017
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010018 /* Exchange capability info between Host and FW and also get versioning info from FW */
10019 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010020
Agarwal Ashishad9281b2014-06-10 14:57:30 +053010021#ifdef CONFIG_ENABLE_LINUX_REG
10022 status = wlan_hdd_init_channels(pHddCtx);
10023 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10024 {
10025 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
10026 __func__);
10027 goto err_vosstop;
10028 }
10029#endif
10030
Jeff Johnson295189b2012-06-20 16:38:30 -070010031 status = hdd_post_voss_start_config( pHddCtx );
10032 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10033 {
10034 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
10035 __func__);
10036 goto err_vosstop;
10037 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010038
10039#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010040 wlan_hdd_cfg80211_update_reg_info( wiphy );
10041
10042 /* registration of wiphy dev with cfg80211 */
10043 if (0 > wlan_hdd_cfg80211_register(wiphy))
10044 {
10045 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
10046 goto err_vosstop;
10047 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010048#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010049
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010050#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010051 /* registration of wiphy dev with cfg80211 */
10052 if (0 > wlan_hdd_cfg80211_register(wiphy))
10053 {
10054 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
10055 goto err_vosstop;
10056 }
10057
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010058 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010059 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10060 {
10061 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
10062 __func__);
10063 goto err_unregister_wiphy;
10064 }
10065#endif
10066
c_hpothu4a298be2014-12-22 21:12:51 +053010067 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
10068
Jeff Johnson295189b2012-06-20 16:38:30 -070010069 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10070 {
10071 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
10072 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
10073 }
10074 else
10075 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010076 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
10077 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
10078 if (pAdapter != NULL)
10079 {
Katya Nigama7d81d72014-11-12 12:44:34 +053010080 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070010081 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053010082 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
10083 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
10084 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070010085
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053010086 /* Generate the P2P Device Address. This consists of the device's
10087 * primary MAC address with the locally administered bit set.
10088 */
10089 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070010090 }
10091 else
10092 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053010093 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
10094 if (p2p_dev_addr != NULL)
10095 {
10096 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
10097 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
10098 }
10099 else
10100 {
10101 hddLog(VOS_TRACE_LEVEL_FATAL,
10102 "%s: Failed to allocate mac_address for p2p_device",
10103 __func__);
10104 goto err_close_adapter;
10105 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010106 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010107
10108 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
10109 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
10110 if ( NULL == pP2pAdapter )
10111 {
10112 hddLog(VOS_TRACE_LEVEL_FATAL,
10113 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010114 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070010115 goto err_close_adapter;
10116 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010117 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010118 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010119
10120 if( pAdapter == NULL )
10121 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010122 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
10123 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010124 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010125
Arif Hussain66559122013-11-21 10:11:40 -080010126 if (country_code)
10127 {
10128 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080010129 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080010130 hdd_checkandupdate_dfssetting(pAdapter, country_code);
10131#ifndef CONFIG_ENABLE_LINUX_REG
10132 hdd_checkandupdate_phymode(pAdapter, country_code);
10133#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080010134 ret = sme_ChangeCountryCode(pHddCtx->hHal,
10135 (void *)(tSmeChangeCountryCallback)
10136 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080010137 country_code,
10138 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010139 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080010140 if (eHAL_STATUS_SUCCESS == ret)
10141 {
Arif Hussaincb607082013-12-20 11:57:42 -080010142 ret = wait_for_completion_interruptible_timeout(
10143 &pAdapter->change_country_code,
10144 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
10145
10146 if (0 >= ret)
10147 {
10148 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10149 "%s: SME while setting country code timed out", __func__);
10150 }
Arif Hussain66559122013-11-21 10:11:40 -080010151 }
10152 else
10153 {
Arif Hussaincb607082013-12-20 11:57:42 -080010154 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10155 "%s: SME Change Country code from module param fail ret=%d",
10156 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080010157 }
10158 }
10159
Jeff Johnson295189b2012-06-20 16:38:30 -070010160#ifdef WLAN_BTAMP_FEATURE
10161 vStatus = WLANBAP_Open(pVosContext);
10162 if(!VOS_IS_STATUS_SUCCESS(vStatus))
10163 {
10164 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10165 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070010166 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010167 }
10168
10169 vStatus = BSL_Init(pVosContext);
10170 if(!VOS_IS_STATUS_SUCCESS(vStatus))
10171 {
10172 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10173 "%s: Failed to Init BSL",__func__);
10174 goto err_bap_close;
10175 }
10176 vStatus = WLANBAP_Start(pVosContext);
10177 if (!VOS_IS_STATUS_SUCCESS(vStatus))
10178 {
10179 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10180 "%s: Failed to start TL",__func__);
10181 goto err_bap_close;
10182 }
10183
10184 pConfig = pHddCtx->cfg_ini;
10185 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
10186 status = WLANBAP_SetConfig(&btAmpConfig);
10187
10188#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070010189
Mihir Shete9c238772014-10-15 14:35:16 +053010190 /*
10191 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
10192 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
10193 * which is greater than 0xf. So the below check is safe to make
10194 * sure that there is no entry for UapsdMask in the ini
10195 */
10196 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
10197 {
10198 if(IS_DYNAMIC_WMM_PS_ENABLED)
10199 {
10200 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
10201 __func__);
10202 pHddCtx->cfg_ini->UapsdMask =
10203 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
10204 }
10205 else
10206 {
10207 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
10208 __func__);
10209 pHddCtx->cfg_ini->UapsdMask =
10210 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
10211 }
10212 }
10213
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070010214#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
10215 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
10216 {
10217 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
10218 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
10219 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
10220 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
10221 }
10222#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010223
Agarwal Ashish4b87f922014-06-18 03:03:21 +053010224 wlan_hdd_tdls_init(pHddCtx);
10225
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053010226 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
10227
Jeff Johnson295189b2012-06-20 16:38:30 -070010228 /* Register with platform driver as client for Suspend/Resume */
10229 status = hddRegisterPmOps(pHddCtx);
10230 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10231 {
10232 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
10233#ifdef WLAN_BTAMP_FEATURE
10234 goto err_bap_stop;
10235#else
Jeff Johnsone7245742012-09-05 17:12:55 -070010236 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010237#endif //WLAN_BTAMP_FEATURE
10238 }
10239
Yue Ma0d4891e2013-08-06 17:01:45 -070010240 /* Open debugfs interface */
10241 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
10242 {
10243 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10244 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070010245 }
10246
Jeff Johnson295189b2012-06-20 16:38:30 -070010247 /* Register TM level change handler function to the platform */
10248 status = hddDevTmRegisterNotifyCallback(pHddCtx);
10249 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10250 {
10251 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
10252 goto err_unregister_pmops;
10253 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010254
Jeff Johnson295189b2012-06-20 16:38:30 -070010255 // register net device notifier for device change notification
10256 ret = register_netdevice_notifier(&hdd_netdev_notifier);
10257
10258 if(ret < 0)
10259 {
10260 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010261 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070010262 }
10263
10264 //Initialize the nlink service
10265 if(nl_srv_init() != 0)
10266 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010267 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010268 goto err_reg_netdev;
10269 }
10270
Leo Chang4ce1cc52013-10-21 18:27:15 -070010271#ifdef WLAN_KD_READY_NOTIFIER
10272 pHddCtx->kd_nl_init = 1;
10273#endif /* WLAN_KD_READY_NOTIFIER */
10274
Jeff Johnson295189b2012-06-20 16:38:30 -070010275 //Initialize the BTC service
10276 if(btc_activate_service(pHddCtx) != 0)
10277 {
10278 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
10279 goto err_nl_srv;
10280 }
10281
10282#ifdef PTT_SOCK_SVC_ENABLE
10283 //Initialize the PTT service
10284 if(ptt_sock_activate_svc(pHddCtx) != 0)
10285 {
10286 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
10287 goto err_nl_srv;
10288 }
10289#endif
10290
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010291#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10292 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
10293 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053010294 if(wlan_logging_sock_activate_svc(
10295 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
10296 pHddCtx->cfg_ini->wlanLoggingNumBuf))
10297 {
10298 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
10299 " failed", __func__);
10300 goto err_nl_srv;
10301 }
10302 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
10303 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053010304 if (!pHddCtx->cfg_ini->gEnableDebugLog)
10305 pHddCtx->cfg_ini->gEnableDebugLog =
10306 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010307 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010308
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010309 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
10310 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053010311 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053010312 pHddCtx->cfg_ini->enableContFWLogging ||
10313 pHddCtx->cfg_ini->enableFwrMemDump )
10314 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010315 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010316 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010317 }
10318 else
10319 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010320 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010321 }
10322
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010323#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010324
10325
Sushant Kaushik215778f2015-05-21 14:05:36 +053010326 if (vos_is_multicast_logging())
10327 wlan_logging_set_log_level();
10328
Jeff Johnson295189b2012-06-20 16:38:30 -070010329 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010330 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070010331 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070010332 /* Action frame registered in one adapter which will
10333 * applicable to all interfaces
10334 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053010335 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010336 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010337
10338 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053010339 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010340
Jeff Johnsone7245742012-09-05 17:12:55 -070010341#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10342 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010343 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070010344 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010345
Jeff Johnsone7245742012-09-05 17:12:55 -070010346#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010347 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010348 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010349 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010350
Jeff Johnsone7245742012-09-05 17:12:55 -070010351
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010352 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
10353 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010354
Katya Nigam5c306ea2014-06-19 15:39:54 +053010355 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010356 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010357 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053010358
10359#ifdef FEATURE_WLAN_SCAN_PNO
10360 /*SME must send channel update configuration to RIVA*/
10361 sme_UpdateChannelConfig(pHddCtx->hHal);
10362#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053010363 /* Send the update default channel list to the FW*/
10364 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053010365
10366 /* Fwr capabilities received, Set the Dot11 mode */
10367 sme_SetDefDot11Mode(pHddCtx->hHal);
10368
Abhishek Singha306a442013-11-07 18:39:01 +053010369#ifndef CONFIG_ENABLE_LINUX_REG
10370 /*updating wiphy so that regulatory user hints can be processed*/
10371 if (wiphy)
10372 {
10373 regulatory_hint(wiphy, "00");
10374 }
10375#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010376 // Initialize the restart logic
10377 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053010378
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010379 //Register the traffic monitor timer now
10380 if ( pHddCtx->cfg_ini->dynSplitscan)
10381 {
10382 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
10383 VOS_TIMER_TYPE_SW,
10384 hdd_tx_rx_pkt_cnt_stat_timer_handler,
10385 (void *)pHddCtx);
10386 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053010387 wlan_hdd_cfg80211_nan_init(pHddCtx);
10388
Dino Mycle6fb96c12014-06-10 11:52:40 +053010389#ifdef WLAN_FEATURE_EXTSCAN
10390 sme_EXTScanRegisterCallback(pHddCtx->hHal,
10391 wlan_hdd_cfg80211_extscan_callback,
10392 pHddCtx);
10393#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010394
10395#ifdef WLAN_NS_OFFLOAD
10396 // Register IPv6 notifier to notify if any change in IP
10397 // So that we can reconfigure the offload parameters
10398 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
10399 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10400 if (ret)
10401 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010402 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010403 }
10404 else
10405 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010406 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010407 }
10408#endif
10409
10410 // Register IPv4 notifier to notify if any change in IP
10411 // So that we can reconfigure the offload parameters
10412 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
10413 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10414 if (ret)
10415 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010416 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010417 }
10418 else
10419 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010420 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010421 }
c_manjeecfd1efb2015-09-25 19:32:34 +053010422 /*Fw mem dump procfs initialization*/
10423 memdump_init();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010424
Jeff Johnson295189b2012-06-20 16:38:30 -070010425 goto success;
10426
10427err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -070010428#ifdef WLAN_KD_READY_NOTIFIER
10429 nl_srv_exit(pHddCtx->ptt_pid);
10430#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010431 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -070010432#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -070010433err_reg_netdev:
10434 unregister_netdevice_notifier(&hdd_netdev_notifier);
10435
Jeff Johnson295189b2012-06-20 16:38:30 -070010436err_unregister_pmops:
10437 hddDevTmUnregisterNotifyCallback(pHddCtx);
10438 hddDeregisterPmOps(pHddCtx);
10439
Yue Ma0d4891e2013-08-06 17:01:45 -070010440 hdd_debugfs_exit(pHddCtx);
10441
Jeff Johnson295189b2012-06-20 16:38:30 -070010442#ifdef WLAN_BTAMP_FEATURE
10443err_bap_stop:
10444 WLANBAP_Stop(pVosContext);
10445#endif
10446
10447#ifdef WLAN_BTAMP_FEATURE
10448err_bap_close:
10449 WLANBAP_Close(pVosContext);
10450#endif
10451
Jeff Johnson295189b2012-06-20 16:38:30 -070010452err_close_adapter:
10453 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010454#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010455err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010456#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010457 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010458err_vosstop:
10459 vos_stop(pVosContext);
10460
Amar Singhala49cbc52013-10-08 18:37:44 -070010461err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070010462 status = vos_sched_close( pVosContext );
10463 if (!VOS_IS_STATUS_SUCCESS(status)) {
10464 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10465 "%s: Failed to close VOSS Scheduler", __func__);
10466 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
10467 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010468 vos_close(pVosContext );
10469
Amar Singhal0a402232013-10-11 20:57:16 -070010470err_vos_nv_close:
10471
c_hpothue6a36282014-03-19 12:27:38 +053010472#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070010473 vos_nv_close();
10474
c_hpothu70f8d812014-03-22 22:59:23 +053010475#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010476
10477err_wdclose:
10478 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10479 vos_watchdog_close(pVosContext);
10480
Jeff Johnson295189b2012-06-20 16:38:30 -070010481err_config:
10482 kfree(pHddCtx->cfg_ini);
10483 pHddCtx->cfg_ini= NULL;
10484
10485err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010486 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010487 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010488 wiphy_free(wiphy) ;
10489 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010490 VOS_BUG(1);
10491
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080010492 if (hdd_is_ssr_required())
10493 {
10494 /* WDI timeout had happened during load, so SSR is needed here */
10495 subsystem_restart("wcnss");
10496 msleep(5000);
10497 }
10498 hdd_set_ssr_required (VOS_FALSE);
10499
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010500 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010501
10502success:
10503 EXIT();
10504 return 0;
10505}
10506
10507/**---------------------------------------------------------------------------
10508
Jeff Johnson32d95a32012-09-10 13:15:23 -070010509 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070010510
Jeff Johnson32d95a32012-09-10 13:15:23 -070010511 This is the driver entry point - called in different timeline depending
10512 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070010513
10514 \param - None
10515
10516 \return - 0 for success, non zero for failure
10517
10518 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070010519static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010520{
10521 VOS_STATUS status;
10522 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010523 struct device *dev = NULL;
10524 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010525#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10526 int max_retries = 0;
10527#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010528#ifdef HAVE_CBC_DONE
10529 int max_cbc_retries = 0;
10530#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010531
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010532#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10533 wlan_logging_sock_init_svc();
10534#endif
10535
Jeff Johnson295189b2012-06-20 16:38:30 -070010536 ENTER();
10537
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010538 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010539
10540 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
10541 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
10542
Jeff Johnson295189b2012-06-20 16:38:30 -070010543#ifdef ANI_BUS_TYPE_PCI
10544
10545 dev = wcnss_wlan_get_device();
10546
10547#endif // ANI_BUS_TYPE_PCI
10548
10549#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010550
10551#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10552 /* wait until WCNSS driver downloads NV */
10553 while (!wcnss_device_ready() && 5 >= ++max_retries) {
10554 msleep(1000);
10555 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010556
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010557 if (max_retries >= 5) {
10558 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010559 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010560#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10561 wlan_logging_sock_deinit_svc();
10562#endif
10563
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010564 return -ENODEV;
10565 }
10566#endif
10567
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010568#ifdef HAVE_CBC_DONE
10569 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
10570 msleep(1000);
10571 }
10572 if (max_cbc_retries >= 10) {
10573 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
10574 }
10575#endif
10576
Jeff Johnson295189b2012-06-20 16:38:30 -070010577 dev = wcnss_wlan_get_device();
10578#endif // ANI_BUS_TYPE_PLATFORM
10579
10580
10581 do {
10582 if (NULL == dev) {
10583 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
10584 ret_status = -1;
10585 break;
10586 }
10587
Jeff Johnson295189b2012-06-20 16:38:30 -070010588#ifdef TIMER_MANAGER
10589 vos_timer_manager_init();
10590#endif
10591
10592 /* Preopen VOSS so that it is ready to start at least SAL */
10593 status = vos_preOpen(&pVosContext);
10594
10595 if (!VOS_IS_STATUS_SUCCESS(status))
10596 {
10597 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
10598 ret_status = -1;
10599 break;
10600 }
10601
Sushant Kaushik02beb352015-06-04 15:15:01 +053010602 hddTraceInit();
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010603#ifndef MODULE
10604 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
10605 */
10606 hdd_set_conparam((v_UINT_t)con_mode);
10607#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010608
10609 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010610 if (hdd_wlan_startup(dev))
10611 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010612 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010613 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010614 vos_preClose( &pVosContext );
10615 ret_status = -1;
10616 break;
10617 }
10618
Jeff Johnson295189b2012-06-20 16:38:30 -070010619 } while (0);
10620
10621 if (0 != ret_status)
10622 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010623#ifdef TIMER_MANAGER
10624 vos_timer_exit();
10625#endif
10626#ifdef MEMORY_DEBUG
10627 vos_mem_exit();
10628#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010629 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010630#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10631 wlan_logging_sock_deinit_svc();
10632#endif
10633
Jeff Johnson295189b2012-06-20 16:38:30 -070010634 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
10635 }
10636 else
10637 {
10638 //Send WLAN UP indication to Nlink Service
10639 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
10640
10641 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070010642 }
10643
10644 EXIT();
10645
10646 return ret_status;
10647}
10648
Jeff Johnson32d95a32012-09-10 13:15:23 -070010649/**---------------------------------------------------------------------------
10650
10651 \brief hdd_module_init() - Init Function
10652
10653 This is the driver entry point (invoked when module is loaded using insmod)
10654
10655 \param - None
10656
10657 \return - 0 for success, non zero for failure
10658
10659 --------------------------------------------------------------------------*/
10660#ifdef MODULE
10661static int __init hdd_module_init ( void)
10662{
10663 return hdd_driver_init();
10664}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010665#else /* #ifdef MODULE */
10666static int __init hdd_module_init ( void)
10667{
10668 /* Driver initialization is delayed to fwpath_changed_handler */
10669 return 0;
10670}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010671#endif /* #ifdef MODULE */
10672
Jeff Johnson295189b2012-06-20 16:38:30 -070010673
10674/**---------------------------------------------------------------------------
10675
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010676 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070010677
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010678 This is the driver exit point (invoked when module is unloaded using rmmod
10679 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070010680
10681 \param - None
10682
10683 \return - None
10684
10685 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010686static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010687{
10688 hdd_context_t *pHddCtx = NULL;
10689 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053010690 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053010691 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010692
10693 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
10694
10695 //Get the global vos context
10696 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10697
10698 if(!pVosContext)
10699 {
10700 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10701 goto done;
10702 }
10703
10704 //Get the HDD context.
10705 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10706
10707 if(!pHddCtx)
10708 {
10709 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10710 }
Katya Nigame7b69a82015-04-28 15:24:06 +053010711 else if (VOS_MONITOR_MODE == hdd_get_conparam())
10712 {
10713 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
10714 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10715 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
10716 hdd_wlan_exit(pHddCtx);
10717 vos_preClose( &pVosContext );
10718 goto done;
10719 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010720 else
10721 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053010722 /* We wait for active entry threads to exit from driver
10723 * by waiting until rtnl_lock is available.
10724 */
10725 rtnl_lock();
10726 rtnl_unlock();
10727
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010728 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10729 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10730 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10731 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010733 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010734 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10735 msecs_to_jiffies(30000));
10736 if(!rc)
10737 {
10738 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10739 "%s:SSR timedout, fatal error", __func__);
10740 VOS_BUG(0);
10741 }
10742 }
10743
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010744 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10745 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010746
c_hpothu8adb97b2014-12-08 19:38:20 +053010747 /* Driver Need to send country code 00 in below condition
10748 * 1) If gCountryCodePriority is set to 1; and last country
10749 * code set is through 11d. This needs to be done in case
10750 * when NV country code is 00.
10751 * This Needs to be done as when kernel store last country
10752 * code and if stored country code is not through 11d,
10753 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10754 * in next load/unload as soon as we get any country through
10755 * 11d. In sme_HandleChangeCountryCodeByUser
10756 * pMsg->countryCode will be last countryCode and
10757 * pMac->scan.countryCode11d will be country through 11d so
10758 * due to mismatch driver will disable 11d.
10759 *
10760 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010761
c_hpothu8adb97b2014-12-08 19:38:20 +053010762 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010763 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010764 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010765 {
10766 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010767 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010768 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10769 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010770
c_hpothu8adb97b2014-12-08 19:38:20 +053010771 //Do all the cleanup before deregistering the driver
10772 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010773 }
10774
Jeff Johnson295189b2012-06-20 16:38:30 -070010775 vos_preClose( &pVosContext );
10776
10777#ifdef TIMER_MANAGER
10778 vos_timer_exit();
10779#endif
10780#ifdef MEMORY_DEBUG
10781 vos_mem_exit();
10782#endif
10783
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010784#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10785 wlan_logging_sock_deinit_svc();
10786#endif
10787
Jeff Johnson295189b2012-06-20 16:38:30 -070010788done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010789 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010790
Jeff Johnson295189b2012-06-20 16:38:30 -070010791 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10792}
10793
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010794/**---------------------------------------------------------------------------
10795
10796 \brief hdd_module_exit() - Exit function
10797
10798 This is the driver exit point (invoked when module is unloaded using rmmod)
10799
10800 \param - None
10801
10802 \return - None
10803
10804 --------------------------------------------------------------------------*/
10805static void __exit hdd_module_exit(void)
10806{
10807 hdd_driver_exit();
10808}
10809
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010810#ifdef MODULE
10811static int fwpath_changed_handler(const char *kmessage,
10812 struct kernel_param *kp)
10813{
Jeff Johnson76052702013-04-16 13:55:05 -070010814 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010815}
10816
10817static int con_mode_handler(const char *kmessage,
10818 struct kernel_param *kp)
10819{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010820 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010821}
10822#else /* #ifdef MODULE */
10823/**---------------------------------------------------------------------------
10824
Jeff Johnson76052702013-04-16 13:55:05 -070010825 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010826
Jeff Johnson76052702013-04-16 13:55:05 -070010827 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010828 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010829 - invoked when module parameter fwpath is modified from userspace to signal
10830 initializing the WLAN driver or when con_mode is modified from userspace
10831 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010832
10833 \return - 0 for success, non zero for failure
10834
10835 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010836static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010837{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010838 int ret_status;
10839
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010840 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010841 ret_status = hdd_driver_init();
10842 wlan_hdd_inited = ret_status ? 0 : 1;
10843 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010844 }
10845
10846 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010847
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010848 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010849
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010850 ret_status = hdd_driver_init();
10851 wlan_hdd_inited = ret_status ? 0 : 1;
10852 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010853}
10854
Jeff Johnson295189b2012-06-20 16:38:30 -070010855/**---------------------------------------------------------------------------
10856
Jeff Johnson76052702013-04-16 13:55:05 -070010857 \brief fwpath_changed_handler() - Handler Function
10858
10859 Handle changes to the fwpath parameter
10860
10861 \return - 0 for success, non zero for failure
10862
10863 --------------------------------------------------------------------------*/
10864static int fwpath_changed_handler(const char *kmessage,
10865 struct kernel_param *kp)
10866{
10867 int ret;
10868
10869 ret = param_set_copystring(kmessage, kp);
10870 if (0 == ret)
10871 ret = kickstart_driver();
10872 return ret;
10873}
10874
10875/**---------------------------------------------------------------------------
10876
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010877 \brief con_mode_handler() -
10878
10879 Handler function for module param con_mode when it is changed by userspace
10880 Dynamically linked - do nothing
10881 Statically linked - exit and init driver, as in rmmod and insmod
10882
Jeff Johnson76052702013-04-16 13:55:05 -070010883 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010884
Jeff Johnson76052702013-04-16 13:55:05 -070010885 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010886
10887 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010888static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010889{
Jeff Johnson76052702013-04-16 13:55:05 -070010890 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010891
Jeff Johnson76052702013-04-16 13:55:05 -070010892 ret = param_set_int(kmessage, kp);
10893 if (0 == ret)
10894 ret = kickstart_driver();
10895 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010896}
10897#endif /* #ifdef MODULE */
10898
10899/**---------------------------------------------------------------------------
10900
Jeff Johnson295189b2012-06-20 16:38:30 -070010901 \brief hdd_get_conparam() -
10902
10903 This is the driver exit point (invoked when module is unloaded using rmmod)
10904
10905 \param - None
10906
10907 \return - tVOS_CON_MODE
10908
10909 --------------------------------------------------------------------------*/
10910tVOS_CON_MODE hdd_get_conparam ( void )
10911{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010912#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010913 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010914#else
10915 return (tVOS_CON_MODE)curr_con_mode;
10916#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010917}
10918void hdd_set_conparam ( v_UINT_t newParam )
10919{
10920 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010921#ifndef MODULE
10922 curr_con_mode = con_mode;
10923#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010924}
10925/**---------------------------------------------------------------------------
10926
10927 \brief hdd_softap_sta_deauth() - function
10928
10929 This to take counter measure to handle deauth req from HDD
10930
10931 \param - pAdapter - Pointer to the HDD
10932
10933 \param - enable - boolean value
10934
10935 \return - None
10936
10937 --------------------------------------------------------------------------*/
10938
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010939VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10940 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010941{
Jeff Johnson295189b2012-06-20 16:38:30 -070010942 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010943 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010944
10945 ENTER();
10946
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010947 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10948 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010949
10950 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010951 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010952 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010953
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010954 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010955
10956 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010957 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010958}
10959
10960/**---------------------------------------------------------------------------
10961
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010962 \brief hdd_del_all_sta() - function
10963
10964 This function removes all the stations associated on stopping AP/P2P GO.
10965
10966 \param - pAdapter - Pointer to the HDD
10967
10968 \return - None
10969
10970 --------------------------------------------------------------------------*/
10971
10972int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10973{
10974 v_U16_t i;
10975 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010976 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10977 ptSapContext pSapCtx = NULL;
10978 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10979 if(pSapCtx == NULL){
10980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10981 FL("psapCtx is NULL"));
10982 return 1;
10983 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010984 ENTER();
10985
10986 hddLog(VOS_TRACE_LEVEL_INFO,
10987 "%s: Delete all STAs associated.",__func__);
10988 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10989 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10990 )
10991 {
10992 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10993 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010994 if ((pSapCtx->aStaInfo[i].isUsed) &&
10995 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010996 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010997 struct tagCsrDelStaParams delStaParams;
10998
10999 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011000 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053011001 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
11002 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011003 &delStaParams);
11004 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011005 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011006 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011007 }
11008 }
11009 }
11010
11011 EXIT();
11012 return 0;
11013}
11014
11015/**---------------------------------------------------------------------------
11016
Jeff Johnson295189b2012-06-20 16:38:30 -070011017 \brief hdd_softap_sta_disassoc() - function
11018
11019 This to take counter measure to handle deauth req from HDD
11020
11021 \param - pAdapter - Pointer to the HDD
11022
11023 \param - enable - boolean value
11024
11025 \return - None
11026
11027 --------------------------------------------------------------------------*/
11028
11029void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
11030{
11031 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11032
11033 ENTER();
11034
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011035 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011036
11037 //Ignore request to disassoc bcmc station
11038 if( pDestMacAddress[0] & 0x1 )
11039 return;
11040
11041 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
11042}
11043
11044void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
11045{
11046 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11047
11048 ENTER();
11049
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011050 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011051
11052 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
11053}
11054
Jeff Johnson295189b2012-06-20 16:38:30 -070011055/**---------------------------------------------------------------------------
11056 *
11057 * \brief hdd_get__concurrency_mode() -
11058 *
11059 *
11060 * \param - None
11061 *
11062 * \return - CONCURRENCY MODE
11063 *
11064 * --------------------------------------------------------------------------*/
11065tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
11066{
11067 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
11068 hdd_context_t *pHddCtx;
11069
11070 if (NULL != pVosContext)
11071 {
11072 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
11073 if (NULL != pHddCtx)
11074 {
11075 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
11076 }
11077 }
11078
11079 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011080 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011081 return VOS_STA;
11082}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011083v_BOOL_t
11084wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
11085{
11086 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011087
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011088 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
11089 if (pAdapter == NULL)
11090 {
11091 hddLog(VOS_TRACE_LEVEL_INFO,
11092 FL("GO doesn't exist"));
11093 return TRUE;
11094 }
11095 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11096 {
11097 hddLog(VOS_TRACE_LEVEL_INFO,
11098 FL("GO started"));
11099 return TRUE;
11100 }
11101 else
11102 /* wait till GO changes its interface to p2p device */
11103 hddLog(VOS_TRACE_LEVEL_INFO,
11104 FL("Del_bss called, avoid apps suspend"));
11105 return FALSE;
11106
11107}
Jeff Johnson295189b2012-06-20 16:38:30 -070011108/* Decide whether to allow/not the apps power collapse.
11109 * Allow apps power collapse if we are in connected state.
11110 * if not, allow only if we are in IMPS */
11111v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
11112{
11113 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080011114 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080011115 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011116 hdd_config_t *pConfig = pHddCtx->cfg_ini;
11117 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11118 hdd_adapter_t *pAdapter = NULL;
11119 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080011120 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011121
Jeff Johnson295189b2012-06-20 16:38:30 -070011122 if (VOS_STA_SAP_MODE == hdd_get_conparam())
11123 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011124
Yathish9f22e662012-12-10 14:21:35 -080011125 concurrent_state = hdd_get_concurrency_mode();
11126
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011127 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
11128 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
11129 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080011130#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011131
Yathish9f22e662012-12-10 14:21:35 -080011132 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011133 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080011134 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
11135 return TRUE;
11136#endif
11137
Jeff Johnson295189b2012-06-20 16:38:30 -070011138 /*loop through all adapters. TBD fix for Concurrency */
11139 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11140 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11141 {
11142 pAdapter = pAdapterNode->pAdapter;
11143 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11144 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11145 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080011146 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053011147 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053011148 && pmcState != STOPPED && pmcState != STANDBY &&
11149 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080011150 (eANI_BOOLEAN_TRUE == scanRspPending) ||
11151 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070011152 {
Mukul Sharma4be88422015-03-09 20:29:07 +053011153 if(pmcState == FULL_POWER &&
11154 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
11155 {
11156 /*
11157 * When SCO indication comes from Coex module , host will
11158 * enter in to full power mode, but this should not prevent
11159 * apps processor power collapse.
11160 */
11161 hddLog(LOG1,
11162 FL("Allow apps power collapse"
11163 "even when sco indication is set"));
11164 return TRUE;
11165 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080011166 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080011167 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
11168 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070011169 return FALSE;
11170 }
11171 }
11172 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11173 pAdapterNode = pNext;
11174 }
11175 return TRUE;
11176}
11177
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080011178/* Decides whether to send suspend notification to Riva
11179 * if any adapter is in BMPS; then it is required */
11180v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
11181{
11182 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
11183 hdd_config_t *pConfig = pHddCtx->cfg_ini;
11184
11185 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
11186 {
11187 return TRUE;
11188 }
11189 return FALSE;
11190}
11191
Jeff Johnson295189b2012-06-20 16:38:30 -070011192void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11193{
11194 switch(mode)
11195 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011196 case VOS_STA_MODE:
11197 case VOS_P2P_CLIENT_MODE:
11198 case VOS_P2P_GO_MODE:
11199 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070011200 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011201 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070011202 break;
11203 default:
11204 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011205 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011206 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11207 "Number of open sessions for mode %d = %d"),
11208 pHddCtx->concurrency_mode, mode,
11209 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011210}
11211
11212
11213void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11214{
11215 switch(mode)
11216 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011217 case VOS_STA_MODE:
11218 case VOS_P2P_CLIENT_MODE:
11219 case VOS_P2P_GO_MODE:
11220 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053011221 pHddCtx->no_of_open_sessions[mode]--;
11222 if (!(pHddCtx->no_of_open_sessions[mode]))
11223 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070011224 break;
11225 default:
11226 break;
11227 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011228 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11229 "Number of open sessions for mode %d = %d"),
11230 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
11231
11232}
11233/**---------------------------------------------------------------------------
11234 *
11235 * \brief wlan_hdd_incr_active_session()
11236 *
11237 * This function increments the number of active sessions
11238 * maintained per device mode
11239 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
11240 * Incase of SAP/P2P GO upon bss start it is incremented
11241 *
11242 * \param pHddCtx - HDD Context
11243 * \param mode - device mode
11244 *
11245 * \return - None
11246 *
11247 * --------------------------------------------------------------------------*/
11248void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11249{
11250 switch (mode) {
11251 case VOS_STA_MODE:
11252 case VOS_P2P_CLIENT_MODE:
11253 case VOS_P2P_GO_MODE:
11254 case VOS_STA_SAP_MODE:
11255 pHddCtx->no_of_active_sessions[mode]++;
11256 break;
11257 default:
11258 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11259 break;
11260 }
11261 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11262 mode,
11263 pHddCtx->no_of_active_sessions[mode]);
11264}
11265
11266/**---------------------------------------------------------------------------
11267 *
11268 * \brief wlan_hdd_decr_active_session()
11269 *
11270 * This function decrements the number of active sessions
11271 * maintained per device mode
11272 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
11273 * Incase of SAP/P2P GO upon bss stop it is decremented
11274 *
11275 * \param pHddCtx - HDD Context
11276 * \param mode - device mode
11277 *
11278 * \return - None
11279 *
11280 * --------------------------------------------------------------------------*/
11281void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11282{
11283 switch (mode) {
11284 case VOS_STA_MODE:
11285 case VOS_P2P_CLIENT_MODE:
11286 case VOS_P2P_GO_MODE:
11287 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053011288 if (pHddCtx->no_of_active_sessions[mode] > 0)
11289 pHddCtx->no_of_active_sessions[mode]--;
11290 else
11291 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
11292 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053011293 break;
11294 default:
11295 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11296 break;
11297 }
11298 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11299 mode,
11300 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011301}
11302
Jeff Johnsone7245742012-09-05 17:12:55 -070011303/**---------------------------------------------------------------------------
11304 *
11305 * \brief wlan_hdd_restart_init
11306 *
11307 * This function initalizes restart timer/flag. An internal function.
11308 *
11309 * \param - pHddCtx
11310 *
11311 * \return - None
11312 *
11313 * --------------------------------------------------------------------------*/
11314
11315static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
11316{
11317 /* Initialize */
11318 pHddCtx->hdd_restart_retries = 0;
11319 atomic_set(&pHddCtx->isRestartInProgress, 0);
11320 vos_timer_init(&pHddCtx->hdd_restart_timer,
11321 VOS_TIMER_TYPE_SW,
11322 wlan_hdd_restart_timer_cb,
11323 pHddCtx);
11324}
11325/**---------------------------------------------------------------------------
11326 *
11327 * \brief wlan_hdd_restart_deinit
11328 *
11329 * This function cleans up the resources used. An internal function.
11330 *
11331 * \param - pHddCtx
11332 *
11333 * \return - None
11334 *
11335 * --------------------------------------------------------------------------*/
11336
11337static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
11338{
11339
11340 VOS_STATUS vos_status;
11341 /* Block any further calls */
11342 atomic_set(&pHddCtx->isRestartInProgress, 1);
11343 /* Cleanup */
11344 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
11345 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011346 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011347 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
11348 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011349 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011350
11351}
11352
11353/**---------------------------------------------------------------------------
11354 *
11355 * \brief wlan_hdd_framework_restart
11356 *
11357 * This function uses a cfg80211 API to start a framework initiated WLAN
11358 * driver module unload/load.
11359 *
11360 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
11361 *
11362 *
11363 * \param - pHddCtx
11364 *
11365 * \return - VOS_STATUS_SUCCESS: Success
11366 * VOS_STATUS_E_EMPTY: Adapter is Empty
11367 * VOS_STATUS_E_NOMEM: No memory
11368
11369 * --------------------------------------------------------------------------*/
11370
11371static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
11372{
11373 VOS_STATUS status = VOS_STATUS_SUCCESS;
11374 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011375 int len = (sizeof (struct ieee80211_mgmt));
11376 struct ieee80211_mgmt *mgmt = NULL;
11377
11378 /* Prepare the DEAUTH managment frame with reason code */
11379 mgmt = kzalloc(len, GFP_KERNEL);
11380 if(mgmt == NULL)
11381 {
11382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11383 "%s: memory allocation failed (%d bytes)", __func__, len);
11384 return VOS_STATUS_E_NOMEM;
11385 }
11386 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070011387
11388 /* Iterate over all adapters/devices */
11389 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011390 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
11391 {
11392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11393 FL("fail to get adapter: %p %d"), pAdapterNode, status);
11394 goto end;
11395 }
11396
Jeff Johnsone7245742012-09-05 17:12:55 -070011397 do
11398 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011399 if(pAdapterNode->pAdapter &&
11400 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070011401 {
11402 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11403 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
11404 pAdapterNode->pAdapter->dev->name,
11405 pAdapterNode->pAdapter->device_mode,
11406 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011407 /*
11408 * CFG80211 event to restart the driver
11409 *
11410 * 'cfg80211_send_unprot_deauth' sends a
11411 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
11412 * of SME(Linux Kernel) state machine.
11413 *
11414 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
11415 * the driver.
11416 *
11417 */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011418#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
11419 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
11420#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011421 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011422#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011423 }
11424 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11425 pAdapterNode = pNext;
11426 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
11427
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011428 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011429 /* Free the allocated management frame */
11430 kfree(mgmt);
11431
Jeff Johnsone7245742012-09-05 17:12:55 -070011432 /* Retry until we unload or reach max count */
11433 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
11434 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
11435
11436 return status;
11437
11438}
11439/**---------------------------------------------------------------------------
11440 *
11441 * \brief wlan_hdd_restart_timer_cb
11442 *
11443 * Restart timer callback. An internal function.
11444 *
11445 * \param - User data:
11446 *
11447 * \return - None
11448 *
11449 * --------------------------------------------------------------------------*/
11450
11451void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
11452{
11453 hdd_context_t *pHddCtx = usrDataForCallback;
11454 wlan_hdd_framework_restart(pHddCtx);
11455 return;
11456
11457}
11458
11459
11460/**---------------------------------------------------------------------------
11461 *
11462 * \brief wlan_hdd_restart_driver
11463 *
11464 * This function sends an event to supplicant to restart the WLAN driver.
11465 *
11466 * This function is called from vos_wlanRestart.
11467 *
11468 * \param - pHddCtx
11469 *
11470 * \return - VOS_STATUS_SUCCESS: Success
11471 * VOS_STATUS_E_EMPTY: Adapter is Empty
11472 * VOS_STATUS_E_ALREADY: Request already in progress
11473
11474 * --------------------------------------------------------------------------*/
11475VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
11476{
11477 VOS_STATUS status = VOS_STATUS_SUCCESS;
11478
11479 /* A tight check to make sure reentrancy */
11480 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
11481 {
Mihir Shetefd528652014-06-23 19:07:50 +053011482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070011483 "%s: WLAN restart is already in progress", __func__);
11484
11485 return VOS_STATUS_E_ALREADY;
11486 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070011487 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080011488#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053011489 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070011490#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011491
Jeff Johnsone7245742012-09-05 17:12:55 -070011492 return status;
11493}
11494
Mihir Shetee1093ba2014-01-21 20:13:32 +053011495/**---------------------------------------------------------------------------
11496 *
11497 * \brief wlan_hdd_init_channels
11498 *
11499 * This function is used to initialize the channel list in CSR
11500 *
11501 * This function is called from hdd_wlan_startup
11502 *
11503 * \param - pHddCtx: HDD context
11504 *
11505 * \return - VOS_STATUS_SUCCESS: Success
11506 * VOS_STATUS_E_FAULT: Failure reported by SME
11507
11508 * --------------------------------------------------------------------------*/
11509static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
11510{
11511 eHalStatus status;
11512
11513 status = sme_InitChannels(pHddCtx->hHal);
11514 if (HAL_STATUS_SUCCESS(status))
11515 {
11516 return VOS_STATUS_SUCCESS;
11517 }
11518 else
11519 {
11520 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
11521 __func__, status);
11522 return VOS_STATUS_E_FAULT;
11523 }
11524}
11525
Mihir Shete04206452014-11-20 17:50:58 +053011526#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011527VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011528{
11529 eHalStatus status;
11530
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011531 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011532 if (HAL_STATUS_SUCCESS(status))
11533 {
11534 return VOS_STATUS_SUCCESS;
11535 }
11536 else
11537 {
11538 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
11539 __func__, status);
11540 return VOS_STATUS_E_FAULT;
11541 }
11542}
Mihir Shete04206452014-11-20 17:50:58 +053011543#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070011544/*
11545 * API to find if there is any STA or P2P-Client is connected
11546 */
11547VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
11548{
11549 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
11550}
Jeff Johnsone7245742012-09-05 17:12:55 -070011551
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011552
11553/*
11554 * API to find if the firmware will send logs using DXE channel
11555 */
11556v_U8_t hdd_is_fw_logging_enabled(void)
11557{
11558 hdd_context_t *pHddCtx;
11559
11560 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11561 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11562
Sachin Ahuja084313e2015-05-21 17:57:10 +053011563 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011564}
11565
Agarwal Ashish57e84372014-12-05 18:26:53 +053011566/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053011567 * API to find if the firmware will send trace logs using DXE channel
11568 */
11569v_U8_t hdd_is_fw_ev_logging_enabled(void)
11570{
11571 hdd_context_t *pHddCtx;
11572
11573 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11574 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11575
11576 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
11577}
11578/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053011579 * API to find if there is any session connected
11580 */
11581VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
11582{
11583 return sme_is_any_session_connected(pHddCtx->hHal);
11584}
11585
11586
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011587int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
11588{
11589 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11590 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053011591 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053011592 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011593
11594 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053011595 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011596 if (pScanInfo->mScanPending)
11597 {
c_hpothua3d45d52015-01-05 14:11:17 +053011598 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
11599 eCSR_SCAN_ABORT_DEFAULT);
11600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11601 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011602
c_hpothua3d45d52015-01-05 14:11:17 +053011603 /* If there is active scan command lets wait for the completion else
11604 * there is no need to wait as scan command might be in the SME pending
11605 * command list.
11606 */
11607 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
11608 {
c_hpothua3d45d52015-01-05 14:11:17 +053011609 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011610 &pScanInfo->abortscan_event_var,
11611 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053011612 if (0 >= status)
11613 {
11614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053011615 "%s: Timeout or Interrupt occurred while waiting for abort"
11616 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053011617 return -ETIMEDOUT;
11618 }
11619 }
11620 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
11621 {
11622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11623 FL("hdd_abort_mac_scan failed"));
11624 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011625 }
11626 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053011627 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011628}
11629
c_hpothu225aa7c2014-10-22 17:45:13 +053011630VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
11631{
11632 hdd_adapter_t *pAdapter;
11633 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11634 VOS_STATUS vosStatus;
11635
11636 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11637 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11638 {
11639 pAdapter = pAdapterNode->pAdapter;
11640 if (NULL != pAdapter)
11641 {
11642 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
11643 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
11644 WLAN_HDD_P2P_GO == pAdapter->device_mode)
11645 {
11646 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
11647 pAdapter->device_mode);
11648 if (VOS_STATUS_SUCCESS !=
11649 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
11650 {
11651 hddLog(LOGE, FL("failed to abort ROC"));
11652 return VOS_STATUS_E_FAILURE;
11653 }
11654 }
11655 }
11656 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11657 pAdapterNode = pNext;
11658 }
11659 return VOS_STATUS_SUCCESS;
11660}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053011661
Mihir Shete0be28772015-02-17 18:42:14 +053011662hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
11663{
11664 hdd_adapter_t *pAdapter;
11665 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11666 hdd_cfg80211_state_t *cfgState;
11667 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
11668 VOS_STATUS vosStatus;
11669
11670 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
11671 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11672 {
11673 pAdapter = pAdapterNode->pAdapter;
11674 if (NULL != pAdapter)
11675 {
11676 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
11677 pRemainChanCtx = cfgState->remain_on_chan_ctx;
11678 if (pRemainChanCtx)
11679 break;
11680 }
11681 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
11682 pAdapterNode = pNext;
11683 }
11684 return pRemainChanCtx;
11685}
11686
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053011687/**
11688 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
11689 *
11690 * @pHddCtx: HDD context within host driver
11691 * @dfsScanMode: dfsScanMode passed from ioctl
11692 *
11693 */
11694
11695VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
11696 tANI_U8 dfsScanMode)
11697{
11698 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11699 hdd_adapter_t *pAdapter;
11700 VOS_STATUS vosStatus;
11701 hdd_station_ctx_t *pHddStaCtx;
11702 eHalStatus status = eHAL_STATUS_SUCCESS;
11703
11704 if(!pHddCtx)
11705 {
11706 hddLog(LOGE, FL("HDD context is Null"));
11707 return eHAL_STATUS_FAILURE;
11708 }
11709
11710 if (pHddCtx->scan_info.mScanPending)
11711 {
11712 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
11713 pHddCtx->scan_info.sessionId);
11714 hdd_abort_mac_scan(pHddCtx,
11715 pHddCtx->scan_info.sessionId,
11716 eCSR_SCAN_ABORT_DEFAULT);
11717 }
11718
11719 if (!dfsScanMode)
11720 {
11721 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11722 while ((NULL != pAdapterNode) &&
11723 (VOS_STATUS_SUCCESS == vosStatus))
11724 {
11725 pAdapter = pAdapterNode->pAdapter;
11726
11727 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11728 {
11729 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11730
11731 if(!pHddStaCtx)
11732 {
11733 hddLog(LOGE, FL("HDD STA context is Null"));
11734 return eHAL_STATUS_FAILURE;
11735 }
11736
11737 /* if STA is already connected on DFS channel,
11738 disconnect immediately*/
11739 if (hdd_connIsConnected(pHddStaCtx) &&
11740 (NV_CHANNEL_DFS ==
11741 vos_nv_getChannelEnabledState(
11742 pHddStaCtx->conn_info.operationChannel)))
11743 {
11744 status = sme_RoamDisconnect(pHddCtx->hHal,
11745 pAdapter->sessionId,
11746 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11747 hddLog(LOG1, FL("Client connected on DFS channel %d,"
11748 "sme_RoamDisconnect returned with status: %d"
11749 "for sessionid: %d"), pHddStaCtx->conn_info.
11750 operationChannel, status, pAdapter->sessionId);
11751 }
11752 }
11753
11754 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
11755 &pNext);
11756 pAdapterNode = pNext;
11757 }
11758 }
11759
11760 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
11761 sme_UpdateDFSRoamMode(pHddCtx->hHal,
11762 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
11763
11764 status = sme_HandleDFSChanScan(pHddCtx->hHal);
11765 if (!HAL_STATUS_SUCCESS(status))
11766 {
11767 hddLog(LOGE,
11768 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
11769 return status;
11770 }
11771
11772 return status;
11773}
11774
Nirav Shah7e3c8132015-06-22 23:51:42 +053011775static int hdd_log2_ceil(unsigned value)
11776{
11777 /* need to switch to unsigned math so that negative values
11778 * will right-shift towards 0 instead of -1
11779 */
11780 unsigned tmp = value;
11781 int log2 = -1;
11782
11783 if (value == 0)
11784 return 0;
11785
11786 while (tmp) {
11787 log2++;
11788 tmp >>= 1;
11789 }
11790 if (1U << log2 != value)
11791 log2++;
11792
11793 return log2;
11794}
11795
11796/**
11797 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
11798 * @pAdapter: adapter handle
11799 *
11800 * Return: vos status
11801 */
11802VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
11803{
11804 int hash_elem, log2, i;
11805
11806 spin_lock_bh( &pAdapter->sta_hash_lock);
11807 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
11808 spin_unlock_bh( &pAdapter->sta_hash_lock);
11809 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11810 "%s: hash already attached for session id %d",
11811 __func__, pAdapter->sessionId);
11812 return VOS_STATUS_SUCCESS;
11813 }
11814 spin_unlock_bh( &pAdapter->sta_hash_lock);
11815
11816 hash_elem = WLAN_MAX_STA_COUNT;
11817 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
11818 log2 = hdd_log2_ceil(hash_elem);
11819 hash_elem = 1 << log2;
11820
11821 pAdapter->sta_id_hash.mask = hash_elem - 1;
11822 pAdapter->sta_id_hash.idx_bits = log2;
11823 pAdapter->sta_id_hash.bins =
11824 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
11825 if (!pAdapter->sta_id_hash.bins) {
11826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11827 "%s: malloc failed for session %d",
11828 __func__, pAdapter->sessionId);
11829 return VOS_STATUS_E_NOMEM;
11830 }
11831
11832 for (i = 0; i < hash_elem; i++)
11833 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
11834
11835 spin_lock_bh( &pAdapter->sta_hash_lock);
11836 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
11837 spin_unlock_bh( &pAdapter->sta_hash_lock);
11838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11839 "%s: Station ID Hash attached for session id %d",
11840 __func__, pAdapter->sessionId);
11841
11842 return VOS_STATUS_SUCCESS;
11843}
11844
11845/**
11846 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
11847 * @pAdapter: adapter handle
11848 *
11849 * Return: vos status
11850 */
11851VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
11852{
11853 int hash_elem, i;
11854 v_SIZE_t size;
11855
11856 spin_lock_bh( &pAdapter->sta_hash_lock);
11857 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11858 spin_unlock_bh( &pAdapter->sta_hash_lock);
11859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11860 "%s: hash not initialized for session id %d",
11861 __func__, pAdapter->sessionId);
11862 return VOS_STATUS_SUCCESS;
11863 }
11864
11865 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
11866 spin_unlock_bh( &pAdapter->sta_hash_lock);
11867
11868 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
11869
11870 /* free all station info*/
11871 for (i = 0; i < hash_elem; i++) {
11872 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
11873 if (size != 0) {
11874 VOS_STATUS status;
11875 hdd_staid_hash_node_t *sta_info_node = NULL;
11876 hdd_staid_hash_node_t *next_node = NULL;
11877 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
11878 (hdd_list_node_t**) &sta_info_node );
11879
11880 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11881 {
11882 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
11883 &sta_info_node->node);
11884 vos_mem_free(sta_info_node);
11885
11886 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
11887 (hdd_list_node_t*)sta_info_node,
11888 (hdd_list_node_t**)&next_node);
11889 sta_info_node = next_node;
11890 }
11891 }
11892 }
11893
11894 vos_mem_free(pAdapter->sta_id_hash.bins);
11895 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11896 "%s: Station ID Hash detached for session id %d",
11897 __func__, pAdapter->sessionId);
11898 return VOS_STATUS_SUCCESS;
11899}
11900
11901/**
11902 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
11903 * @pAdapter: adapter handle
11904 * @mac_addr_in: input mac address
11905 *
11906 * Return: index derived from mac address
11907 */
11908int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
11909 v_MACADDR_t *mac_addr_in)
11910{
11911 uint16 index;
11912 struct hdd_align_mac_addr_t * mac_addr =
11913 (struct hdd_align_mac_addr_t *)mac_addr_in;
11914
11915 index = mac_addr->bytes_ab ^
11916 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
11917 index ^= index >> pAdapter->sta_id_hash.idx_bits;
11918 index &= pAdapter->sta_id_hash.mask;
11919 return index;
11920}
11921
11922/**
11923 * hdd_sta_id_hash_add_entry() - add entry in hash
11924 * @pAdapter: adapter handle
11925 * @sta_id: station id
11926 * @mac_addr: mac address
11927 *
11928 * Return: vos status
11929 */
11930VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
11931 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11932{
11933 uint16 index;
11934 hdd_staid_hash_node_t *sta_info_node = NULL;
11935
Nirav Shah7e3c8132015-06-22 23:51:42 +053011936 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11937 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
11938 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053011939 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11940 "%s: malloc failed", __func__);
11941 return VOS_STATUS_E_NOMEM;
11942 }
11943
11944 sta_info_node->sta_id = sta_id;
11945 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
11946
Nirav Shah303ed5c2015-08-24 10:29:25 +053011947 spin_lock_bh( &pAdapter->sta_hash_lock);
11948 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11949 spin_unlock_bh( &pAdapter->sta_hash_lock);
11950 vos_mem_free(sta_info_node);
11951 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11952 "%s: hash is not initialized for session id %d",
11953 __func__, pAdapter->sessionId);
11954 return VOS_STATUS_E_FAILURE;
11955 }
11956
Nirav Shah7e3c8132015-06-22 23:51:42 +053011957 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
11958 (hdd_list_node_t*) sta_info_node );
11959 spin_unlock_bh( &pAdapter->sta_hash_lock);
11960 return VOS_STATUS_SUCCESS;
11961}
11962
11963/**
11964 * hdd_sta_id_hash_remove_entry() - remove entry from hash
11965 * @pAdapter: adapter handle
11966 * @sta_id: station id
11967 * @mac_addr: mac address
11968 *
11969 * Return: vos status
11970 */
11971VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
11972 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11973{
11974 uint16 index;
11975 VOS_STATUS status;
11976 hdd_staid_hash_node_t *sta_info_node = NULL;
11977 hdd_staid_hash_node_t *next_node = NULL;
11978
11979 spin_lock_bh( &pAdapter->sta_hash_lock);
11980 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11981 spin_unlock_bh( &pAdapter->sta_hash_lock);
11982 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11983 "%s: hash is not initialized for session id %d",
11984 __func__, pAdapter->sessionId);
11985 return VOS_STATUS_E_FAILURE;
11986 }
11987
11988 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11989 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11990 (hdd_list_node_t**) &sta_info_node );
11991
11992 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11993 {
11994 if (sta_info_node->sta_id == sta_id) {
11995 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
11996 &sta_info_node->node);
11997 vos_mem_free(sta_info_node);
11998 break;
11999 }
12000 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
12001 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
12002 sta_info_node = next_node;
12003 }
12004 spin_unlock_bh( &pAdapter->sta_hash_lock);
12005 return status;
12006}
12007
12008/**
12009 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
12010 * @pAdapter: adapter handle
12011 * @mac_addr_in: mac address
12012 *
12013 * Return: station id
12014 */
12015int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
12016 v_MACADDR_t *mac_addr_in)
12017{
12018 uint8 is_found = 0;
12019 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
12020 uint16 index;
12021 VOS_STATUS status;
12022 hdd_staid_hash_node_t *sta_info_node = NULL;
12023 hdd_staid_hash_node_t *next_node = NULL;
12024
12025 spin_lock_bh( &pAdapter->sta_hash_lock);
12026 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
12027 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053012028 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053012029 FL("hash is not initialized for session id %d"),
12030 pAdapter->sessionId);
12031 return HDD_WLAN_INVALID_STA_ID;
12032 }
12033
12034 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
12035 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
12036 (hdd_list_node_t**) &sta_info_node );
12037
12038 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
12039 {
12040 if (vos_mem_compare(&sta_info_node->mac_addr,
12041 mac_addr_in, sizeof(v_MACADDR_t))) {
12042 is_found = 1;
12043 sta_id = sta_info_node->sta_id;
12044 break;
12045 }
12046 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
12047 (hdd_list_node_t*)sta_info_node,
12048 (hdd_list_node_t**)&next_node);
12049 sta_info_node = next_node;
12050 }
12051 spin_unlock_bh( &pAdapter->sta_hash_lock);
12052 return sta_id;
12053}
12054
c_manjeecfd1efb2015-09-25 19:32:34 +053012055/*FW memory dump feature*/
12056/**
12057 * This structure hold information about the /proc file
12058 *
12059 */
12060static struct proc_dir_entry *proc_file, *proc_dir;
12061
12062/**
12063 * memdump_read() - perform read operation in memory dump proc file
12064 *
12065 * @file - handle for the proc file.
12066 * @buf - pointer to user space buffer.
12067 * @count - number of bytes to be read.
12068 * @pos - offset in the from buffer.
12069 *
12070 * This function performs read operation for the memory dump proc file.
12071 *
12072 * Return: number of bytes read on success, error code otherwise.
12073 */
12074static ssize_t memdump_read(struct file *file, char __user *buf,
12075 size_t count, loff_t *pos)
12076{
12077 int status;
12078 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
12079 size_t ret_count;
12080 ENTER();
12081
12082 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
12083 status = wlan_hdd_validate_context(hdd_ctx);
12084 if (0 != status) {
12085 return -EINVAL;
12086 }
12087
12088 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
12089 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
12090 return -EINVAL;
12091 }
12092
12093 /* run fs_read_handler in an atomic context*/
12094 vos_ssr_protect(__func__);
12095 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos);
12096 if(ret_count == 0)
12097 {
12098 /*Free the fwr mem dump buffer */
12099 wlan_free_fwr_mem_dump_buffer();
12100 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
12101 }
12102 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
12103 vos_ssr_unprotect(__func__);
12104 EXIT();
12105 return ret_count;
12106}
12107
12108/**
12109 * struct memdump_fops - file operations for memory dump feature
12110 * @read - read function for memory dump operation.
12111 *
12112 * This structure initialize the file operation handle for memory
12113 * dump feature
12114 */
12115static const struct file_operations memdump_fops = {
12116 read: memdump_read
12117};
12118
12119/*
12120* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
12121* To be passed by HDD to WDA and called upon receiving of response
12122* from firmware
12123* @fwMemDumpReqContext : memory dump request context
12124* @dump_rsp : dump response from HAL
12125* Returns none
12126*/
12127void wlan_hdd_fw_mem_dump_cb(void *fwMemDumpReqContext,
12128 tAniFwrDumpRsp *dump_rsp)
12129{
12130 hdd_context_t *pHddCtx = (hdd_context_t *)fwMemDumpReqContext;
12131 int status;
12132 ENTER();
12133 status = wlan_hdd_validate_context(pHddCtx);
12134 if (0 != status) {
12135 return;
12136 }
12137
12138 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
12139 hddLog(LOGE, FL("fw dump request declined by fwr"));
12140 //report failure to user space
12141 wlan_indicate_mem_dump_complete(false);
12142 //Free the allocated fwr dump
12143 wlan_free_fwr_mem_dump_buffer();
12144 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
12145 return;
12146 }
12147 else
12148 hddLog(LOG1, FL("fw dump request accepted by fwr"));
12149 EXIT();
12150
12151}
12152
12153/**
12154 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
12155 *
12156 * This function removes file/dir under proc file system that was
12157 * processing firmware memory dump
12158 *
12159 * Return: None
12160 */
12161static void memdump_procfs_remove(void)
12162{
12163 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
12164 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
12165 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
12166 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
12167 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
12168}
12169
12170/**
12171 * memdump_procfs_init() - Initialize procfs for memory dump
12172 *
12173 * @vos_ctx - Global vos context.
12174 *
12175 * This function create file under proc file system to be used later for
12176 * processing firmware memory dump
12177 *
12178 * Return: 0 on success, error code otherwise.
12179 */
12180static int memdump_procfs_init(void *vos_ctx)
12181{
12182 hdd_context_t *hdd_ctx;
12183
12184 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
12185 if (!hdd_ctx) {
12186 hddLog(LOGE , FL("Invalid HDD context"));
12187 return -EINVAL;
12188 }
12189
12190 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
12191 if (proc_dir == NULL) {
12192 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
12193 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
12194 PROCFS_MEMDUMP_DIR);
12195 return -ENOMEM;
12196 }
12197
12198 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
12199 S_IRUSR | S_IWUSR, proc_dir,
12200 &memdump_fops, hdd_ctx);
12201 if (proc_file == NULL) {
12202 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
12203 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
12204 PROCFS_MEMDUMP_NAME);
12205 return -ENOMEM;
12206 }
12207
12208 hddLog(LOG1 , FL("/proc/%s/%s created"),
12209 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
12210
12211 return 0;
12212}
12213
12214/**
12215 * memdump_init() - Initialization function for memory dump feature
12216 *
12217 * This function creates proc file for memdump feature and registers
12218 * HDD callback function with SME.
12219 *
12220 * Return - 0 on success, error otherwise
12221 */
12222int memdump_init(void)
12223{
12224 hdd_context_t *hdd_ctx;
12225 void *vos_ctx;
12226 int status = 0;
12227
12228 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12229 if (!vos_ctx) {
12230 hddLog(LOGE, FL("Invalid VOS context"));
12231 return -EINVAL;
12232 }
12233
12234 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
12235 if (!hdd_ctx) {
12236 hddLog(LOGE , FL("Invalid HDD context"));
12237 return -EINVAL;
12238 }
12239
12240 status = memdump_procfs_init(vos_ctx);
12241 if (status) {
12242 hddLog(LOGE , FL("Failed to create proc file"));
12243 return status;
12244 }
12245
12246 return 0;
12247}
12248
12249/**
12250 * memdump_deinit() - De initialize memdump feature
12251 *
12252 * This function removes proc file created for memdump feature.
12253 *
12254 * Return: None
12255 */
12256int memdump_deinit(void)
12257{
12258 hdd_context_t *hdd_ctx;
12259 void *vos_ctx;
12260
12261 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12262 if (!vos_ctx) {
12263 hddLog(LOGE, FL("Invalid VOS context"));
12264 return -EINVAL;
12265 }
12266
12267 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
12268 if(!hdd_ctx) {
12269 hddLog(LOGE , FL("Invalid HDD context"));
12270 return -EINVAL;
12271 }
12272
12273 memdump_procfs_remove();
12274 return 0;
12275}
12276
12277/**
12278 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
12279 * Return: HAL status
12280 */
12281
12282int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
12283{
12284 tAniFwrDumpReq fw_mem_dump_req={0};
12285 eHalStatus status = eHAL_STATUS_FAILURE;
12286 int ret=0;
12287 ENTER();
12288 /*Check whether a dump request is already going on
12289 *Caution this function will free previously held memory if new dump request is allowed*/
12290 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
12291 hddLog(LOGE, FL("Fw memdump already in progress"));
12292 return -EBUSY;
12293 }
12294 //Allocate memory for fw mem dump buffer
12295 ret = wlan_fwr_mem_dump_buffer_allocation();
12296 if(ret == -EFAULT)
12297 {
12298 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
12299 return ret;
12300 }
12301 if (0 != ret) {
12302 hddLog(LOGE, FL("Fwr mem Allocation failed"));
12303 return -ENOMEM;
12304 }
12305 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
12306 fw_mem_dump_req.fwMemDumpReqContext = pHddCtx;
12307 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
12308 if(eHAL_STATUS_SUCCESS != status)
12309 {
12310 hddLog(VOS_TRACE_LEVEL_ERROR,
12311 "%s: fw_mem_dump_req failed ", __func__);
12312 wlan_free_fwr_mem_dump_buffer();
12313 }
12314 EXIT();
12315
12316 return status;
12317}
12318
12319
12320
Jeff Johnson295189b2012-06-20 16:38:30 -070012321//Register the module init/exit functions
12322module_init(hdd_module_init);
12323module_exit(hdd_module_exit);
12324
12325MODULE_LICENSE("Dual BSD/GPL");
12326MODULE_AUTHOR("Qualcomm Atheros, Inc.");
12327MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
12328
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012329module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
12330 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070012331
Jeff Johnson76052702013-04-16 13:55:05 -070012332module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070012333 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080012334
12335module_param(enable_dfs_chan_scan, int,
12336 S_IRUSR | S_IRGRP | S_IROTH);
12337
12338module_param(enable_11d, int,
12339 S_IRUSR | S_IRGRP | S_IROTH);
12340
12341module_param(country_code, charp,
12342 S_IRUSR | S_IRGRP | S_IROTH);