blob: 4b0ed43451e632edc0fb36a3f7cb7a14fe83c0cf [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
2230
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302231
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002232static int hdd_driver_command(hdd_adapter_t *pAdapter,
2233 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002234{
Jeff Johnson295189b2012-06-20 16:38:30 -07002235 hdd_priv_data_t priv_data;
2236 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302237 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2238 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002239 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302240 int status;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05302241#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
2242 struct cfg80211_mgmt_tx_params params;
2243#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302244
2245 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002246 /*
2247 * Note that valid pointers are provided by caller
2248 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002249
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002250 /* copy to local struct to avoid numerous changes to legacy code */
2251 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002252
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002253 if (priv_data.total_len <= 0 ||
2254 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002255 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002256 hddLog(VOS_TRACE_LEVEL_WARN,
2257 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2258 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002259 ret = -EINVAL;
2260 goto exit;
2261 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302262 status = wlan_hdd_validate_context(pHddCtx);
2263 if (0 != status)
2264 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302265 ret = -EINVAL;
2266 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302267 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002268 /* Allocate +1 for '\0' */
2269 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002270 if (!command)
2271 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002272 hddLog(VOS_TRACE_LEVEL_ERROR,
2273 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002274 ret = -ENOMEM;
2275 goto exit;
2276 }
2277
2278 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2279 {
2280 ret = -EFAULT;
2281 goto exit;
2282 }
2283
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002284 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002285 command[priv_data.total_len] = '\0';
2286
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002287 /* at one time the following block of code was conditional. braces
2288 * have been retained to avoid re-indenting the legacy code
2289 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002290 {
2291 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2292
2293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002294 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002295
2296 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2297 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302298 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2299 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2300 pAdapter->sessionId, (unsigned)
2301 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2302 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2303 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2304 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002305 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2306 sizeof(tSirMacAddr)))
2307 {
2308 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002309 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002310 ret = -EFAULT;
2311 }
2312 }
Amar Singhal0974e402013-02-12 14:27:46 -08002313 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002314 {
Amar Singhal0974e402013-02-12 14:27:46 -08002315 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002316
Jeff Johnson295189b2012-06-20 16:38:30 -07002317 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002318
2319 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002320 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002322 "%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 +05302323 if(VOS_FTM_MODE != hdd_get_conparam())
2324 {
2325 /* Change band request received */
2326 ret = hdd_setBand_helper(pAdapter->dev, ptr);
2327 if(ret < 0)
2328 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2329 "%s: failed to set band ret=%d", __func__, ret);
2330 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002331 }
Kiet Lamf040f472013-11-20 21:15:23 +05302332 else if(strncmp(command, "SETWMMPS", 8) == 0)
2333 {
2334 tANI_U8 *ptr = command;
2335 ret = hdd_wmmps_helper(pAdapter, ptr);
2336 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05302337
2338 else if(strncmp(command, "TDLSSCAN", 8) == 0)
2339 {
2340 tANI_U8 *ptr = command;
2341 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
2342 }
2343
Jeff Johnson32d95a32012-09-10 13:15:23 -07002344 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2345 {
2346 char *country_code;
2347
2348 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002349
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002350 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002351 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002352#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302353 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002354#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002355 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2356 (void *)(tSmeChangeCountryCallback)
2357 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302358 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002359 if (eHAL_STATUS_SUCCESS == ret)
2360 {
2361 ret = wait_for_completion_interruptible_timeout(
2362 &pAdapter->change_country_code,
2363 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2364 if (0 >= ret)
2365 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002366 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302367 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002368 }
2369 }
2370 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002371 {
2372 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002373 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002374 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002375 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002376
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002377 }
2378 /*
2379 command should be a string having format
2380 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2381 */
Amar Singhal0974e402013-02-12 14:27:46 -08002382 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002383 {
Amar Singhal0974e402013-02-12 14:27:46 -08002384 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002385
2386 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002387 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002388
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002389 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002390 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002391 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2392 {
2393 int suspend = 0;
2394 tANI_U8 *ptr = (tANI_U8*)command + 15;
2395
2396 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302397 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2398 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2399 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002400 hdd_set_wlan_suspend_mode(suspend);
2401 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002402#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2403 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2404 {
2405 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002406 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002407 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2408 eHalStatus status = eHAL_STATUS_SUCCESS;
2409
2410 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2411 value = value + 15;
2412
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002413 /* Convert the value from ascii to integer */
2414 ret = kstrtos8(value, 10, &rssi);
2415 if (ret < 0)
2416 {
2417 /* If the input value is greater than max value of datatype, then also
2418 kstrtou8 fails */
2419 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2420 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002421 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002422 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2423 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2424 ret = -EINVAL;
2425 goto exit;
2426 }
2427
Srinivas Girigowdade697412013-02-14 16:31:48 -08002428 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002429
Srinivas Girigowdade697412013-02-14 16:31:48 -08002430 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2431 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2432 {
2433 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2434 "Neighbor lookup threshold value %d is out of range"
2435 " (Min: %d Max: %d)", lookUpThreshold,
2436 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2437 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2438 ret = -EINVAL;
2439 goto exit;
2440 }
2441
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302442 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2443 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2444 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002445 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2446 "%s: Received Command to Set Roam trigger"
2447 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2448
2449 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2450 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2451 if (eHAL_STATUS_SUCCESS != status)
2452 {
2453 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2454 "%s: Failed to set roam trigger, try again", __func__);
2455 ret = -EPERM;
2456 goto exit;
2457 }
2458
2459 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302460 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002461 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2462 }
2463 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2464 {
2465 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2466 int rssi = (-1) * lookUpThreshold;
2467 char extra[32];
2468 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302469 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2470 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2471 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002472 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05302473 len = VOS_MIN(priv_data.total_len, len + 1);
2474 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002475 {
2476 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2477 "%s: failed to copy data to user buffer", __func__);
2478 ret = -EFAULT;
2479 goto exit;
2480 }
2481 }
2482 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2483 {
2484 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002485 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002486 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002487
Srinivas Girigowdade697412013-02-14 16:31:48 -08002488 /* input refresh period is in terms of seconds */
2489 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2490 value = value + 18;
2491 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002492 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002493 if (ret < 0)
2494 {
2495 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002496 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002497 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002498 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002499 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002500 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2501 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002502 ret = -EINVAL;
2503 goto exit;
2504 }
2505
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002506 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2507 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002508 {
2509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002510 "Roam scan period value %d is out of range"
2511 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002512 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2513 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002514 ret = -EINVAL;
2515 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302516 }
2517 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2518 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2519 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002520 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002521
2522 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2523 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002524 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002525
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002526 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2527 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002528 }
2529 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2530 {
2531 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2532 char extra[32];
2533 tANI_U8 len = 0;
2534
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302535 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2536 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2537 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002538 len = scnprintf(extra, sizeof(extra), "%s %d",
2539 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002540 /* Returned value is in units of seconds */
Ratnam Rachuria72ba112015-07-17 13:27:03 +05302541 len = VOS_MIN(priv_data.total_len, len + 1);
2542 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08002543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2544 "%s: failed to copy data to user buffer", __func__);
2545 ret = -EFAULT;
2546 goto exit;
2547 }
2548 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002549 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2550 {
2551 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002552 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002553 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002554
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002555 /* input refresh period is in terms of seconds */
2556 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2557 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002558
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002559 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002560 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002561 if (ret < 0)
2562 {
2563 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002564 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002566 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002567 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002568 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2569 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2570 ret = -EINVAL;
2571 goto exit;
2572 }
2573
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002574 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2575 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2576 {
2577 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2578 "Neighbor scan results refresh period value %d is out of range"
2579 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2580 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2581 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2582 ret = -EINVAL;
2583 goto exit;
2584 }
2585 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2586
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2588 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002589 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002590
2591 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2592 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2593 }
2594 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2595 {
2596 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2597 char extra[32];
2598 tANI_U8 len = 0;
2599
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002600 len = scnprintf(extra, sizeof(extra), "%s %d",
2601 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002602 /* Returned value is in units of seconds */
Ratnam Rachuri2c9d6702015-07-17 13:25:16 +05302603 len = VOS_MIN(priv_data.total_len, len + 1);
2604 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2606 "%s: failed to copy data to user buffer", __func__);
2607 ret = -EFAULT;
2608 goto exit;
2609 }
2610 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002611#ifdef FEATURE_WLAN_LFR
2612 /* SETROAMMODE */
2613 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2614 {
2615 tANI_U8 *value = command;
2616 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2617
2618 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2619 value = value + SIZE_OF_SETROAMMODE + 1;
2620
2621 /* Convert the value from ascii to integer */
2622 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2623 if (ret < 0)
2624 {
2625 /* If the input value is greater than max value of datatype, then also
2626 kstrtou8 fails */
2627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2628 "%s: kstrtou8 failed range [%d - %d]", __func__,
2629 CFG_LFR_FEATURE_ENABLED_MIN,
2630 CFG_LFR_FEATURE_ENABLED_MAX);
2631 ret = -EINVAL;
2632 goto exit;
2633 }
2634 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2635 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2636 {
2637 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2638 "Roam Mode value %d is out of range"
2639 " (Min: %d Max: %d)", roamMode,
2640 CFG_LFR_FEATURE_ENABLED_MIN,
2641 CFG_LFR_FEATURE_ENABLED_MAX);
2642 ret = -EINVAL;
2643 goto exit;
2644 }
2645
2646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2647 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2648 /*
2649 * Note that
2650 * SETROAMMODE 0 is to enable LFR while
2651 * SETROAMMODE 1 is to disable LFR, but
2652 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2653 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2654 */
2655 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2656 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2657 else
2658 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2659
2660 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2661 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2662 }
2663 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302664 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002665 {
2666 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2667 char extra[32];
2668 tANI_U8 len = 0;
2669
2670 /*
2671 * roamMode value shall be inverted because the sementics is different.
2672 */
2673 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2674 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2675 else
2676 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2677
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002678 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Ratnam Rachuri28693eb2015-07-17 13:23:42 +05302679 len = VOS_MIN(priv_data.total_len, len + 1);
2680 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002681 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2682 "%s: failed to copy data to user buffer", __func__);
2683 ret = -EFAULT;
2684 goto exit;
2685 }
2686 }
2687#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002688#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002689#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002690 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2691 {
2692 tANI_U8 *value = command;
2693 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2694
2695 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2696 value = value + 13;
2697 /* Convert the value from ascii to integer */
2698 ret = kstrtou8(value, 10, &roamRssiDiff);
2699 if (ret < 0)
2700 {
2701 /* If the input value is greater than max value of datatype, then also
2702 kstrtou8 fails */
2703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2704 "%s: kstrtou8 failed range [%d - %d]", __func__,
2705 CFG_ROAM_RSSI_DIFF_MIN,
2706 CFG_ROAM_RSSI_DIFF_MAX);
2707 ret = -EINVAL;
2708 goto exit;
2709 }
2710
2711 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2712 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2713 {
2714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2715 "Roam rssi diff value %d is out of range"
2716 " (Min: %d Max: %d)", roamRssiDiff,
2717 CFG_ROAM_RSSI_DIFF_MIN,
2718 CFG_ROAM_RSSI_DIFF_MAX);
2719 ret = -EINVAL;
2720 goto exit;
2721 }
2722
2723 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2724 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2725
2726 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2727 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2728 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302729 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002730 {
2731 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2732 char extra[32];
2733 tANI_U8 len = 0;
2734
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302735 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2736 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2737 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002738 len = scnprintf(extra, sizeof(extra), "%s %d",
2739 command, roamRssiDiff);
Ratnam Rachuri22a3b402015-07-17 13:21:49 +05302740 len = VOS_MIN(priv_data.total_len, len + 1);
2741 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08002742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2743 "%s: failed to copy data to user buffer", __func__);
2744 ret = -EFAULT;
2745 goto exit;
2746 }
2747 }
2748#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002749#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002750 else if (strncmp(command, "GETBAND", 7) == 0)
2751 {
2752 int band = -1;
2753 char extra[32];
2754 tANI_U8 len = 0;
2755 hdd_getBand_helper(pHddCtx, &band);
2756
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302757 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2758 TRACE_CODE_HDD_GETBAND_IOCTL,
2759 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002760 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Ratnam Rachuri52139592015-07-17 13:17:29 +05302761 len = VOS_MIN(priv_data.total_len, len + 1);
2762 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08002763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2764 "%s: failed to copy data to user buffer", __func__);
2765 ret = -EFAULT;
2766 goto exit;
2767 }
2768 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002769 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2770 {
2771 tANI_U8 *value = command;
2772 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2773 tANI_U8 numChannels = 0;
2774 eHalStatus status = eHAL_STATUS_SUCCESS;
2775
2776 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2777 if (eHAL_STATUS_SUCCESS != status)
2778 {
2779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2780 "%s: Failed to parse channel list information", __func__);
2781 ret = -EINVAL;
2782 goto exit;
2783 }
2784
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302785 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2786 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2787 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002788 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2789 {
2790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2791 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2792 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2793 ret = -EINVAL;
2794 goto exit;
2795 }
2796 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2797 numChannels);
2798 if (eHAL_STATUS_SUCCESS != status)
2799 {
2800 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2801 "%s: Failed to update channel list information", __func__);
2802 ret = -EINVAL;
2803 goto exit;
2804 }
2805 }
2806 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2807 {
2808 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2809 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002810 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002811 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002812 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002813
2814 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2815 ChannelList, &numChannels ))
2816 {
2817 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2818 "%s: failed to get roam scan channel list", __func__);
2819 ret = -EFAULT;
2820 goto exit;
2821 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302822 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2823 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2824 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002825 /* output channel list is of the format
2826 [Number of roam scan channels][Channel1][Channel2]... */
2827 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002828 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002829 for (j = 0; (j < numChannels); j++)
2830 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002831 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2832 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002833 }
2834
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05302835 len = VOS_MIN(priv_data.total_len, len + 1);
2836 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002837 {
2838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2839 "%s: failed to copy data to user buffer", __func__);
2840 ret = -EFAULT;
2841 goto exit;
2842 }
2843 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002844 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2845 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002846 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002847 char extra[32];
2848 tANI_U8 len = 0;
2849
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002850 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002851 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002852 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002853 hdd_is_okc_mode_enabled(pHddCtx) &&
2854 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2855 {
2856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002857 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002858 " hence this operation is not permitted!", __func__);
2859 ret = -EPERM;
2860 goto exit;
2861 }
2862
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002863 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002864 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05302865 len = VOS_MIN(priv_data.total_len, len + 1);
2866 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002867 {
2868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2869 "%s: failed to copy data to user buffer", __func__);
2870 ret = -EFAULT;
2871 goto exit;
2872 }
2873 }
2874 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2875 {
2876 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2877 char extra[32];
2878 tANI_U8 len = 0;
2879
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002880 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002881 then this operation is not permitted (return FAILURE) */
2882 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002883 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002884 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2885 {
2886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002887 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002888 " hence this operation is not permitted!", __func__);
2889 ret = -EPERM;
2890 goto exit;
2891 }
2892
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002893 len = scnprintf(extra, sizeof(extra), "%s %d",
2894 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05302895 len = VOS_MIN(priv_data.total_len, len + 1);
2896 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002897 {
2898 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2899 "%s: failed to copy data to user buffer", __func__);
2900 ret = -EFAULT;
2901 goto exit;
2902 }
2903 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002904 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002905 {
2906 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2907 char extra[32];
2908 tANI_U8 len = 0;
2909
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002910 len = scnprintf(extra, sizeof(extra), "%s %d",
2911 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05302912 len = VOS_MIN(priv_data.total_len, len + 1);
2913 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002914 {
2915 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2916 "%s: failed to copy data to user buffer", __func__);
2917 ret = -EFAULT;
2918 goto exit;
2919 }
2920 }
2921 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2922 {
2923 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2924 char extra[32];
2925 tANI_U8 len = 0;
2926
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002927 len = scnprintf(extra, sizeof(extra), "%s %d",
2928 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05302929 len = VOS_MIN(priv_data.total_len, len + 1);
2930 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002931 {
2932 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2933 "%s: failed to copy data to user buffer", __func__);
2934 ret = -EFAULT;
2935 goto exit;
2936 }
2937 }
2938 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2939 {
2940 tANI_U8 *value = command;
2941 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2942
2943 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2944 value = value + 26;
2945 /* Convert the value from ascii to integer */
2946 ret = kstrtou8(value, 10, &minTime);
2947 if (ret < 0)
2948 {
2949 /* If the input value is greater than max value of datatype, then also
2950 kstrtou8 fails */
2951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2952 "%s: kstrtou8 failed range [%d - %d]", __func__,
2953 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2954 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2955 ret = -EINVAL;
2956 goto exit;
2957 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002958 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2959 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2960 {
2961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2962 "scan min channel time value %d is out of range"
2963 " (Min: %d Max: %d)", minTime,
2964 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2965 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2966 ret = -EINVAL;
2967 goto exit;
2968 }
2969
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302970 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2971 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2972 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002973 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2974 "%s: Received Command to change channel min time = %d", __func__, minTime);
2975
2976 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2977 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2978 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002979 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2980 {
2981 tANI_U8 *value = command;
2982 tANI_U8 channel = 0;
2983 tANI_U8 dwellTime = 0;
2984 tANI_U8 bufLen = 0;
2985 tANI_U8 *buf = NULL;
2986 tSirMacAddr targetApBssid;
2987 eHalStatus status = eHAL_STATUS_SUCCESS;
2988 struct ieee80211_channel chan;
2989 tANI_U8 finalLen = 0;
2990 tANI_U8 *finalBuf = NULL;
2991 tANI_U8 temp = 0;
2992 u64 cookie;
2993 hdd_station_ctx_t *pHddStaCtx = NULL;
2994 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2995
2996 /* if not associated, no need to send action frame */
2997 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2998 {
2999 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3000 ret = -EINVAL;
3001 goto exit;
3002 }
3003
3004 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
3005 &dwellTime, &buf, &bufLen);
3006 if (eHAL_STATUS_SUCCESS != status)
3007 {
3008 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3009 "%s: Failed to parse send action frame data", __func__);
3010 ret = -EINVAL;
3011 goto exit;
3012 }
3013
3014 /* if the target bssid is different from currently associated AP,
3015 then no need to send action frame */
3016 if (VOS_TRUE != vos_mem_compare(targetApBssid,
3017 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3018 {
3019 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
3020 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003021 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003022 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003023 goto exit;
3024 }
3025
3026 /* if the channel number is different from operating channel then
3027 no need to send action frame */
3028 if (channel != pHddStaCtx->conn_info.operationChannel)
3029 {
3030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3031 "%s: channel(%d) is different from operating channel(%d)",
3032 __func__, channel, pHddStaCtx->conn_info.operationChannel);
3033 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003034 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003035 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003036 goto exit;
3037 }
3038 chan.center_freq = sme_ChnToFreq(channel);
3039
3040 finalLen = bufLen + 24;
3041 finalBuf = vos_mem_malloc(finalLen);
3042 if (NULL == finalBuf)
3043 {
3044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
3045 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07003046 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003047 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003048 goto exit;
3049 }
3050 vos_mem_zero(finalBuf, finalLen);
3051
3052 /* Fill subtype */
3053 temp = SIR_MAC_MGMT_ACTION << 4;
3054 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3055
3056 /* Fill type */
3057 temp = SIR_MAC_MGMT_FRAME;
3058 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3059
3060 /* Fill destination address (bssid of the AP) */
3061 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3062
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003063 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003064 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3065
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003066 /* Fill BSSID (AP mac address) */
3067 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003068
3069 /* Fill received buffer from 24th address */
3070 vos_mem_copy(finalBuf + 24, buf, bufLen);
3071
Jeff Johnson11c33152013-04-16 17:52:40 -07003072 /* done with the parsed buffer */
3073 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003074 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003075
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303076#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3077 params.chan = &chan;
3078 params.offchan = 0;
3079 params.wait = dwellTime;
3080 params.buf = finalBuf;
3081 params.len = finalLen;
3082 params.no_cck = 1;
3083 params.dont_wait_for_ack = 1;
3084 ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
3085#else
DARAM SUDHA39eede62014-02-12 11:16:40 +05303086 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003087#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3088 &(pAdapter->wdev),
3089#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003090 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003091#endif
3092 &chan, 0,
3093#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3094 NL80211_CHAN_HT20, 1,
3095#endif
3096 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003097 1, &cookie );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303098#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003099 vos_mem_free(finalBuf);
3100 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003101 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3102 {
3103 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3104 char extra[32];
3105 tANI_U8 len = 0;
3106
3107 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003108 len = scnprintf(extra, sizeof(extra), "%s %d",
3109 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303110 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3111 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3112 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05303113 len = VOS_MIN(priv_data.total_len, len + 1);
3114 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003115 {
3116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3117 "%s: failed to copy data to user buffer", __func__);
3118 ret = -EFAULT;
3119 goto exit;
3120 }
3121 }
3122 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3123 {
3124 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003125 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003126
3127 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3128 value = value + 19;
3129 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003130 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003131 if (ret < 0)
3132 {
3133 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003134 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003136 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003137 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3138 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3139 ret = -EINVAL;
3140 goto exit;
3141 }
3142
3143 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3144 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3145 {
3146 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3147 "lfr mode value %d is out of range"
3148 " (Min: %d Max: %d)", maxTime,
3149 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3150 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3151 ret = -EINVAL;
3152 goto exit;
3153 }
3154
3155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3156 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3157
3158 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3159 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3160 }
3161 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3162 {
3163 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3164 char extra[32];
3165 tANI_U8 len = 0;
3166
3167 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003168 len = scnprintf(extra, sizeof(extra), "%s %d",
3169 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05303170 len = VOS_MIN(priv_data.total_len, len + 1);
3171 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003172 {
3173 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3174 "%s: failed to copy data to user buffer", __func__);
3175 ret = -EFAULT;
3176 goto exit;
3177 }
3178 }
3179 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3180 {
3181 tANI_U8 *value = command;
3182 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3183
3184 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3185 value = value + 16;
3186 /* Convert the value from ascii to integer */
3187 ret = kstrtou16(value, 10, &val);
3188 if (ret < 0)
3189 {
3190 /* If the input value is greater than max value of datatype, then also
3191 kstrtou16 fails */
3192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3193 "%s: kstrtou16 failed range [%d - %d]", __func__,
3194 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3195 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3196 ret = -EINVAL;
3197 goto exit;
3198 }
3199
3200 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3201 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3202 {
3203 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3204 "scan home time value %d is out of range"
3205 " (Min: %d Max: %d)", val,
3206 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3207 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3208 ret = -EINVAL;
3209 goto exit;
3210 }
3211
3212 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3213 "%s: Received Command to change scan home time = %d", __func__, val);
3214
3215 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3216 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3217 }
3218 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3219 {
3220 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3221 char extra[32];
3222 tANI_U8 len = 0;
3223
3224 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003225 len = scnprintf(extra, sizeof(extra), "%s %d",
3226 "GETSCANHOMETIME", val);
Ratheesh S P728d7c62015-07-16 15:38:58 +05303227 len = VOS_MIN(priv_data.total_len, len + 1);
3228 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003229 {
3230 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3231 "%s: failed to copy data to user buffer", __func__);
3232 ret = -EFAULT;
3233 goto exit;
3234 }
3235 }
3236 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3237 {
3238 tANI_U8 *value = command;
3239 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3240
3241 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3242 value = value + 17;
3243 /* Convert the value from ascii to integer */
3244 ret = kstrtou8(value, 10, &val);
3245 if (ret < 0)
3246 {
3247 /* If the input value is greater than max value of datatype, then also
3248 kstrtou8 fails */
3249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3250 "%s: kstrtou8 failed range [%d - %d]", __func__,
3251 CFG_ROAM_INTRA_BAND_MIN,
3252 CFG_ROAM_INTRA_BAND_MAX);
3253 ret = -EINVAL;
3254 goto exit;
3255 }
3256
3257 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3258 (val > CFG_ROAM_INTRA_BAND_MAX))
3259 {
3260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3261 "intra band mode value %d is out of range"
3262 " (Min: %d Max: %d)", val,
3263 CFG_ROAM_INTRA_BAND_MIN,
3264 CFG_ROAM_INTRA_BAND_MAX);
3265 ret = -EINVAL;
3266 goto exit;
3267 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3269 "%s: Received Command to change intra band = %d", __func__, val);
3270
3271 pHddCtx->cfg_ini->nRoamIntraBand = val;
3272 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3273 }
3274 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3275 {
3276 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3277 char extra[32];
3278 tANI_U8 len = 0;
3279
3280 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003281 len = scnprintf(extra, sizeof(extra), "%s %d",
3282 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +05303283 len = VOS_MIN(priv_data.total_len, len + 1);
3284 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003285 {
3286 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3287 "%s: failed to copy data to user buffer", __func__);
3288 ret = -EFAULT;
3289 goto exit;
3290 }
3291 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003292 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3293 {
3294 tANI_U8 *value = command;
3295 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3296
3297 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3298 value = value + 15;
3299 /* Convert the value from ascii to integer */
3300 ret = kstrtou8(value, 10, &nProbes);
3301 if (ret < 0)
3302 {
3303 /* If the input value is greater than max value of datatype, then also
3304 kstrtou8 fails */
3305 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3306 "%s: kstrtou8 failed range [%d - %d]", __func__,
3307 CFG_ROAM_SCAN_N_PROBES_MIN,
3308 CFG_ROAM_SCAN_N_PROBES_MAX);
3309 ret = -EINVAL;
3310 goto exit;
3311 }
3312
3313 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3314 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3315 {
3316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3317 "NProbes value %d is out of range"
3318 " (Min: %d Max: %d)", nProbes,
3319 CFG_ROAM_SCAN_N_PROBES_MIN,
3320 CFG_ROAM_SCAN_N_PROBES_MAX);
3321 ret = -EINVAL;
3322 goto exit;
3323 }
3324
3325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3326 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3327
3328 pHddCtx->cfg_ini->nProbes = nProbes;
3329 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3330 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303331 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003332 {
3333 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3334 char extra[32];
3335 tANI_U8 len = 0;
3336
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003337 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri6da525d2015-08-07 13:55:54 +05303338 len = VOS_MIN(priv_data.total_len, len + 1);
3339 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3341 "%s: failed to copy data to user buffer", __func__);
3342 ret = -EFAULT;
3343 goto exit;
3344 }
3345 }
3346 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3347 {
3348 tANI_U8 *value = command;
3349 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3350
3351 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3352 /* input value is in units of msec */
3353 value = value + 20;
3354 /* Convert the value from ascii to integer */
3355 ret = kstrtou16(value, 10, &homeAwayTime);
3356 if (ret < 0)
3357 {
3358 /* If the input value is greater than max value of datatype, then also
3359 kstrtou8 fails */
3360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3361 "%s: kstrtou8 failed range [%d - %d]", __func__,
3362 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3363 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3364 ret = -EINVAL;
3365 goto exit;
3366 }
3367
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003368 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3369 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3370 {
3371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3372 "homeAwayTime value %d is out of range"
3373 " (Min: %d Max: %d)", homeAwayTime,
3374 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3375 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3376 ret = -EINVAL;
3377 goto exit;
3378 }
3379
3380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3381 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003382 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3383 {
3384 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3385 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3386 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003387 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303388 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003389 {
3390 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3391 char extra[32];
3392 tANI_U8 len = 0;
3393
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003394 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri51a5ad12015-08-07 14:06:37 +05303395 len = VOS_MIN(priv_data.total_len, len + 1);
3396 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3398 "%s: failed to copy data to user buffer", __func__);
3399 ret = -EFAULT;
3400 goto exit;
3401 }
3402 }
3403 else if (strncmp(command, "REASSOC", 7) == 0)
3404 {
3405 tANI_U8 *value = command;
3406 tANI_U8 channel = 0;
3407 tSirMacAddr targetApBssid;
3408 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003409#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3410 tCsrHandoffRequest handoffInfo;
3411#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003412 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003413 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3414
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003415 /* if not associated, no need to proceed with reassoc */
3416 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3417 {
3418 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3419 ret = -EINVAL;
3420 goto exit;
3421 }
3422
3423 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3424 if (eHAL_STATUS_SUCCESS != status)
3425 {
3426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3427 "%s: Failed to parse reassoc command data", __func__);
3428 ret = -EINVAL;
3429 goto exit;
3430 }
3431
3432 /* if the target bssid is same as currently associated AP,
3433 then no need to proceed with reassoc */
3434 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3435 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3436 {
3437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3438 ret = -EINVAL;
3439 goto exit;
3440 }
3441
3442 /* Check channel number is a valid channel number */
3443 if(VOS_STATUS_SUCCESS !=
3444 wlan_hdd_validate_operation_channel(pAdapter, channel))
3445 {
3446 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003447 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003448 return -EINVAL;
3449 }
3450
3451 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003452#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3453 handoffInfo.channel = channel;
3454 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3455 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3456#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003457 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003458 else if (strncmp(command, "SETWESMODE", 10) == 0)
3459 {
3460 tANI_U8 *value = command;
3461 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3462
3463 /* Move pointer to ahead of SETWESMODE<delimiter> */
3464 value = value + 11;
3465 /* Convert the value from ascii to integer */
3466 ret = kstrtou8(value, 10, &wesMode);
3467 if (ret < 0)
3468 {
3469 /* If the input value is greater than max value of datatype, then also
3470 kstrtou8 fails */
3471 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3472 "%s: kstrtou8 failed range [%d - %d]", __func__,
3473 CFG_ENABLE_WES_MODE_NAME_MIN,
3474 CFG_ENABLE_WES_MODE_NAME_MAX);
3475 ret = -EINVAL;
3476 goto exit;
3477 }
3478
3479 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3480 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3481 {
3482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3483 "WES Mode value %d is out of range"
3484 " (Min: %d Max: %d)", wesMode,
3485 CFG_ENABLE_WES_MODE_NAME_MIN,
3486 CFG_ENABLE_WES_MODE_NAME_MAX);
3487 ret = -EINVAL;
3488 goto exit;
3489 }
3490 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3491 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3492
3493 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3494 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3495 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303496 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003497 {
3498 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3499 char extra[32];
3500 tANI_U8 len = 0;
3501
Arif Hussain826d9412013-11-12 16:44:54 -08003502 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05303503 len = VOS_MIN(priv_data.total_len, len + 1);
3504 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003505 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3506 "%s: failed to copy data to user buffer", __func__);
3507 ret = -EFAULT;
3508 goto exit;
3509 }
3510 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003511#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003512#ifdef FEATURE_WLAN_LFR
3513 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3514 {
3515 tANI_U8 *value = command;
3516 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3517
3518 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3519 value = value + 12;
3520 /* Convert the value from ascii to integer */
3521 ret = kstrtou8(value, 10, &lfrMode);
3522 if (ret < 0)
3523 {
3524 /* If the input value is greater than max value of datatype, then also
3525 kstrtou8 fails */
3526 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3527 "%s: kstrtou8 failed range [%d - %d]", __func__,
3528 CFG_LFR_FEATURE_ENABLED_MIN,
3529 CFG_LFR_FEATURE_ENABLED_MAX);
3530 ret = -EINVAL;
3531 goto exit;
3532 }
3533
3534 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3535 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3536 {
3537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3538 "lfr mode value %d is out of range"
3539 " (Min: %d Max: %d)", lfrMode,
3540 CFG_LFR_FEATURE_ENABLED_MIN,
3541 CFG_LFR_FEATURE_ENABLED_MAX);
3542 ret = -EINVAL;
3543 goto exit;
3544 }
3545
3546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3547 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3548
3549 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3550 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3551 }
3552#endif
3553#ifdef WLAN_FEATURE_VOWIFI_11R
3554 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3555 {
3556 tANI_U8 *value = command;
3557 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3558
3559 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3560 value = value + 18;
3561 /* Convert the value from ascii to integer */
3562 ret = kstrtou8(value, 10, &ft);
3563 if (ret < 0)
3564 {
3565 /* If the input value is greater than max value of datatype, then also
3566 kstrtou8 fails */
3567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3568 "%s: kstrtou8 failed range [%d - %d]", __func__,
3569 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3570 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3571 ret = -EINVAL;
3572 goto exit;
3573 }
3574
3575 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3576 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3577 {
3578 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3579 "ft mode value %d is out of range"
3580 " (Min: %d Max: %d)", ft,
3581 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3582 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3583 ret = -EINVAL;
3584 goto exit;
3585 }
3586
3587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3588 "%s: Received Command to change ft mode = %d", __func__, ft);
3589
3590 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3591 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3592 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303593 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
3594 {
3595 tANI_U8 *value = command;
3596 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303597
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303598 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
3599 value = value + 15;
3600 /* Convert the value from ascii to integer */
3601 ret = kstrtou8(value, 10, &dfsScanMode);
3602 if (ret < 0)
3603 {
3604 /* If the input value is greater than max value of
3605 datatype, then also kstrtou8 fails
3606 */
3607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3608 "%s: kstrtou8 failed range [%d - %d]", __func__,
3609 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3610 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3611 ret = -EINVAL;
3612 goto exit;
3613 }
3614
3615 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
3616 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
3617 {
3618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3619 "dfsScanMode value %d is out of range"
3620 " (Min: %d Max: %d)", dfsScanMode,
3621 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3622 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3623 ret = -EINVAL;
3624 goto exit;
3625 }
3626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3627 "%s: Received Command to Set DFS Scan Mode = %d",
3628 __func__, dfsScanMode);
3629
3630 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
3631 }
3632 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
3633 {
3634 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
3635 char extra[32];
3636 tANI_U8 len = 0;
3637
3638 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05303639 len = VOS_MIN(priv_data.total_len, len + 1);
3640 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303641 {
3642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3643 "%s: failed to copy data to user buffer", __func__);
3644 ret = -EFAULT;
3645 goto exit;
3646 }
3647 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303648 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3649 {
3650 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303651 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303652 tSirMacAddr targetApBssid;
3653 tANI_U8 trigger = 0;
3654 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303655 tHalHandle hHal;
3656 v_U32_t roamId = 0;
3657 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303658 hdd_station_ctx_t *pHddStaCtx = NULL;
3659 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303660 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303661
3662 /* if not associated, no need to proceed with reassoc */
3663 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3664 {
3665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3666 ret = -EINVAL;
3667 goto exit;
3668 }
3669
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303670 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303671 if (eHAL_STATUS_SUCCESS != status)
3672 {
3673 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3674 "%s: Failed to parse reassoc command data", __func__);
3675 ret = -EINVAL;
3676 goto exit;
3677 }
3678
3679 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303680 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303681 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3682 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3683 {
3684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3685 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3686 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303687 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3688 &modProfileFields);
3689 sme_RoamReassoc(hHal, pAdapter->sessionId,
3690 NULL, modProfileFields, &roamId, 1);
3691 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303692 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303693
3694 /* Check channel number is a valid channel number */
3695 if(VOS_STATUS_SUCCESS !=
3696 wlan_hdd_validate_operation_channel(pAdapter, channel))
3697 {
3698 hddLog(VOS_TRACE_LEVEL_ERROR,
3699 "%s: Invalid Channel [%d]", __func__, channel);
3700 return -EINVAL;
3701 }
3702
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303703 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303704
3705 /* Proceed with scan/roam */
3706 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3707 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303708 (tSmeFastRoamTrigger)(trigger),
3709 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303710 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003711#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003712#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003713 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3714 {
3715 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003716 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003717
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003718 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003719 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003720 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003721 hdd_is_okc_mode_enabled(pHddCtx) &&
3722 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3723 {
3724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003725 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003726 " hence this operation is not permitted!", __func__);
3727 ret = -EPERM;
3728 goto exit;
3729 }
3730
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003731 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3732 value = value + 11;
3733 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003734 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003735 if (ret < 0)
3736 {
3737 /* If the input value is greater than max value of datatype, then also
3738 kstrtou8 fails */
3739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3740 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003741 CFG_ESE_FEATURE_ENABLED_MIN,
3742 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003743 ret = -EINVAL;
3744 goto exit;
3745 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003746 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3747 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003748 {
3749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003750 "Ese mode value %d is out of range"
3751 " (Min: %d Max: %d)", eseMode,
3752 CFG_ESE_FEATURE_ENABLED_MIN,
3753 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003754 ret = -EINVAL;
3755 goto exit;
3756 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003758 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003759
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003760 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3761 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003762 }
3763#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003764 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3765 {
3766 tANI_U8 *value = command;
3767 tANI_BOOLEAN roamScanControl = 0;
3768
3769 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3770 value = value + 19;
3771 /* Convert the value from ascii to integer */
3772 ret = kstrtou8(value, 10, &roamScanControl);
3773 if (ret < 0)
3774 {
3775 /* If the input value is greater than max value of datatype, then also
3776 kstrtou8 fails */
3777 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3778 "%s: kstrtou8 failed ", __func__);
3779 ret = -EINVAL;
3780 goto exit;
3781 }
3782
3783 if (0 != roamScanControl)
3784 {
3785 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3786 "roam scan control invalid value = %d",
3787 roamScanControl);
3788 ret = -EINVAL;
3789 goto exit;
3790 }
3791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3792 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3793
3794 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3795 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003796#ifdef FEATURE_WLAN_OKC
3797 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3798 {
3799 tANI_U8 *value = command;
3800 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3801
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003802 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003803 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003804 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003805 hdd_is_okc_mode_enabled(pHddCtx) &&
3806 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3807 {
3808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003809 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003810 " hence this operation is not permitted!", __func__);
3811 ret = -EPERM;
3812 goto exit;
3813 }
3814
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003815 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3816 value = value + 11;
3817 /* Convert the value from ascii to integer */
3818 ret = kstrtou8(value, 10, &okcMode);
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 range [%d - %d]", __func__,
3825 CFG_OKC_FEATURE_ENABLED_MIN,
3826 CFG_OKC_FEATURE_ENABLED_MAX);
3827 ret = -EINVAL;
3828 goto exit;
3829 }
3830
3831 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3832 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3833 {
3834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3835 "Okc mode value %d is out of range"
3836 " (Min: %d Max: %d)", okcMode,
3837 CFG_OKC_FEATURE_ENABLED_MIN,
3838 CFG_OKC_FEATURE_ENABLED_MAX);
3839 ret = -EINVAL;
3840 goto exit;
3841 }
3842
3843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3844 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3845
3846 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3847 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003848#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303849 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003850 {
3851 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3852 char extra[32];
3853 tANI_U8 len = 0;
3854
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003855 len = scnprintf(extra, sizeof(extra), "%s %d",
3856 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05303857 len = VOS_MIN(priv_data.total_len, len + 1);
3858 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003859 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3860 "%s: failed to copy data to user buffer", __func__);
3861 ret = -EFAULT;
3862 goto exit;
3863 }
3864 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303865#ifdef WLAN_FEATURE_PACKET_FILTERING
3866 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3867 {
3868 tANI_U8 filterType = 0;
3869 tANI_U8 *value = command;
3870
3871 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3872 value = value + 22;
3873
3874 /* Convert the value from ascii to integer */
3875 ret = kstrtou8(value, 10, &filterType);
3876 if (ret < 0)
3877 {
3878 /* If the input value is greater than max value of datatype,
3879 * then also kstrtou8 fails
3880 */
3881 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3882 "%s: kstrtou8 failed range ", __func__);
3883 ret = -EINVAL;
3884 goto exit;
3885 }
3886
3887 if (filterType != 0 && filterType != 1)
3888 {
3889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3890 "%s: Accepted Values are 0 and 1 ", __func__);
3891 ret = -EINVAL;
3892 goto exit;
3893 }
3894 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3895 pAdapter->sessionId);
3896 }
3897#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303898 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3899 {
Kiet Lamad161252014-07-22 11:23:32 -07003900 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303901 int ret;
3902
Kiet Lamad161252014-07-22 11:23:32 -07003903 dhcpPhase = command + 11;
3904 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303905 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303906 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003907 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303908
3909 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003910
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303911 ret = wlan_hdd_scan_abort(pAdapter);
3912 if (ret < 0)
3913 {
3914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3915 FL("failed to abort existing scan %d"), ret);
3916 }
3917
Kiet Lamad161252014-07-22 11:23:32 -07003918 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3919 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303920 }
Kiet Lamad161252014-07-22 11:23:32 -07003921 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303922 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303923 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003924 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303925
3926 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003927
3928 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3929 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303930 }
3931 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003932 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3933 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303934 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3935 FL("making default scan to ACTIVE"));
3936 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003937 }
3938 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3939 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3941 FL("making default scan to PASSIVE"));
3942 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003943 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303944 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3945 {
3946 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3947 char extra[32];
3948 tANI_U8 len = 0;
3949
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303950 memset(extra, 0, sizeof(extra));
3951 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05303952 len = VOS_MIN(priv_data.total_len, len + 1);
3953 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303954 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3955 "%s: failed to copy data to user buffer", __func__);
3956 ret = -EFAULT;
3957 goto exit;
3958 }
3959 ret = len;
3960 }
3961 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3962 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303963 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303964 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003965 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3966 {
3967 tANI_U8 filterType = 0;
3968 tANI_U8 *value;
3969 value = command + 9;
3970
3971 /* Convert the value from ascii to integer */
3972 ret = kstrtou8(value, 10, &filterType);
3973 if (ret < 0)
3974 {
3975 /* If the input value is greater than max value of datatype,
3976 * then also kstrtou8 fails
3977 */
3978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3979 "%s: kstrtou8 failed range ", __func__);
3980 ret = -EINVAL;
3981 goto exit;
3982 }
3983 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3984 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3985 {
3986 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3987 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3988 " 2-Sink ", __func__);
3989 ret = -EINVAL;
3990 goto exit;
3991 }
3992 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3993 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303994 pScanInfo = &pHddCtx->scan_info;
3995 if (filterType && pScanInfo != NULL &&
3996 pHddCtx->scan_info.mScanPending)
3997 {
3998 /*Miracast Session started. Abort Scan */
3999 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4000 "%s, Aborting Scan For Miracast",__func__);
4001 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
4002 eCSR_SCAN_ABORT_DEFAULT);
4003 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004004 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05304005 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004006 }
Leo Chang614d2072013-08-22 14:59:44 -07004007 else if (strncmp(command, "SETMCRATE", 9) == 0)
4008 {
Leo Chang614d2072013-08-22 14:59:44 -07004009 tANI_U8 *value = command;
4010 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07004011 tSirRateUpdateInd *rateUpdate;
4012 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07004013
4014 /* Only valid for SAP mode */
4015 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
4016 {
4017 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4018 "%s: SAP mode is not running", __func__);
4019 ret = -EFAULT;
4020 goto exit;
4021 }
4022
4023 /* Move pointer to ahead of SETMCRATE<delimiter> */
4024 /* input value is in units of hundred kbps */
4025 value = value + 10;
4026 /* Convert the value from ascii to integer, decimal base */
4027 ret = kstrtouint(value, 10, &targetRate);
4028
Leo Chang1f98cbd2013-10-17 15:03:52 -07004029 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
4030 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07004031 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07004032 hddLog(VOS_TRACE_LEVEL_ERROR,
4033 "%s: SETMCRATE indication alloc fail", __func__);
4034 ret = -EFAULT;
4035 goto exit;
4036 }
4037 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
4038
4039 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4040 "MC Target rate %d", targetRate);
4041 /* Ignore unicast */
4042 rateUpdate->ucastDataRate = -1;
4043 rateUpdate->mcastDataRate24GHz = targetRate;
4044 rateUpdate->mcastDataRate5GHz = targetRate;
4045 rateUpdate->mcastDataRate24GHzTxFlag = 0;
4046 rateUpdate->mcastDataRate5GHzTxFlag = 0;
4047 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
4048 if (eHAL_STATUS_SUCCESS != status)
4049 {
4050 hddLog(VOS_TRACE_LEVEL_ERROR,
4051 "%s: SET_MC_RATE failed", __func__);
4052 vos_mem_free(rateUpdate);
4053 ret = -EFAULT;
4054 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07004055 }
4056 }
Rajeev79dbe4c2013-10-05 11:03:42 +05304057#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08004058 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05304059 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08004060 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05304061 }
4062#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004063#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004064 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
4065 {
4066 tANI_U8 *value = command;
4067 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4068 tANI_U8 numChannels = 0;
4069 eHalStatus status = eHAL_STATUS_SUCCESS;
4070
4071 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4072 if (eHAL_STATUS_SUCCESS != status)
4073 {
4074 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4075 "%s: Failed to parse channel list information", __func__);
4076 ret = -EINVAL;
4077 goto exit;
4078 }
4079
4080 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4081 {
4082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4083 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4084 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4085 ret = -EINVAL;
4086 goto exit;
4087 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004088 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004089 ChannelList,
4090 numChannels);
4091 if (eHAL_STATUS_SUCCESS != status)
4092 {
4093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4094 "%s: Failed to update channel list information", __func__);
4095 ret = -EINVAL;
4096 goto exit;
4097 }
4098 }
4099 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
4100 {
4101 tANI_U8 *value = command;
4102 char extra[128] = {0};
4103 int len = 0;
4104 tANI_U8 tid = 0;
4105 hdd_station_ctx_t *pHddStaCtx = NULL;
4106 tAniTrafStrmMetrics tsmMetrics;
4107 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4108
4109 /* if not associated, return error */
4110 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4111 {
4112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
4113 ret = -EINVAL;
4114 goto exit;
4115 }
4116
4117 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
4118 value = value + 12;
4119 /* Convert the value from ascii to integer */
4120 ret = kstrtou8(value, 10, &tid);
4121 if (ret < 0)
4122 {
4123 /* If the input value is greater than max value of datatype, then also
4124 kstrtou8 fails */
4125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4126 "%s: kstrtou8 failed range [%d - %d]", __func__,
4127 TID_MIN_VALUE,
4128 TID_MAX_VALUE);
4129 ret = -EINVAL;
4130 goto exit;
4131 }
4132
4133 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4134 {
4135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4136 "tid value %d is out of range"
4137 " (Min: %d Max: %d)", tid,
4138 TID_MIN_VALUE,
4139 TID_MAX_VALUE);
4140 ret = -EINVAL;
4141 goto exit;
4142 }
4143
4144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4145 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4146
4147 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4148 {
4149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4150 "%s: failed to get tsm stats", __func__);
4151 ret = -EFAULT;
4152 goto exit;
4153 }
4154
4155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4156 "UplinkPktQueueDly(%d)\n"
4157 "UplinkPktQueueDlyHist[0](%d)\n"
4158 "UplinkPktQueueDlyHist[1](%d)\n"
4159 "UplinkPktQueueDlyHist[2](%d)\n"
4160 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304161 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004162 "UplinkPktLoss(%d)\n"
4163 "UplinkPktCount(%d)\n"
4164 "RoamingCount(%d)\n"
4165 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4166 tsmMetrics.UplinkPktQueueDlyHist[0],
4167 tsmMetrics.UplinkPktQueueDlyHist[1],
4168 tsmMetrics.UplinkPktQueueDlyHist[2],
4169 tsmMetrics.UplinkPktQueueDlyHist[3],
4170 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4171 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4172
4173 /* Output TSM stats is of the format
4174 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4175 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004176 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004177 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4178 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4179 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4180 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4181 tsmMetrics.RoamingDly);
4182
Ratnam Rachurid53009c2015-08-07 13:59:00 +05304183 len = VOS_MIN(priv_data.total_len, len + 1);
4184 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004185 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4186 "%s: failed to copy data to user buffer", __func__);
4187 ret = -EFAULT;
4188 goto exit;
4189 }
4190 }
4191 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4192 {
4193 tANI_U8 *value = command;
4194 tANI_U8 *cckmIe = NULL;
4195 tANI_U8 cckmIeLen = 0;
4196 eHalStatus status = eHAL_STATUS_SUCCESS;
4197
4198 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4199 if (eHAL_STATUS_SUCCESS != status)
4200 {
4201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4202 "%s: Failed to parse cckm ie data", __func__);
4203 ret = -EINVAL;
4204 goto exit;
4205 }
4206
4207 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4208 {
4209 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4210 "%s: CCKM Ie input length is more than max[%d]", __func__,
4211 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004212 vos_mem_free(cckmIe);
4213 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004214 ret = -EINVAL;
4215 goto exit;
4216 }
4217 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004218 vos_mem_free(cckmIe);
4219 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004220 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004221 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4222 {
4223 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004224 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004225 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004226
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004227 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004228 if (eHAL_STATUS_SUCCESS != status)
4229 {
4230 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004231 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004232 ret = -EINVAL;
4233 goto exit;
4234 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004235 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4236 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4237 hdd_indicateEseBcnReportNoResults (pAdapter,
4238 eseBcnReq.bcnReq[0].measurementToken,
4239 0x02, //BIT(1) set for measurement done
4240 0); // no BSS
4241 goto exit;
4242 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004243
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004244 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4245 if (eHAL_STATUS_SUCCESS != status)
4246 {
4247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4248 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4249 ret = -EINVAL;
4250 goto exit;
4251 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004252 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004253#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304254 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4255 {
4256 eHalStatus status;
4257 char buf[32], len;
4258 long waitRet;
4259 bcnMissRateContext_t getBcnMissRateCtx;
4260
4261 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4262
4263 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4264 {
4265 hddLog(VOS_TRACE_LEVEL_WARN,
4266 FL("GETBCNMISSRATE: STA is not in connected state"));
4267 ret = -1;
4268 goto exit;
4269 }
4270
4271 init_completion(&(getBcnMissRateCtx.completion));
4272 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4273
4274 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4275 pAdapter->sessionId,
4276 (void *)getBcnMissRateCB,
4277 (void *)(&getBcnMissRateCtx));
4278 if( eHAL_STATUS_SUCCESS != status)
4279 {
4280 hddLog(VOS_TRACE_LEVEL_INFO,
4281 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4282 ret = -EINVAL;
4283 goto exit;
4284 }
4285
4286 waitRet = wait_for_completion_interruptible_timeout
4287 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4288 if(waitRet <= 0)
4289 {
4290 hddLog(VOS_TRACE_LEVEL_ERROR,
4291 FL("failed to wait on bcnMissRateComp %d"), ret);
4292
4293 //Make magic number to zero so that callback is not called.
4294 spin_lock(&hdd_context_lock);
4295 getBcnMissRateCtx.magic = 0x0;
4296 spin_unlock(&hdd_context_lock);
4297 ret = -EINVAL;
4298 goto exit;
4299 }
4300
4301 hddLog(VOS_TRACE_LEVEL_INFO,
4302 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4303
4304 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4305 if (copy_to_user(priv_data.buf, &buf, len + 1))
4306 {
4307 hddLog(VOS_TRACE_LEVEL_ERROR,
4308 "%s: failed to copy data to user buffer", __func__);
4309 ret = -EFAULT;
4310 goto exit;
4311 }
4312 ret = len;
4313 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304314#ifdef FEATURE_WLAN_TDLS
4315 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4316 tANI_U8 *value = command;
4317 int set_value;
4318 /* Move pointer to ahead of TDLSOFFCH*/
4319 value += 26;
4320 sscanf(value, "%d", &set_value);
4321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4322 "%s: Tdls offchannel offset:%d",
4323 __func__, set_value);
4324 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4325 if (ret < 0)
4326 {
4327 ret = -EINVAL;
4328 goto exit;
4329 }
4330
4331 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4332 tANI_U8 *value = command;
4333 int set_value;
4334 /* Move pointer to ahead of tdlsoffchnmode*/
4335 value += 18;
4336 sscanf(value, "%d", &set_value);
4337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4338 "%s: Tdls offchannel mode:%d",
4339 __func__, set_value);
4340 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4341 if (ret < 0)
4342 {
4343 ret = -EINVAL;
4344 goto exit;
4345 }
4346 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4347 tANI_U8 *value = command;
4348 int set_value;
4349 /* Move pointer to ahead of TDLSOFFCH*/
4350 value += 14;
4351 sscanf(value, "%d", &set_value);
4352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4353 "%s: Tdls offchannel num: %d",
4354 __func__, set_value);
4355 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4356 if (ret < 0)
4357 {
4358 ret = -EINVAL;
4359 goto exit;
4360 }
4361 }
4362#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304363 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4364 {
4365 eHalStatus status;
4366 char *buf = NULL;
4367 char len;
4368 long waitRet;
4369 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304370 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304371 tANI_U8 *ptr = command;
4372 int stats = *(ptr + 11) - '0';
4373
4374 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4375 if (!IS_FEATURE_FW_STATS_ENABLE)
4376 {
4377 hddLog(VOS_TRACE_LEVEL_INFO,
4378 FL("Get Firmware stats feature not supported"));
4379 ret = -EINVAL;
4380 goto exit;
4381 }
4382
4383 if (FW_STATS_MAX <= stats || 0 >= stats)
4384 {
4385 hddLog(VOS_TRACE_LEVEL_INFO,
4386 FL(" stats %d not supported"),stats);
4387 ret = -EINVAL;
4388 goto exit;
4389 }
4390
4391 init_completion(&(fwStatsCtx.completion));
4392 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4393 fwStatsCtx.pAdapter = pAdapter;
4394 fwStatsRsp->type = 0;
4395 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304396 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304397 if (eHAL_STATUS_SUCCESS != status)
4398 {
4399 hddLog(VOS_TRACE_LEVEL_ERROR,
4400 FL(" fail to post WDA cmd status = %d"), status);
4401 ret = -EINVAL;
4402 goto exit;
4403 }
4404 waitRet = wait_for_completion_timeout
4405 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4406 if (waitRet <= 0)
4407 {
4408 hddLog(VOS_TRACE_LEVEL_ERROR,
4409 FL("failed to wait on GwtFwstats"));
4410 //Make magic number to zero so that callback is not executed.
4411 spin_lock(&hdd_context_lock);
4412 fwStatsCtx.magic = 0x0;
4413 spin_unlock(&hdd_context_lock);
4414 ret = -EINVAL;
4415 goto exit;
4416 }
4417 if (fwStatsRsp->type)
4418 {
4419 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4420 if (!buf)
4421 {
4422 hddLog(VOS_TRACE_LEVEL_ERROR,
4423 FL(" failed to allocate memory"));
4424 ret = -ENOMEM;
4425 goto exit;
4426 }
4427 switch( fwStatsRsp->type )
4428 {
4429 case FW_UBSP_STATS:
4430 {
4431 len = snprintf(buf, FW_STATE_RSP_LEN,
4432 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304433 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4434 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304435 }
4436 break;
4437 default:
4438 {
4439 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4440 ret = -EFAULT;
4441 kfree(buf);
4442 goto exit;
4443 }
4444 }
4445 if (copy_to_user(priv_data.buf, buf, len + 1))
4446 {
4447 hddLog(VOS_TRACE_LEVEL_ERROR,
4448 FL(" failed to copy data to user buffer"));
4449 ret = -EFAULT;
4450 kfree(buf);
4451 goto exit;
4452 }
4453 ret = len;
4454 kfree(buf);
4455 }
4456 else
4457 {
4458 hddLog(VOS_TRACE_LEVEL_ERROR,
4459 FL("failed to fetch the stats"));
4460 ret = -EFAULT;
4461 goto exit;
4462 }
4463
4464 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05304465 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
4466 {
4467 /*
4468 * this command wld be called by user-space when it detects WLAN
4469 * ON after airplane mode is set. When APM is set, WLAN turns off.
4470 * But it can be turned back on. Otherwise; when APM is turned back
4471 * off, WLAN wld turn back on. So at that point the command is
4472 * expected to come down. 0 means disable, 1 means enable. The
4473 * constraint is removed when parameter 1 is set or different
4474 * country code is set
4475 */
4476 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
4477 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004478 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304479 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4480 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4481 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304482 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4483 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004484 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004485 }
4486exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304487 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004488 if (command)
4489 {
4490 kfree(command);
4491 }
4492 return ret;
4493}
4494
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004495#ifdef CONFIG_COMPAT
4496static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4497{
4498 struct {
4499 compat_uptr_t buf;
4500 int used_len;
4501 int total_len;
4502 } compat_priv_data;
4503 hdd_priv_data_t priv_data;
4504 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004505
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004506 /*
4507 * Note that pAdapter and ifr have already been verified by caller,
4508 * and HDD context has also been validated
4509 */
4510 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4511 sizeof(compat_priv_data))) {
4512 ret = -EFAULT;
4513 goto exit;
4514 }
4515 priv_data.buf = compat_ptr(compat_priv_data.buf);
4516 priv_data.used_len = compat_priv_data.used_len;
4517 priv_data.total_len = compat_priv_data.total_len;
4518 ret = hdd_driver_command(pAdapter, &priv_data);
4519 exit:
4520 return ret;
4521}
4522#else /* CONFIG_COMPAT */
4523static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4524{
4525 /* will never be invoked */
4526 return 0;
4527}
4528#endif /* CONFIG_COMPAT */
4529
4530static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4531{
4532 hdd_priv_data_t priv_data;
4533 int ret = 0;
4534
4535 /*
4536 * Note that pAdapter and ifr have already been verified by caller,
4537 * and HDD context has also been validated
4538 */
4539 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4540 ret = -EFAULT;
4541 } else {
4542 ret = hdd_driver_command(pAdapter, &priv_data);
4543 }
4544 return ret;
4545}
4546
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304547int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004548{
4549 hdd_adapter_t *pAdapter;
4550 hdd_context_t *pHddCtx;
4551 int ret;
4552
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304553 ENTER();
4554
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004555 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4556 if (NULL == pAdapter) {
4557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4558 "%s: HDD adapter context is Null", __func__);
4559 ret = -ENODEV;
4560 goto exit;
4561 }
4562 if (dev != pAdapter->dev) {
4563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4564 "%s: HDD adapter/dev inconsistency", __func__);
4565 ret = -ENODEV;
4566 goto exit;
4567 }
4568
4569 if ((!ifr) || (!ifr->ifr_data)) {
4570 ret = -EINVAL;
4571 goto exit;
4572 }
4573
4574 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4575 ret = wlan_hdd_validate_context(pHddCtx);
4576 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004577 ret = -EBUSY;
4578 goto exit;
4579 }
4580
4581 switch (cmd) {
4582 case (SIOCDEVPRIVATE + 1):
4583 if (is_compat_task())
4584 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4585 else
4586 ret = hdd_driver_ioctl(pAdapter, ifr);
4587 break;
4588 default:
4589 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4590 __func__, cmd);
4591 ret = -EINVAL;
4592 break;
4593 }
4594 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304595 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004596 return ret;
4597}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004598
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304599int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4600{
4601 int ret;
4602
4603 vos_ssr_protect(__func__);
4604 ret = __hdd_ioctl(dev, ifr, cmd);
4605 vos_ssr_unprotect(__func__);
4606
4607 return ret;
4608}
4609
Katya Nigame7b69a82015-04-28 15:24:06 +05304610int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4611{
4612 return 0;
4613}
4614
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004615#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004616/**---------------------------------------------------------------------------
4617
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004618 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004619
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004620 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004621 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4622 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4623 <space>Scan Mode N<space>Meas Duration N
4624 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4625 then take N.
4626 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4627 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4628 This function does not take care of removing duplicate channels from the list
4629
4630 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004631 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004632
4633 \return - 0 for success non-zero for failure
4634
4635 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004636static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4637 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004638{
4639 tANI_U8 *inPtr = pValue;
4640 int tempInt = 0;
4641 int j = 0, i = 0, v = 0;
4642 char buf[32];
4643
4644 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4645 /*no argument after the command*/
4646 if (NULL == inPtr)
4647 {
4648 return -EINVAL;
4649 }
4650 /*no space after the command*/
4651 else if (SPACE_ASCII_VALUE != *inPtr)
4652 {
4653 return -EINVAL;
4654 }
4655
4656 /*removing empty spaces*/
4657 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4658
4659 /*no argument followed by spaces*/
4660 if ('\0' == *inPtr) return -EINVAL;
4661
4662 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004663 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004664 if (1 != v) return -EINVAL;
4665
4666 v = kstrtos32(buf, 10, &tempInt);
4667 if ( v < 0) return -EINVAL;
4668
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004669 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004670
4671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004672 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004673
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004674 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004675 {
4676 for (i = 0; i < 4; i++)
4677 {
4678 /*inPtr pointing to the beginning of first space after number of ie fields*/
4679 inPtr = strpbrk( inPtr, " " );
4680 /*no ie data after the number of ie fields argument*/
4681 if (NULL == inPtr) return -EINVAL;
4682
4683 /*removing empty space*/
4684 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4685
4686 /*no ie data after the number of ie fields argument and spaces*/
4687 if ( '\0' == *inPtr ) return -EINVAL;
4688
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004689 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004690 if (1 != v) return -EINVAL;
4691
4692 v = kstrtos32(buf, 10, &tempInt);
4693 if (v < 0) return -EINVAL;
4694
4695 switch (i)
4696 {
4697 case 0: /* Measurement token */
4698 if (tempInt <= 0)
4699 {
4700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4701 "Invalid Measurement Token(%d)", tempInt);
4702 return -EINVAL;
4703 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004704 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004705 break;
4706
4707 case 1: /* Channel number */
4708 if ((tempInt <= 0) ||
4709 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4710 {
4711 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4712 "Invalid Channel Number(%d)", tempInt);
4713 return -EINVAL;
4714 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004715 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004716 break;
4717
4718 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004719 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004720 {
4721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4722 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4723 return -EINVAL;
4724 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004725 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004726 break;
4727
4728 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004729 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4730 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004731 {
4732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4733 "Invalid Measurement Duration(%d)", tempInt);
4734 return -EINVAL;
4735 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004736 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004737 break;
4738 }
4739 }
4740 }
4741
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004742 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004743 {
4744 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304745 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004746 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004747 pEseBcnReq->bcnReq[j].measurementToken,
4748 pEseBcnReq->bcnReq[j].channel,
4749 pEseBcnReq->bcnReq[j].scanMode,
4750 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004751 }
4752
4753 return VOS_STATUS_SUCCESS;
4754}
4755
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004756static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4757{
4758 struct statsContext *pStatsContext = NULL;
4759 hdd_adapter_t *pAdapter = NULL;
4760
4761 if (NULL == pContext)
4762 {
4763 hddLog(VOS_TRACE_LEVEL_ERROR,
4764 "%s: Bad param, pContext [%p]",
4765 __func__, pContext);
4766 return;
4767 }
4768
Jeff Johnson72a40512013-12-19 10:14:15 -08004769 /* there is a race condition that exists between this callback
4770 function and the caller since the caller could time out either
4771 before or while this code is executing. we use a spinlock to
4772 serialize these actions */
4773 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004774
4775 pStatsContext = pContext;
4776 pAdapter = pStatsContext->pAdapter;
4777 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4778 {
4779 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004780 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004781 hddLog(VOS_TRACE_LEVEL_WARN,
4782 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4783 __func__, pAdapter, pStatsContext->magic);
4784 return;
4785 }
4786
Jeff Johnson72a40512013-12-19 10:14:15 -08004787 /* context is valid so caller is still waiting */
4788
4789 /* paranoia: invalidate the magic */
4790 pStatsContext->magic = 0;
4791
4792 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004793 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4794 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4795 tsmMetrics.UplinkPktQueueDlyHist,
4796 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4797 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4798 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4799 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4800 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4801 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4802 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4803
Jeff Johnson72a40512013-12-19 10:14:15 -08004804 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004805 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004806
4807 /* serialization is complete */
4808 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004809}
4810
4811
4812
4813static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4814 tAniTrafStrmMetrics* pTsmMetrics)
4815{
4816 hdd_station_ctx_t *pHddStaCtx = NULL;
4817 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004818 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004819 long lrc;
4820 struct statsContext context;
4821 hdd_context_t *pHddCtx = NULL;
4822
4823 if (NULL == pAdapter)
4824 {
4825 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4826 return VOS_STATUS_E_FAULT;
4827 }
4828
4829 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4830 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4831
4832 /* we are connected prepare our callback context */
4833 init_completion(&context.completion);
4834 context.pAdapter = pAdapter;
4835 context.magic = STATS_CONTEXT_MAGIC;
4836
4837 /* query tsm stats */
4838 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4839 pHddStaCtx->conn_info.staId[ 0 ],
4840 pHddStaCtx->conn_info.bssId,
4841 &context, pHddCtx->pvosContext, tid);
4842
4843 if (eHAL_STATUS_SUCCESS != hstatus)
4844 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004845 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4846 __func__);
4847 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004848 }
4849 else
4850 {
4851 /* request was sent -- wait for the response */
4852 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4853 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004854 if (lrc <= 0)
4855 {
4856 hddLog(VOS_TRACE_LEVEL_ERROR,
4857 "%s: SME %s while retrieving statistics",
4858 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004859 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004860 }
4861 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004862
Jeff Johnson72a40512013-12-19 10:14:15 -08004863 /* either we never sent a request, we sent a request and received a
4864 response or we sent a request and timed out. if we never sent a
4865 request or if we sent a request and got a response, we want to
4866 clear the magic out of paranoia. if we timed out there is a
4867 race condition such that the callback function could be
4868 executing at the same time we are. of primary concern is if the
4869 callback function had already verified the "magic" but had not
4870 yet set the completion variable when a timeout occurred. we
4871 serialize these activities by invalidating the magic while
4872 holding a shared spinlock which will cause us to block if the
4873 callback is currently executing */
4874 spin_lock(&hdd_context_lock);
4875 context.magic = 0;
4876 spin_unlock(&hdd_context_lock);
4877
4878 if (VOS_STATUS_SUCCESS == vstatus)
4879 {
4880 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4881 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4882 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4883 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4884 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4885 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4886 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4887 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4888 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4889 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4890 }
4891 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004892}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004893#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004894
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004895#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004896void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4897{
4898 eCsrBand band = -1;
4899 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4900 switch (band)
4901 {
4902 case eCSR_BAND_ALL:
4903 *pBand = WLAN_HDD_UI_BAND_AUTO;
4904 break;
4905
4906 case eCSR_BAND_24:
4907 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4908 break;
4909
4910 case eCSR_BAND_5G:
4911 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4912 break;
4913
4914 default:
4915 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4916 *pBand = -1;
4917 break;
4918 }
4919}
4920
4921/**---------------------------------------------------------------------------
4922
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004923 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4924
4925 This function parses the send action frame data passed in the format
4926 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4927
Srinivas Girigowda56076852013-08-20 14:00:50 -07004928 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004929 \param - pTargetApBssid Pointer to target Ap bssid
4930 \param - pChannel Pointer to the Target AP channel
4931 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4932 \param - pBuf Pointer to data
4933 \param - pBufLen Pointer to data length
4934
4935 \return - 0 for success non-zero for failure
4936
4937 --------------------------------------------------------------------------*/
4938VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4939 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4940{
4941 tANI_U8 *inPtr = pValue;
4942 tANI_U8 *dataEnd;
4943 int tempInt;
4944 int j = 0;
4945 int i = 0;
4946 int v = 0;
4947 tANI_U8 tempBuf[32];
4948 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004949 /* 12 hexa decimal digits, 5 ':' and '\0' */
4950 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004951
4952 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4953 /*no argument after the command*/
4954 if (NULL == inPtr)
4955 {
4956 return -EINVAL;
4957 }
4958
4959 /*no space after the command*/
4960 else if (SPACE_ASCII_VALUE != *inPtr)
4961 {
4962 return -EINVAL;
4963 }
4964
4965 /*removing empty spaces*/
4966 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4967
4968 /*no argument followed by spaces*/
4969 if ('\0' == *inPtr)
4970 {
4971 return -EINVAL;
4972 }
4973
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004974 v = sscanf(inPtr, "%17s", macAddress);
4975 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004976 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004977 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4978 "Invalid MAC address or All hex inputs are not read (%d)", v);
4979 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004980 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004981
4982 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4983 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4984 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4985 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4986 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4987 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004988
4989 /* point to the next argument */
4990 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4991 /*no argument after the command*/
4992 if (NULL == inPtr) return -EINVAL;
4993
4994 /*removing empty spaces*/
4995 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4996
4997 /*no argument followed by spaces*/
4998 if ('\0' == *inPtr)
4999 {
5000 return -EINVAL;
5001 }
5002
5003 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005004 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005005 if (1 != v) return -EINVAL;
5006
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005007 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05305008 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05305009 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005010
5011 *pChannel = tempInt;
5012
5013 /* point to the next argument */
5014 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5015 /*no argument after the command*/
5016 if (NULL == inPtr) return -EINVAL;
5017 /*removing empty spaces*/
5018 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5019
5020 /*no argument followed by spaces*/
5021 if ('\0' == *inPtr)
5022 {
5023 return -EINVAL;
5024 }
5025
5026 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005027 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005028 if (1 != v) return -EINVAL;
5029
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005030 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08005031 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005032
5033 *pDwellTime = tempInt;
5034
5035 /* point to the next argument */
5036 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5037 /*no argument after the command*/
5038 if (NULL == inPtr) return -EINVAL;
5039 /*removing empty spaces*/
5040 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5041
5042 /*no argument followed by spaces*/
5043 if ('\0' == *inPtr)
5044 {
5045 return -EINVAL;
5046 }
5047
5048 /* find the length of data */
5049 dataEnd = inPtr;
5050 while(('\0' != *dataEnd) )
5051 {
5052 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005053 }
Kiet Lambe150c22013-11-21 16:30:32 +05305054 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005055 if ( *pBufLen <= 0) return -EINVAL;
5056
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07005057 /* Allocate the number of bytes based on the number of input characters
5058 whether it is even or odd.
5059 if the number of input characters are even, then we need N/2 byte.
5060 if the number of input characters are odd, then we need do (N+1)/2 to
5061 compensate rounding off.
5062 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5063 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5064 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005065 if (NULL == *pBuf)
5066 {
5067 hddLog(VOS_TRACE_LEVEL_FATAL,
5068 "%s: vos_mem_alloc failed ", __func__);
5069 return -EINVAL;
5070 }
5071
5072 /* the buffer received from the upper layer is character buffer,
5073 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5074 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5075 and f0 in 3rd location */
5076 for (i = 0, j = 0; j < *pBufLen; j += 2)
5077 {
Kiet Lambe150c22013-11-21 16:30:32 +05305078 if( j+1 == *pBufLen)
5079 {
5080 tempByte = hdd_parse_hex(inPtr[j]);
5081 }
5082 else
5083 {
5084 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5085 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005086 (*pBuf)[i++] = tempByte;
5087 }
5088 *pBufLen = i;
5089 return VOS_STATUS_SUCCESS;
5090}
5091
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005092/**---------------------------------------------------------------------------
5093
Srinivas Girigowdade697412013-02-14 16:31:48 -08005094 \brief hdd_parse_channellist() - HDD Parse channel list
5095
5096 This function parses the channel list passed in the format
5097 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005098 if the Number of channels (N) does not match with the actual number of channels passed
5099 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
5100 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
5101 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
5102 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08005103
5104 \param - pValue Pointer to input channel list
5105 \param - ChannelList Pointer to local output array to record channel list
5106 \param - pNumChannels Pointer to number of roam scan channels
5107
5108 \return - 0 for success non-zero for failure
5109
5110 --------------------------------------------------------------------------*/
5111VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
5112{
5113 tANI_U8 *inPtr = pValue;
5114 int tempInt;
5115 int j = 0;
5116 int v = 0;
5117 char buf[32];
5118
5119 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5120 /*no argument after the command*/
5121 if (NULL == inPtr)
5122 {
5123 return -EINVAL;
5124 }
5125
5126 /*no space after the command*/
5127 else if (SPACE_ASCII_VALUE != *inPtr)
5128 {
5129 return -EINVAL;
5130 }
5131
5132 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005133 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005134
5135 /*no argument followed by spaces*/
5136 if ('\0' == *inPtr)
5137 {
5138 return -EINVAL;
5139 }
5140
5141 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005142 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005143 if (1 != v) return -EINVAL;
5144
Srinivas Girigowdade697412013-02-14 16:31:48 -08005145 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005146 if ((v < 0) ||
5147 (tempInt <= 0) ||
5148 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
5149 {
5150 return -EINVAL;
5151 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005152
5153 *pNumChannels = tempInt;
5154
5155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5156 "Number of channels are: %d", *pNumChannels);
5157
5158 for (j = 0; j < (*pNumChannels); j++)
5159 {
5160 /*inPtr pointing to the beginning of first space after number of channels*/
5161 inPtr = strpbrk( inPtr, " " );
5162 /*no channel list after the number of channels argument*/
5163 if (NULL == inPtr)
5164 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005165 if (0 != j)
5166 {
5167 *pNumChannels = j;
5168 return VOS_STATUS_SUCCESS;
5169 }
5170 else
5171 {
5172 return -EINVAL;
5173 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005174 }
5175
5176 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005177 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005178
5179 /*no channel list after the number of channels argument and spaces*/
5180 if ( '\0' == *inPtr )
5181 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005182 if (0 != j)
5183 {
5184 *pNumChannels = j;
5185 return VOS_STATUS_SUCCESS;
5186 }
5187 else
5188 {
5189 return -EINVAL;
5190 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005191 }
5192
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005193 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005194 if (1 != v) return -EINVAL;
5195
Srinivas Girigowdade697412013-02-14 16:31:48 -08005196 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005197 if ((v < 0) ||
5198 (tempInt <= 0) ||
5199 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5200 {
5201 return -EINVAL;
5202 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005203 pChannelList[j] = tempInt;
5204
5205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5206 "Channel %d added to preferred channel list",
5207 pChannelList[j] );
5208 }
5209
Srinivas Girigowdade697412013-02-14 16:31:48 -08005210 return VOS_STATUS_SUCCESS;
5211}
5212
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005213
5214/**---------------------------------------------------------------------------
5215
5216 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5217
5218 This function parses the reasoc command data passed in the format
5219 REASSOC<space><bssid><space><channel>
5220
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005221 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005222 \param - pTargetApBssid Pointer to target Ap bssid
5223 \param - pChannel Pointer to the Target AP channel
5224
5225 \return - 0 for success non-zero for failure
5226
5227 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005228VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5229 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005230{
5231 tANI_U8 *inPtr = pValue;
5232 int tempInt;
5233 int v = 0;
5234 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005235 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005236 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005237
5238 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5239 /*no argument after the command*/
5240 if (NULL == inPtr)
5241 {
5242 return -EINVAL;
5243 }
5244
5245 /*no space after the command*/
5246 else if (SPACE_ASCII_VALUE != *inPtr)
5247 {
5248 return -EINVAL;
5249 }
5250
5251 /*removing empty spaces*/
5252 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5253
5254 /*no argument followed by spaces*/
5255 if ('\0' == *inPtr)
5256 {
5257 return -EINVAL;
5258 }
5259
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005260 v = sscanf(inPtr, "%17s", macAddress);
5261 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005262 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005263 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5264 "Invalid MAC address or All hex inputs are not read (%d)", v);
5265 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005266 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005267
5268 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5269 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5270 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5271 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5272 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5273 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005274
5275 /* point to the next argument */
5276 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5277 /*no argument after the command*/
5278 if (NULL == inPtr) return -EINVAL;
5279
5280 /*removing empty spaces*/
5281 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5282
5283 /*no argument followed by spaces*/
5284 if ('\0' == *inPtr)
5285 {
5286 return -EINVAL;
5287 }
5288
5289 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005290 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005291 if (1 != v) return -EINVAL;
5292
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005293 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005294 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305295 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005296 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5297 {
5298 return -EINVAL;
5299 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005300
5301 *pChannel = tempInt;
5302 return VOS_STATUS_SUCCESS;
5303}
5304
5305#endif
5306
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005307#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005308/**---------------------------------------------------------------------------
5309
5310 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5311
5312 This function parses the SETCCKM IE command
5313 SETCCKMIE<space><ie data>
5314
5315 \param - pValue Pointer to input data
5316 \param - pCckmIe Pointer to output cckm Ie
5317 \param - pCckmIeLen Pointer to output cckm ie length
5318
5319 \return - 0 for success non-zero for failure
5320
5321 --------------------------------------------------------------------------*/
5322VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5323 tANI_U8 *pCckmIeLen)
5324{
5325 tANI_U8 *inPtr = pValue;
5326 tANI_U8 *dataEnd;
5327 int j = 0;
5328 int i = 0;
5329 tANI_U8 tempByte = 0;
5330
5331 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5332 /*no argument after the command*/
5333 if (NULL == inPtr)
5334 {
5335 return -EINVAL;
5336 }
5337
5338 /*no space after the command*/
5339 else if (SPACE_ASCII_VALUE != *inPtr)
5340 {
5341 return -EINVAL;
5342 }
5343
5344 /*removing empty spaces*/
5345 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5346
5347 /*no argument followed by spaces*/
5348 if ('\0' == *inPtr)
5349 {
5350 return -EINVAL;
5351 }
5352
5353 /* find the length of data */
5354 dataEnd = inPtr;
5355 while(('\0' != *dataEnd) )
5356 {
5357 dataEnd++;
5358 ++(*pCckmIeLen);
5359 }
5360 if ( *pCckmIeLen <= 0) return -EINVAL;
5361
5362 /* Allocate the number of bytes based on the number of input characters
5363 whether it is even or odd.
5364 if the number of input characters are even, then we need N/2 byte.
5365 if the number of input characters are odd, then we need do (N+1)/2 to
5366 compensate rounding off.
5367 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5368 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5369 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5370 if (NULL == *pCckmIe)
5371 {
5372 hddLog(VOS_TRACE_LEVEL_FATAL,
5373 "%s: vos_mem_alloc failed ", __func__);
5374 return -EINVAL;
5375 }
5376 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5377 /* the buffer received from the upper layer is character buffer,
5378 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5379 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5380 and f0 in 3rd location */
5381 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5382 {
5383 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5384 (*pCckmIe)[i++] = tempByte;
5385 }
5386 *pCckmIeLen = i;
5387
5388 return VOS_STATUS_SUCCESS;
5389}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005390#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005391
Jeff Johnson295189b2012-06-20 16:38:30 -07005392/**---------------------------------------------------------------------------
5393
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005394 \brief hdd_is_valid_mac_address() - Validate MAC address
5395
5396 This function validates whether the given MAC address is valid or not
5397 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5398 where X is the hexa decimal digit character and separated by ':'
5399 This algorithm works even if MAC address is not separated by ':'
5400
5401 This code checks given input string mac contains exactly 12 hexadecimal digits.
5402 and a separator colon : appears in the input string only after
5403 an even number of hex digits.
5404
5405 \param - pMacAddr pointer to the input MAC address
5406 \return - 1 for valid and 0 for invalid
5407
5408 --------------------------------------------------------------------------*/
5409
5410v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5411{
5412 int xdigit = 0;
5413 int separator = 0;
5414 while (*pMacAddr)
5415 {
5416 if (isxdigit(*pMacAddr))
5417 {
5418 xdigit++;
5419 }
5420 else if (':' == *pMacAddr)
5421 {
5422 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5423 break;
5424
5425 ++separator;
5426 }
5427 else
5428 {
5429 separator = -1;
5430 /* Invalid MAC found */
5431 return 0;
5432 }
5433 ++pMacAddr;
5434 }
5435 return (xdigit == 12 && (separator == 5 || separator == 0));
5436}
5437
5438/**---------------------------------------------------------------------------
5439
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305440 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005441
5442 \param - dev Pointer to net_device structure
5443
5444 \return - 0 for success non-zero for failure
5445
5446 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305447int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005448{
5449 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5450 hdd_context_t *pHddCtx;
5451 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5452 VOS_STATUS status;
5453 v_BOOL_t in_standby = TRUE;
5454
5455 if (NULL == pAdapter)
5456 {
5457 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305458 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005459 return -ENODEV;
5460 }
5461
5462 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305463 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5464 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005465 if (NULL == pHddCtx)
5466 {
5467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005468 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005469 return -ENODEV;
5470 }
5471
5472 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5473 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5474 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005475 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5476 {
5477 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305478 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005479 in_standby = FALSE;
5480 break;
5481 }
5482 else
5483 {
5484 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5485 pAdapterNode = pNext;
5486 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005487 }
5488
5489 if (TRUE == in_standby)
5490 {
5491 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5492 {
5493 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5494 "wlan out of power save", __func__);
5495 return -EINVAL;
5496 }
5497 }
5498
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005499 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005500 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5501 {
5502 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005503 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005504 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305505 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005506 netif_tx_start_all_queues(dev);
5507 }
5508
5509 return 0;
5510}
5511
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305512/**---------------------------------------------------------------------------
5513
5514 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5515
5516 This is called in response to ifconfig up
5517
5518 \param - dev Pointer to net_device structure
5519
5520 \return - 0 for success non-zero for failure
5521
5522 --------------------------------------------------------------------------*/
5523int hdd_open(struct net_device *dev)
5524{
5525 int ret;
5526
5527 vos_ssr_protect(__func__);
5528 ret = __hdd_open(dev);
5529 vos_ssr_unprotect(__func__);
5530
5531 return ret;
5532}
5533
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305534int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005535{
5536 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5537
5538 if(pAdapter == NULL) {
5539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005540 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005541 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005542 }
5543
Jeff Johnson295189b2012-06-20 16:38:30 -07005544 return 0;
5545}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305546
5547int hdd_mon_open (struct net_device *dev)
5548{
5549 int ret;
5550
5551 vos_ssr_protect(__func__);
5552 ret = __hdd_mon_open(dev);
5553 vos_ssr_unprotect(__func__);
5554
5555 return ret;
5556}
5557
Katya Nigame7b69a82015-04-28 15:24:06 +05305558int hdd_mon_stop(struct net_device *dev)
5559{
5560 return 0;
5561}
5562
Jeff Johnson295189b2012-06-20 16:38:30 -07005563/**---------------------------------------------------------------------------
5564
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305565 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005566
5567 \param - dev Pointer to net_device structure
5568
5569 \return - 0 for success non-zero for failure
5570
5571 --------------------------------------------------------------------------*/
5572
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305573int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005574{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305575 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005576 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5577 hdd_context_t *pHddCtx;
5578 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5579 VOS_STATUS status;
5580 v_BOOL_t enter_standby = TRUE;
5581
5582 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005583 if (NULL == pAdapter)
5584 {
5585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305586 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005587 return -ENODEV;
5588 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305589 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305590 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305591
5592 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5593 ret = wlan_hdd_validate_context(pHddCtx);
5594 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005595 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305596 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005597 }
5598
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305599 /* Nothing to be done if the interface is not opened */
5600 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5601 {
5602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5603 "%s: NETDEV Interface is not OPENED", __func__);
5604 return -ENODEV;
5605 }
5606
5607 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005608 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005609 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305610
5611 /* Disable TX on the interface, after this hard_start_xmit() will not
5612 * be called on that interface
5613 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305614 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005615 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305616
5617 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005618 netif_carrier_off(pAdapter->dev);
5619
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305620 /* The interface is marked as down for outside world (aka kernel)
5621 * But the driver is pretty much alive inside. The driver needs to
5622 * tear down the existing connection on the netdev (session)
5623 * cleanup the data pipes and wait until the control plane is stabilized
5624 * for this interface. The call also needs to wait until the above
5625 * mentioned actions are completed before returning to the caller.
5626 * Notice that the hdd_stop_adapter is requested not to close the session
5627 * That is intentional to be able to scan if it is a STA/P2P interface
5628 */
5629 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305630#ifdef FEATURE_WLAN_TDLS
5631 mutex_lock(&pHddCtx->tdls_lock);
5632#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305633 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305634 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305635#ifdef FEATURE_WLAN_TDLS
5636 mutex_unlock(&pHddCtx->tdls_lock);
5637#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005638 /* SoftAP ifaces should never go in power save mode
5639 making sure same here. */
5640 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5641 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005642 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005643 )
5644 {
5645 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5647 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005648 EXIT();
5649 return 0;
5650 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305651 /* Find if any iface is up. If any iface is up then can't put device to
5652 * sleep/power save mode
5653 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005654 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5655 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5656 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005657 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5658 {
5659 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305660 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005661 enter_standby = FALSE;
5662 break;
5663 }
5664 else
5665 {
5666 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5667 pAdapterNode = pNext;
5668 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005669 }
5670
5671 if (TRUE == enter_standby)
5672 {
5673 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5674 "entering standby", __func__);
5675 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5676 {
5677 /*log and return success*/
5678 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5679 "wlan in power save", __func__);
5680 }
5681 }
5682
5683 EXIT();
5684 return 0;
5685}
5686
5687/**---------------------------------------------------------------------------
5688
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305689 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005690
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305691 This is called in response to ifconfig down
5692
5693 \param - dev Pointer to net_device structure
5694
5695 \return - 0 for success non-zero for failure
5696-----------------------------------------------------------------------------*/
5697int hdd_stop (struct net_device *dev)
5698{
5699 int ret;
5700
5701 vos_ssr_protect(__func__);
5702 ret = __hdd_stop(dev);
5703 vos_ssr_unprotect(__func__);
5704
5705 return ret;
5706}
5707
5708/**---------------------------------------------------------------------------
5709
5710 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005711
5712 \param - dev Pointer to net_device structure
5713
5714 \return - void
5715
5716 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305717static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005718{
5719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305720 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005721 ENTER();
5722
5723 do
5724 {
5725 if (NULL == pAdapter)
5726 {
5727 hddLog(VOS_TRACE_LEVEL_FATAL,
5728 "%s: NULL pAdapter", __func__);
5729 break;
5730 }
5731
5732 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5733 {
5734 hddLog(VOS_TRACE_LEVEL_FATAL,
5735 "%s: Invalid magic", __func__);
5736 break;
5737 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305738 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5739 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005740 {
5741 hddLog(VOS_TRACE_LEVEL_FATAL,
5742 "%s: NULL pHddCtx", __func__);
5743 break;
5744 }
5745
5746 if (dev != pAdapter->dev)
5747 {
5748 hddLog(VOS_TRACE_LEVEL_FATAL,
5749 "%s: Invalid device reference", __func__);
5750 /* we haven't validated all cases so let this go for now */
5751 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305752#ifdef FEATURE_WLAN_TDLS
5753 mutex_lock(&pHddCtx->tdls_lock);
5754#endif
c_hpothu002231a2015-02-05 14:58:51 +05305755 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305756#ifdef FEATURE_WLAN_TDLS
5757 mutex_unlock(&pHddCtx->tdls_lock);
5758#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005759
5760 /* after uninit our adapter structure will no longer be valid */
5761 pAdapter->dev = NULL;
5762 pAdapter->magic = 0;
5763 } while (0);
5764
5765 EXIT();
5766}
5767
5768/**---------------------------------------------------------------------------
5769
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305770 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5771
5772 This is called during the netdev unregister to uninitialize all data
5773associated with the device
5774
5775 \param - dev Pointer to net_device structure
5776
5777 \return - void
5778
5779 --------------------------------------------------------------------------*/
5780static void hdd_uninit (struct net_device *dev)
5781{
5782 vos_ssr_protect(__func__);
5783 __hdd_uninit(dev);
5784 vos_ssr_unprotect(__func__);
5785}
5786
5787/**---------------------------------------------------------------------------
5788
Jeff Johnson295189b2012-06-20 16:38:30 -07005789 \brief hdd_release_firmware() -
5790
5791 This function calls the release firmware API to free the firmware buffer.
5792
5793 \param - pFileName Pointer to the File Name.
5794 pCtx - Pointer to the adapter .
5795
5796
5797 \return - 0 for success, non zero for failure
5798
5799 --------------------------------------------------------------------------*/
5800
5801VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5802{
5803 VOS_STATUS status = VOS_STATUS_SUCCESS;
5804 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5805 ENTER();
5806
5807
5808 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5809
5810 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5811
5812 if(pHddCtx->fw) {
5813 release_firmware(pHddCtx->fw);
5814 pHddCtx->fw = NULL;
5815 }
5816 else
5817 status = VOS_STATUS_E_FAILURE;
5818 }
5819 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5820 if(pHddCtx->nv) {
5821 release_firmware(pHddCtx->nv);
5822 pHddCtx->nv = NULL;
5823 }
5824 else
5825 status = VOS_STATUS_E_FAILURE;
5826
5827 }
5828
5829 EXIT();
5830 return status;
5831}
5832
5833/**---------------------------------------------------------------------------
5834
5835 \brief hdd_request_firmware() -
5836
5837 This function reads the firmware file using the request firmware
5838 API and returns the the firmware data and the firmware file size.
5839
5840 \param - pfileName - Pointer to the file name.
5841 - pCtx - Pointer to the adapter .
5842 - ppfw_data - Pointer to the pointer of the firmware data.
5843 - pSize - Pointer to the file size.
5844
5845 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5846
5847 --------------------------------------------------------------------------*/
5848
5849
5850VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5851{
5852 int status;
5853 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5854 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5855 ENTER();
5856
5857 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5858
5859 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5860
5861 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5862 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5863 __func__, pfileName);
5864 retval = VOS_STATUS_E_FAILURE;
5865 }
5866
5867 else {
5868 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5869 *pSize = pHddCtx->fw->size;
5870 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5871 __func__, *pSize);
5872 }
5873 }
5874 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5875
5876 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5877
5878 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5879 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5880 __func__, pfileName);
5881 retval = VOS_STATUS_E_FAILURE;
5882 }
5883
5884 else {
5885 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5886 *pSize = pHddCtx->nv->size;
5887 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5888 __func__, *pSize);
5889 }
5890 }
5891
5892 EXIT();
5893 return retval;
5894}
5895/**---------------------------------------------------------------------------
5896 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5897
5898 This is the function invoked by SME to inform the result of a full power
5899 request issued by HDD
5900
5901 \param - callbackcontext - Pointer to cookie
5902 status - result of request
5903
5904 \return - None
5905
5906--------------------------------------------------------------------------*/
5907void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5908{
5909 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5910
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005911 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005912 if(&pHddCtx->full_pwr_comp_var)
5913 {
5914 complete(&pHddCtx->full_pwr_comp_var);
5915 }
5916}
5917
5918/**---------------------------------------------------------------------------
5919
5920 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5921
5922 This is the function invoked by SME to inform the result of BMPS
5923 request issued by HDD
5924
5925 \param - callbackcontext - Pointer to cookie
5926 status - result of request
5927
5928 \return - None
5929
5930--------------------------------------------------------------------------*/
5931void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5932{
5933
5934 struct completion *completion_var = (struct completion*) callbackContext;
5935
Arif Hussain6d2a3322013-11-17 19:50:10 -08005936 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005937 if(completion_var != NULL)
5938 {
5939 complete(completion_var);
5940 }
5941}
5942
5943/**---------------------------------------------------------------------------
5944
5945 \brief hdd_get_cfg_file_size() -
5946
5947 This function reads the configuration file using the request firmware
5948 API and returns the configuration file size.
5949
5950 \param - pCtx - Pointer to the adapter .
5951 - pFileName - Pointer to the file name.
5952 - pBufSize - Pointer to the buffer size.
5953
5954 \return - 0 for success, non zero for failure
5955
5956 --------------------------------------------------------------------------*/
5957
5958VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5959{
5960 int status;
5961 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5962
5963 ENTER();
5964
5965 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5966
5967 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5968 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5969 status = VOS_STATUS_E_FAILURE;
5970 }
5971 else {
5972 *pBufSize = pHddCtx->fw->size;
5973 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5974 release_firmware(pHddCtx->fw);
5975 pHddCtx->fw = NULL;
5976 }
5977
5978 EXIT();
5979 return VOS_STATUS_SUCCESS;
5980}
5981
5982/**---------------------------------------------------------------------------
5983
5984 \brief hdd_read_cfg_file() -
5985
5986 This function reads the configuration file using the request firmware
5987 API and returns the cfg data and the buffer size of the configuration file.
5988
5989 \param - pCtx - Pointer to the adapter .
5990 - pFileName - Pointer to the file name.
5991 - pBuffer - Pointer to the data buffer.
5992 - pBufSize - Pointer to the buffer size.
5993
5994 \return - 0 for success, non zero for failure
5995
5996 --------------------------------------------------------------------------*/
5997
5998VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5999 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
6000{
6001 int status;
6002 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
6003
6004 ENTER();
6005
6006 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
6007
6008 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
6009 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
6010 return VOS_STATUS_E_FAILURE;
6011 }
6012 else {
6013 if(*pBufSize != pHddCtx->fw->size) {
6014 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
6015 "file size", __func__);
6016 release_firmware(pHddCtx->fw);
6017 pHddCtx->fw = NULL;
6018 return VOS_STATUS_E_FAILURE;
6019 }
6020 else {
6021 if(pBuffer) {
6022 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
6023 }
6024 release_firmware(pHddCtx->fw);
6025 pHddCtx->fw = NULL;
6026 }
6027 }
6028
6029 EXIT();
6030
6031 return VOS_STATUS_SUCCESS;
6032}
6033
6034/**---------------------------------------------------------------------------
6035
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306036 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07006037
6038 This function sets the user specified mac address using
6039 the command ifconfig wlanX hw ether <mac adress>.
6040
6041 \param - dev - Pointer to the net device.
6042 - addr - Pointer to the sockaddr.
6043 \return - 0 for success, non zero for failure
6044
6045 --------------------------------------------------------------------------*/
6046
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306047static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07006048{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306049 hdd_adapter_t *pAdapter;
6050 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006051 struct sockaddr *psta_mac_addr = addr;
6052 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306053 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006054
6055 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306056 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6057 if (NULL == pAdapter)
6058 {
6059 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6060 "%s: Adapter is NULL",__func__);
6061 return -EINVAL;
6062 }
6063 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6064 ret = wlan_hdd_validate_context(pHddCtx);
6065 if (0 != ret)
6066 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306067 return ret;
6068 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006069
6070 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07006071 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
6072
6073 EXIT();
6074 return halStatus;
6075}
6076
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306077/**---------------------------------------------------------------------------
6078
6079 \brief hdd_set_mac_address() -
6080
6081 Wrapper function to protect __hdd_set_mac_address() function from ssr
6082
6083 \param - dev - Pointer to the net device.
6084 - addr - Pointer to the sockaddr.
6085 \return - 0 for success, non zero for failure
6086
6087 --------------------------------------------------------------------------*/
6088static int hdd_set_mac_address(struct net_device *dev, void *addr)
6089{
6090 int ret;
6091
6092 vos_ssr_protect(__func__);
6093 ret = __hdd_set_mac_address(dev, addr);
6094 vos_ssr_unprotect(__func__);
6095
6096 return ret;
6097}
6098
Jeff Johnson295189b2012-06-20 16:38:30 -07006099tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
6100{
6101 int i;
6102 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6103 {
Abhishek Singheb183782014-02-06 13:37:21 +05306104 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006105 break;
6106 }
6107
6108 if( VOS_MAX_CONCURRENCY_PERSONA == i)
6109 return NULL;
6110
6111 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
6112 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
6113}
6114
6115void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
6116{
6117 int i;
6118 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6119 {
6120 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
6121 {
6122 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
6123 break;
6124 }
6125 }
6126 return;
6127}
6128
6129#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6130 static struct net_device_ops wlan_drv_ops = {
6131 .ndo_open = hdd_open,
6132 .ndo_stop = hdd_stop,
6133 .ndo_uninit = hdd_uninit,
6134 .ndo_start_xmit = hdd_hard_start_xmit,
6135 .ndo_tx_timeout = hdd_tx_timeout,
6136 .ndo_get_stats = hdd_stats,
6137 .ndo_do_ioctl = hdd_ioctl,
6138 .ndo_set_mac_address = hdd_set_mac_address,
6139 .ndo_select_queue = hdd_select_queue,
6140#ifdef WLAN_FEATURE_PACKET_FILTERING
6141#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
6142 .ndo_set_rx_mode = hdd_set_multicast_list,
6143#else
6144 .ndo_set_multicast_list = hdd_set_multicast_list,
6145#endif //LINUX_VERSION_CODE
6146#endif
6147 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006148 static struct net_device_ops wlan_mon_drv_ops = {
6149 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05306150 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07006151 .ndo_uninit = hdd_uninit,
6152 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6153 .ndo_tx_timeout = hdd_tx_timeout,
6154 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05306155 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07006156 .ndo_set_mac_address = hdd_set_mac_address,
6157 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306158
Jeff Johnson295189b2012-06-20 16:38:30 -07006159#endif
6160
6161void hdd_set_station_ops( struct net_device *pWlanDev )
6162{
6163#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006164 pWlanDev->netdev_ops = &wlan_drv_ops;
6165#else
6166 pWlanDev->open = hdd_open;
6167 pWlanDev->stop = hdd_stop;
6168 pWlanDev->uninit = hdd_uninit;
6169 pWlanDev->hard_start_xmit = NULL;
6170 pWlanDev->tx_timeout = hdd_tx_timeout;
6171 pWlanDev->get_stats = hdd_stats;
6172 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006173 pWlanDev->set_mac_address = hdd_set_mac_address;
6174#endif
6175}
6176
Katya Nigam1fd24402015-02-16 14:52:19 +05306177void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
6178{
6179 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6180 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
6181 #else
6182 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
6183 #endif
6184}
6185
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006186static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006187{
6188 struct net_device *pWlanDev = NULL;
6189 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006190 /*
6191 * cfg80211 initialization and registration....
6192 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05306193 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
6194#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
6195 NET_NAME_UNKNOWN,
6196#endif
6197 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07006198 if(pWlanDev != NULL)
6199 {
6200
6201 //Save the pointer to the net_device in the HDD adapter
6202 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6203
Jeff Johnson295189b2012-06-20 16:38:30 -07006204 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6205
6206 pAdapter->dev = pWlanDev;
6207 pAdapter->pHddCtx = pHddCtx;
6208 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306209 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006210
6211 init_completion(&pAdapter->session_open_comp_var);
6212 init_completion(&pAdapter->session_close_comp_var);
6213 init_completion(&pAdapter->disconnect_comp_var);
6214 init_completion(&pAdapter->linkup_event_var);
6215 init_completion(&pAdapter->cancel_rem_on_chan_var);
6216 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306217 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006218#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6219 init_completion(&pAdapter->offchannel_tx_event);
6220#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006221 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006222#ifdef FEATURE_WLAN_TDLS
6223 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006224 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006225 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306226 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006227#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006228 init_completion(&pHddCtx->mc_sus_event_var);
6229 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306230 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006231 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006232 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006233
Rajeev79dbe4c2013-10-05 11:03:42 +05306234#ifdef FEATURE_WLAN_BATCH_SCAN
6235 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6236 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6237 pAdapter->pBatchScanRsp = NULL;
6238 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006239 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006240 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306241 mutex_init(&pAdapter->hdd_batch_scan_lock);
6242#endif
6243
Jeff Johnson295189b2012-06-20 16:38:30 -07006244 pAdapter->isLinkUpSvcNeeded = FALSE;
6245 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6246 //Init the net_device structure
6247 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6248
6249 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6250 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6251 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6252 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6253
6254 hdd_set_station_ops( pAdapter->dev );
6255
6256 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006257 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6258 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6259 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006260 /* set pWlanDev's parent to underlying device */
6261 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006262
6263 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006264 }
6265
6266 return pAdapter;
6267}
6268
6269VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6270{
6271 struct net_device *pWlanDev = pAdapter->dev;
6272 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6273 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6274 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6275
6276 if( rtnl_lock_held )
6277 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006278 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006279 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6280 {
6281 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6282 return VOS_STATUS_E_FAILURE;
6283 }
6284 }
6285 if (register_netdevice(pWlanDev))
6286 {
6287 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6288 return VOS_STATUS_E_FAILURE;
6289 }
6290 }
6291 else
6292 {
6293 if(register_netdev(pWlanDev))
6294 {
6295 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6296 return VOS_STATUS_E_FAILURE;
6297 }
6298 }
6299 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6300
6301 return VOS_STATUS_SUCCESS;
6302}
6303
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006304static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006305{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006306 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006307
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006308 if (NULL == pAdapter)
6309 {
6310 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6311 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006312 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006313
6314 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6315 {
6316 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6317 return eHAL_STATUS_NOT_INITIALIZED;
6318 }
6319
6320 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6321
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006322#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006323 /* need to make sure all of our scheduled work has completed.
6324 * This callback is called from MC thread context, so it is safe to
6325 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006326 *
6327 * Even though this is called from MC thread context, if there is a faulty
6328 * work item in the system, that can hang this call forever. So flushing
6329 * this global work queue is not safe; and now we make sure that
6330 * individual work queues are stopped correctly. But the cancel work queue
6331 * is a GPL only API, so the proprietary version of the driver would still
6332 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006333 */
6334 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006335#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006336
6337 /* We can be blocked while waiting for scheduled work to be
6338 * flushed, and the adapter structure can potentially be freed, in
6339 * which case the magic will have been reset. So make sure the
6340 * magic is still good, and hence the adapter structure is still
6341 * valid, before signaling completion */
6342 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6343 {
6344 complete(&pAdapter->session_close_comp_var);
6345 }
6346
Jeff Johnson295189b2012-06-20 16:38:30 -07006347 return eHAL_STATUS_SUCCESS;
6348}
6349
6350VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6351{
6352 struct net_device *pWlanDev = pAdapter->dev;
6353 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6354 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6355 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6356 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306357 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006358
Nirav Shah7e3c8132015-06-22 23:51:42 +05306359 spin_lock_init( &pAdapter->sta_hash_lock);
6360 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
6361
Jeff Johnson295189b2012-06-20 16:38:30 -07006362 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006363 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006364 //Open a SME session for future operation
6365 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006366 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006367 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6368 {
6369 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006370 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006371 halStatus, halStatus );
6372 status = VOS_STATUS_E_FAILURE;
6373 goto error_sme_open;
6374 }
6375
6376 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306377 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006378 &pAdapter->session_open_comp_var,
6379 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306380 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006381 {
6382 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306383 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006384 status = VOS_STATUS_E_FAILURE;
6385 goto error_sme_open;
6386 }
6387
6388 // Register wireless extensions
6389 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6390 {
6391 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006392 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006393 halStatus, halStatus );
6394 status = VOS_STATUS_E_FAILURE;
6395 goto error_register_wext;
6396 }
Katya Nigam1fd24402015-02-16 14:52:19 +05306397
Jeff Johnson295189b2012-06-20 16:38:30 -07006398 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05306399 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6400 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6401 #else
6402 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6403 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006404
6405 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306406 hddLog(VOS_TRACE_LEVEL_INFO,
6407 "%s: Set HDD connState to eConnectionState_NotConnected",
6408 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006409 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6410
6411 //Set the default operation channel
6412 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6413
6414 /* Make the default Auth Type as OPEN*/
6415 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6416
6417 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6418 {
6419 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006420 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006421 status, status );
6422 goto error_init_txrx;
6423 }
6424
6425 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6426
6427 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6428 {
6429 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006430 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006431 status, status );
6432 goto error_wmm_init;
6433 }
6434
6435 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6436
6437 return VOS_STATUS_SUCCESS;
6438
6439error_wmm_init:
6440 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6441 hdd_deinit_tx_rx(pAdapter);
6442error_init_txrx:
6443 hdd_UnregisterWext(pWlanDev);
6444error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006445 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006446 {
6447 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006448 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
mukul sharmabab477d2015-06-11 17:14:55 +05306449 pAdapter->sessionId, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006450 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006451 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306452 unsigned long rc;
6453
Jeff Johnson295189b2012-06-20 16:38:30 -07006454 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306455 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006456 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006457 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306458 if (rc <= 0)
6459 hddLog(VOS_TRACE_LEVEL_ERROR,
6460 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006461 }
6462}
6463error_sme_open:
6464 return status;
6465}
6466
Jeff Johnson295189b2012-06-20 16:38:30 -07006467void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6468{
6469 hdd_cfg80211_state_t *cfgState;
6470
6471 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6472
6473 if( NULL != cfgState->buf )
6474 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306475 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006476 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6477 rc = wait_for_completion_interruptible_timeout(
6478 &pAdapter->tx_action_cnf_event,
6479 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306480 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006481 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05306482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6483 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6484 , __func__, rc);
6485
6486 // Inform tx status as FAILURE to upper layer and free cfgState->buf
6487 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006488 }
6489 }
6490 return;
6491}
Jeff Johnson295189b2012-06-20 16:38:30 -07006492
c_hpothu002231a2015-02-05 14:58:51 +05306493void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006494{
6495 ENTER();
6496 switch ( pAdapter->device_mode )
6497 {
Katya Nigam1fd24402015-02-16 14:52:19 +05306498 case WLAN_HDD_IBSS:
6499 {
6500 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6501 {
6502 hdd_ibss_deinit_tx_rx( pAdapter );
6503 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6504 }
6505 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006506 case WLAN_HDD_INFRA_STATION:
6507 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006508 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006509 {
6510 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6511 {
6512 hdd_deinit_tx_rx( pAdapter );
6513 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6514 }
6515
6516 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6517 {
6518 hdd_wmm_adapter_close( pAdapter );
6519 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6520 }
6521
Jeff Johnson295189b2012-06-20 16:38:30 -07006522 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006523 break;
6524 }
6525
6526 case WLAN_HDD_SOFTAP:
6527 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006528 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306529
6530 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6531 {
6532 hdd_wmm_adapter_close( pAdapter );
6533 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6534 }
6535
Jeff Johnson295189b2012-06-20 16:38:30 -07006536 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006537
c_hpothu002231a2015-02-05 14:58:51 +05306538 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006539 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006540 break;
6541 }
6542
6543 case WLAN_HDD_MONITOR:
6544 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006545 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6546 {
6547 hdd_deinit_tx_rx( pAdapter );
6548 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6549 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006550 break;
6551 }
6552
6553
6554 default:
6555 break;
6556 }
6557
6558 EXIT();
6559}
6560
6561void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6562{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006563 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306564
6565 ENTER();
6566 if (NULL == pAdapter)
6567 {
6568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6569 "%s: HDD adapter is Null", __func__);
6570 return;
6571 }
6572
6573 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006574
Rajeev79dbe4c2013-10-05 11:03:42 +05306575#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306576 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6577 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006578 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306579 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6580 )
6581 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006582 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306583 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006584 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6585 {
6586 hdd_deinit_batch_scan(pAdapter);
6587 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306588 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006589 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306590#endif
6591
Jeff Johnson295189b2012-06-20 16:38:30 -07006592 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6593 if( rtnl_held )
6594 {
6595 unregister_netdevice(pWlanDev);
6596 }
6597 else
6598 {
6599 unregister_netdev(pWlanDev);
6600 }
6601 // note that the pAdapter is no longer valid at this point
6602 // since the memory has been reclaimed
6603 }
6604
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306605 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006606}
6607
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006608void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6609{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306610 VOS_STATUS status;
6611 hdd_adapter_t *pAdapter = NULL;
6612 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006613
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306614 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006615
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306616 /*loop through all adapters.*/
6617 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006618 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306619 pAdapter = pAdapterNode->pAdapter;
6620 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6621 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006622
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306623 { // we skip this registration for modes other than STA and P2P client modes.
6624 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6625 pAdapterNode = pNext;
6626 continue;
6627 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006628
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306629 //Apply Dynamic DTIM For P2P
6630 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6631 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6632 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6633 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6634 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6635 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6636 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6637 (eConnectionState_Associated ==
6638 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6639 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6640 {
6641 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006642
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306643 powerRequest.uIgnoreDTIM = 1;
6644 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6645
6646 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6647 {
6648 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6649 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6650 }
6651 else
6652 {
6653 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6654 }
6655
6656 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6657 * specified during Enter/Exit BMPS when LCD off*/
6658 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6659 NULL, eANI_BOOLEAN_FALSE);
6660 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6661 NULL, eANI_BOOLEAN_FALSE);
6662
6663 /* switch to the DTIM specified in cfg.ini */
6664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6665 "Switch to DTIM %d", powerRequest.uListenInterval);
6666 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6667 break;
6668
6669 }
6670
6671 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6672 pAdapterNode = pNext;
6673 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006674}
6675
6676void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6677{
6678 /*Switch back to DTIM 1*/
6679 tSirSetPowerParamsReq powerRequest = { 0 };
6680
6681 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6682 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006683 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006684
6685 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6686 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6687 NULL, eANI_BOOLEAN_FALSE);
6688 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6689 NULL, eANI_BOOLEAN_FALSE);
6690
6691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6692 "Switch to DTIM%d",powerRequest.uListenInterval);
6693 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6694
6695}
6696
Jeff Johnson295189b2012-06-20 16:38:30 -07006697VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6698{
6699 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306700 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6701 {
6702 hddLog( LOGE, FL("Wlan Unload in progress"));
6703 return VOS_STATUS_E_PERM;
6704 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006705 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6706 {
6707 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6708 }
6709
6710 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6711 {
6712 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6713 }
6714
6715 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6716 {
6717 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6718 }
6719
6720 return status;
6721}
6722
6723VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6724{
6725 hdd_adapter_t *pAdapter = NULL;
6726 eHalStatus halStatus;
6727 VOS_STATUS status = VOS_STATUS_E_INVAL;
6728 v_BOOL_t disableBmps = FALSE;
6729 v_BOOL_t disableImps = FALSE;
6730
6731 switch(session_type)
6732 {
6733 case WLAN_HDD_INFRA_STATION:
6734 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006735 case WLAN_HDD_P2P_CLIENT:
6736 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006737 //Exit BMPS -> Is Sta/P2P Client is already connected
6738 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6739 if((NULL != pAdapter)&&
6740 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6741 {
6742 disableBmps = TRUE;
6743 }
6744
6745 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6746 if((NULL != pAdapter)&&
6747 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6748 {
6749 disableBmps = TRUE;
6750 }
6751
6752 //Exit both Bmps and Imps incase of Go/SAP Mode
6753 if((WLAN_HDD_SOFTAP == session_type) ||
6754 (WLAN_HDD_P2P_GO == session_type))
6755 {
6756 disableBmps = TRUE;
6757 disableImps = TRUE;
6758 }
6759
6760 if(TRUE == disableImps)
6761 {
6762 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6763 {
6764 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6765 }
6766 }
6767
6768 if(TRUE == disableBmps)
6769 {
6770 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6771 {
6772 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6773
6774 if(eHAL_STATUS_SUCCESS != halStatus)
6775 {
6776 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006777 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006778 VOS_ASSERT(0);
6779 return status;
6780 }
6781 }
6782
6783 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6784 {
6785 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6786
6787 if(eHAL_STATUS_SUCCESS != halStatus)
6788 {
6789 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006790 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006791 VOS_ASSERT(0);
6792 return status;
6793 }
6794 }
6795 }
6796
6797 if((TRUE == disableBmps) ||
6798 (TRUE == disableImps))
6799 {
6800 /* Now, get the chip into Full Power now */
6801 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6802 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6803 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6804
6805 if(halStatus != eHAL_STATUS_SUCCESS)
6806 {
6807 if(halStatus == eHAL_STATUS_PMC_PENDING)
6808 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306809 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006810 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306811 ret = wait_for_completion_interruptible_timeout(
6812 &pHddCtx->full_pwr_comp_var,
6813 msecs_to_jiffies(1000));
6814 if (ret <= 0)
6815 {
6816 hddLog(VOS_TRACE_LEVEL_ERROR,
6817 "%s: wait on full_pwr_comp_var failed %ld",
6818 __func__, ret);
6819 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006820 }
6821 else
6822 {
6823 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006824 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006825 VOS_ASSERT(0);
6826 return status;
6827 }
6828 }
6829
6830 status = VOS_STATUS_SUCCESS;
6831 }
6832
6833 break;
6834 }
6835 return status;
6836}
Katya Nigame7b69a82015-04-28 15:24:06 +05306837void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
6838 {
6839 hdd_mon_ctx_t *pMonCtx = NULL;
6840 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
6841
6842 pMonCtx->state = 0;
6843 pMonCtx->ChannelNo = 1;
6844 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05306845 pMonCtx->crcCheckEnabled = 1;
6846 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
6847 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05306848 pMonCtx->numOfMacFilters = 0;
6849 }
6850
Jeff Johnson295189b2012-06-20 16:38:30 -07006851
6852hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006853 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006854 tANI_U8 rtnl_held )
6855{
6856 hdd_adapter_t *pAdapter = NULL;
6857 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6858 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6859 VOS_STATUS exitbmpsStatus;
6860
Arif Hussain6d2a3322013-11-17 19:50:10 -08006861 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006862
Nirav Shah436658f2014-02-28 17:05:45 +05306863 if(macAddr == NULL)
6864 {
6865 /* Not received valid macAddr */
6866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6867 "%s:Unable to add virtual intf: Not able to get"
6868 "valid mac address",__func__);
6869 return NULL;
6870 }
6871
Jeff Johnson295189b2012-06-20 16:38:30 -07006872 //Disable BMPS incase of Concurrency
6873 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6874
6875 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6876 {
6877 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306878 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006879 VOS_ASSERT(0);
6880 return NULL;
6881 }
6882
6883 switch(session_type)
6884 {
6885 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006886 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006887 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006888 {
6889 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6890
6891 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306892 {
6893 hddLog(VOS_TRACE_LEVEL_FATAL,
6894 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006895 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306896 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006897
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306898#ifdef FEATURE_WLAN_TDLS
6899 /* A Mutex Lock is introduced while changing/initializing the mode to
6900 * protect the concurrent access for the Adapters by TDLS module.
6901 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306902 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306903#endif
6904
Jeff Johnsone7245742012-09-05 17:12:55 -07006905 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6906 NL80211_IFTYPE_P2P_CLIENT:
6907 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006908
Jeff Johnson295189b2012-06-20 16:38:30 -07006909 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306910#ifdef FEATURE_WLAN_TDLS
6911 mutex_unlock(&pHddCtx->tdls_lock);
6912#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306913
6914 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006915 if( VOS_STATUS_SUCCESS != status )
6916 goto err_free_netdev;
6917
6918 status = hdd_register_interface( pAdapter, rtnl_held );
6919 if( VOS_STATUS_SUCCESS != status )
6920 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306921#ifdef FEATURE_WLAN_TDLS
6922 mutex_lock(&pHddCtx->tdls_lock);
6923#endif
c_hpothu002231a2015-02-05 14:58:51 +05306924 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306925#ifdef FEATURE_WLAN_TDLS
6926 mutex_unlock(&pHddCtx->tdls_lock);
6927#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006928 goto err_free_netdev;
6929 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306930
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306931 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306932 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306933
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306934#ifdef WLAN_NS_OFFLOAD
6935 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306936 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306937#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006938 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306939 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006940 netif_tx_disable(pAdapter->dev);
6941 //netif_tx_disable(pWlanDev);
6942 netif_carrier_off(pAdapter->dev);
6943
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306944 if (WLAN_HDD_P2P_CLIENT == session_type ||
6945 WLAN_HDD_P2P_DEVICE == session_type)
6946 {
6947 /* Initialize the work queue to defer the
6948 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306949 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306950 hdd_p2p_roc_work_queue);
6951 }
6952
Jeff Johnson295189b2012-06-20 16:38:30 -07006953 break;
6954 }
6955
Jeff Johnson295189b2012-06-20 16:38:30 -07006956 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006957 case WLAN_HDD_SOFTAP:
6958 {
6959 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6960 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306961 {
6962 hddLog(VOS_TRACE_LEVEL_FATAL,
6963 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006964 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306965 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006966
Jeff Johnson295189b2012-06-20 16:38:30 -07006967 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6968 NL80211_IFTYPE_AP:
6969 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006970 pAdapter->device_mode = session_type;
6971
6972 status = hdd_init_ap_mode(pAdapter);
6973 if( VOS_STATUS_SUCCESS != status )
6974 goto err_free_netdev;
6975
Nirav Shah7e3c8132015-06-22 23:51:42 +05306976 status = hdd_sta_id_hash_attach(pAdapter);
6977 if (VOS_STATUS_SUCCESS != status)
6978 {
6979 hddLog(VOS_TRACE_LEVEL_FATAL,
6980 FL("failed to attach hash for session %d"), session_type);
6981 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
6982 goto err_free_netdev;
6983 }
6984
Jeff Johnson295189b2012-06-20 16:38:30 -07006985 status = hdd_register_hostapd( pAdapter, rtnl_held );
6986 if( VOS_STATUS_SUCCESS != status )
6987 {
c_hpothu002231a2015-02-05 14:58:51 +05306988 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006989 goto err_free_netdev;
6990 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306991 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006992 netif_tx_disable(pAdapter->dev);
6993 netif_carrier_off(pAdapter->dev);
6994
6995 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306996
6997 if (WLAN_HDD_P2P_GO == session_type)
6998 {
6999 /* Initialize the work queue to
7000 * defer the back to back RoC request */
7001 INIT_DELAYED_WORK(&pAdapter->roc_work,
7002 hdd_p2p_roc_work_queue);
7003 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007004 break;
7005 }
7006 case WLAN_HDD_MONITOR:
7007 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007008 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7009 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307010 {
7011 hddLog(VOS_TRACE_LEVEL_FATAL,
7012 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007013 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307014 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007015
Katya Nigame7b69a82015-04-28 15:24:06 +05307016 // Register wireless extensions
7017 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
7018 {
7019 hddLog(VOS_TRACE_LEVEL_FATAL,
7020 "hdd_register_wext() failed with status code %08d [x%08x]",
7021 status, status );
7022 status = VOS_STATUS_E_FAILURE;
7023 }
7024
Jeff Johnson295189b2012-06-20 16:38:30 -07007025 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
7026 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007027#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
7028 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
7029#else
7030 pAdapter->dev->open = hdd_mon_open;
7031 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05307032 pAdapter->dev->stop = hdd_mon_stop;
7033 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07007034#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05307035 status = hdd_register_interface( pAdapter, rtnl_held );
7036 hdd_init_mon_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007037 hdd_init_tx_rx( pAdapter );
7038 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05307039 //Stop the Interface TX queue.
7040 netif_tx_disable(pAdapter->dev);
7041 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007042 }
7043 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007044 case WLAN_HDD_FTM:
7045 {
7046 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7047
7048 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307049 {
7050 hddLog(VOS_TRACE_LEVEL_FATAL,
7051 FL("failed to allocate adapter for session %d"), session_type);
7052 return NULL;
7053 }
7054
Jeff Johnson295189b2012-06-20 16:38:30 -07007055 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
7056 * message while loading driver in FTM mode. */
7057 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
7058 pAdapter->device_mode = session_type;
7059 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307060
7061 hdd_init_tx_rx( pAdapter );
7062
7063 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307064 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307065 netif_tx_disable(pAdapter->dev);
7066 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007067 }
7068 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007069 default:
7070 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307071 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
7072 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007073 VOS_ASSERT(0);
7074 return NULL;
7075 }
7076 }
7077
Jeff Johnson295189b2012-06-20 16:38:30 -07007078 if( VOS_STATUS_SUCCESS == status )
7079 {
7080 //Add it to the hdd's session list.
7081 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
7082 if( NULL == pHddAdapterNode )
7083 {
7084 status = VOS_STATUS_E_NOMEM;
7085 }
7086 else
7087 {
7088 pHddAdapterNode->pAdapter = pAdapter;
7089 status = hdd_add_adapter_back ( pHddCtx,
7090 pHddAdapterNode );
7091 }
7092 }
7093
7094 if( VOS_STATUS_SUCCESS != status )
7095 {
7096 if( NULL != pAdapter )
7097 {
7098 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
7099 pAdapter = NULL;
7100 }
7101 if( NULL != pHddAdapterNode )
7102 {
7103 vos_mem_free( pHddAdapterNode );
7104 }
7105
7106 goto resume_bmps;
7107 }
7108
7109 if(VOS_STATUS_SUCCESS == status)
7110 {
7111 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
7112
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07007113 //Initialize the WoWL service
7114 if(!hdd_init_wowl(pAdapter))
7115 {
7116 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
7117 goto err_free_netdev;
7118 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007119 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007120 return pAdapter;
7121
7122err_free_netdev:
7123 free_netdev(pAdapter->dev);
7124 wlan_hdd_release_intf_addr( pHddCtx,
7125 pAdapter->macAddressCurrent.bytes );
7126
7127resume_bmps:
7128 //If bmps disabled enable it
7129 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
7130 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307131 if (pHddCtx->hdd_wlan_suspended)
7132 {
7133 hdd_set_pwrparams(pHddCtx);
7134 }
7135 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007136 }
7137 return NULL;
7138}
7139
7140VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7141 tANI_U8 rtnl_held )
7142{
7143 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
7144 VOS_STATUS status;
7145
7146 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
7147 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307148 {
7149 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
7150 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007151 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307152 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007153
7154 while ( pCurrent->pAdapter != pAdapter )
7155 {
7156 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
7157 if( VOS_STATUS_SUCCESS != status )
7158 break;
7159
7160 pCurrent = pNext;
7161 }
7162 pAdapterNode = pCurrent;
7163 if( VOS_STATUS_SUCCESS == status )
7164 {
7165 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7166 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307167
7168#ifdef FEATURE_WLAN_TDLS
7169
7170 /* A Mutex Lock is introduced while changing/initializing the mode to
7171 * protect the concurrent access for the Adapters by TDLS module.
7172 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307173 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307174#endif
7175
Jeff Johnson295189b2012-06-20 16:38:30 -07007176 hdd_remove_adapter( pHddCtx, pAdapterNode );
7177 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007178 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007179
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307180#ifdef FEATURE_WLAN_TDLS
7181 mutex_unlock(&pHddCtx->tdls_lock);
7182#endif
7183
Jeff Johnson295189b2012-06-20 16:38:30 -07007184
7185 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307186 if ((!vos_concurrent_open_sessions_running()) &&
7187 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7188 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007189 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307190 if (pHddCtx->hdd_wlan_suspended)
7191 {
7192 hdd_set_pwrparams(pHddCtx);
7193 }
7194 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007195 }
7196
7197 return VOS_STATUS_SUCCESS;
7198 }
7199
7200 return VOS_STATUS_E_FAILURE;
7201}
7202
7203VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7204{
7205 hdd_adapter_list_node_t *pHddAdapterNode;
7206 VOS_STATUS status;
7207
7208 ENTER();
7209
7210 do
7211 {
7212 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7213 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7214 {
7215 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7216 vos_mem_free( pHddAdapterNode );
7217 }
7218 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7219
7220 EXIT();
7221
7222 return VOS_STATUS_SUCCESS;
7223}
7224
7225void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7226{
7227 v_U8_t addIE[1] = {0};
7228
7229 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7230 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7231 eANI_BOOLEAN_FALSE) )
7232 {
7233 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007234 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007235 }
7236
7237 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7238 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7239 eANI_BOOLEAN_FALSE) )
7240 {
7241 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007242 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007243 }
7244
7245 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7246 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7247 eANI_BOOLEAN_FALSE) )
7248 {
7249 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007250 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007251 }
7252}
7253
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307254VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7255 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007256{
7257 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7258 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307259 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007260 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307261 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307262 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05307263 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007264
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307265 if (pHddCtx->isLogpInProgress) {
7266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7267 "%s:LOGP in Progress. Ignore!!!",__func__);
7268 return VOS_STATUS_E_FAILURE;
7269 }
7270
Jeff Johnson295189b2012-06-20 16:38:30 -07007271 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307272
Bhargav Shah784e6a52015-07-22 16:52:35 +05307273 if ( VOS_TRUE == bCloseSession )
7274 {
7275 status = hdd_sta_id_hash_detach(pAdapter);
7276 if (status != VOS_STATUS_SUCCESS)
7277 hddLog(VOS_TRACE_LEVEL_ERROR,
7278 FL("sta id hash detach failed"));
7279 }
Nirav Shah7e3c8132015-06-22 23:51:42 +05307280
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307281 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007282 switch(pAdapter->device_mode)
7283 {
7284 case WLAN_HDD_INFRA_STATION:
7285 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007286 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307287 {
7288 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05307289#ifdef FEATURE_WLAN_TDLS
7290 mutex_lock(&pHddCtx->tdls_lock);
7291 wlan_hdd_tdls_exit(pAdapter, TRUE);
7292 mutex_unlock(&pHddCtx->tdls_lock);
7293#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307294 if( hdd_connIsConnected(pstation) ||
7295 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007296 {
7297 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7298 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7299 pAdapter->sessionId,
7300 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7301 else
7302 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7303 pAdapter->sessionId,
7304 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7305 //success implies disconnect command got queued up successfully
7306 if(halStatus == eHAL_STATUS_SUCCESS)
7307 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307308 ret = wait_for_completion_interruptible_timeout(
7309 &pAdapter->disconnect_comp_var,
7310 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7311 if (ret <= 0)
7312 {
7313 hddLog(VOS_TRACE_LEVEL_ERROR,
7314 "%s: wait on disconnect_comp_var failed %ld",
7315 __func__, ret);
7316 }
7317 }
7318 else
7319 {
7320 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7321 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007322 }
7323 memset(&wrqu, '\0', sizeof(wrqu));
7324 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7325 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7326 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7327 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307328 else if(pstation->conn_info.connState ==
7329 eConnectionState_Disconnecting)
7330 {
7331 ret = wait_for_completion_interruptible_timeout(
7332 &pAdapter->disconnect_comp_var,
7333 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7334 if (ret <= 0)
7335 {
7336 hddLog(VOS_TRACE_LEVEL_ERROR,
7337 FL("wait on disconnect_comp_var failed %ld"), ret);
7338 }
7339 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307340 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007341 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307342 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307343 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007344 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307345 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7346 {
7347 while (pAdapter->is_roc_inprogress)
7348 {
7349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7350 "%s: ROC in progress for session %d!!!",
7351 __func__, pAdapter->sessionId);
7352 // waiting for ROC to expire
7353 msleep(500);
7354 /* In GO present case , if retry exceeds 3,
7355 it means something went wrong. */
7356 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7357 {
7358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7359 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307360 if (eHAL_STATUS_SUCCESS !=
7361 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7362 pAdapter->sessionId ))
7363 {
7364 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7365 FL("Failed to Cancel Remain on Channel"));
7366 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307367 wait_for_completion_interruptible_timeout(
7368 &pAdapter->cancel_rem_on_chan_var,
7369 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7370 break;
7371 }
7372 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307373 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307374 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307375#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307376 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307377#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307378
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307379 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307380
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307381 /* It is possible that the caller of this function does not
7382 * wish to close the session
7383 */
7384 if (VOS_TRUE == bCloseSession &&
7385 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007386 {
7387 INIT_COMPLETION(pAdapter->session_close_comp_var);
7388 if (eHAL_STATUS_SUCCESS ==
mukul sharmabab477d2015-06-11 17:14:55 +05307389 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, VOS_FALSE,
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307390 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007391 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307392 unsigned long ret;
7393
Jeff Johnson295189b2012-06-20 16:38:30 -07007394 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307395 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307396 &pAdapter->session_close_comp_var,
7397 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307398 if ( 0 >= ret)
7399 {
7400 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307401 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307402 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007403 }
7404 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307405 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007406 break;
7407
7408 case WLAN_HDD_SOFTAP:
7409 case WLAN_HDD_P2P_GO:
7410 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307411 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7412 while (pAdapter->is_roc_inprogress) {
7413 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7414 "%s: ROC in progress for session %d!!!",
7415 __func__, pAdapter->sessionId);
7416 msleep(500);
7417 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7418 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7419 "%s: ROC completion is not received.!!!", __func__);
7420 WLANSAP_CancelRemainOnChannel(
7421 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7422 wait_for_completion_interruptible_timeout(
7423 &pAdapter->cancel_rem_on_chan_var,
7424 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7425 break;
7426 }
7427 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307428
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307429 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307430 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007431 mutex_lock(&pHddCtx->sap_lock);
7432 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7433 {
7434 VOS_STATUS status;
7435 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7436
7437 //Stop Bss.
7438 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7439 if (VOS_IS_STATUS_SUCCESS(status))
7440 {
7441 hdd_hostapd_state_t *pHostapdState =
7442 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7443
7444 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7445
7446 if (!VOS_IS_STATUS_SUCCESS(status))
7447 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307448 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7449 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007450 }
7451 }
7452 else
7453 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007454 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007455 }
7456 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307457 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007458
7459 if (eHAL_STATUS_FAILURE ==
7460 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7461 0, NULL, eANI_BOOLEAN_FALSE))
7462 {
7463 hddLog(LOGE,
7464 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007465 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007466 }
7467
7468 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7469 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7470 eANI_BOOLEAN_FALSE) )
7471 {
7472 hddLog(LOGE,
7473 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7474 }
7475
7476 // Reset WNI_CFG_PROBE_RSP Flags
7477 wlan_hdd_reset_prob_rspies(pAdapter);
7478 kfree(pAdapter->sessionCtx.ap.beacon);
7479 pAdapter->sessionCtx.ap.beacon = NULL;
7480 }
7481 mutex_unlock(&pHddCtx->sap_lock);
7482 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007483
Jeff Johnson295189b2012-06-20 16:38:30 -07007484 case WLAN_HDD_MONITOR:
7485 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007486
Jeff Johnson295189b2012-06-20 16:38:30 -07007487 default:
7488 break;
7489 }
7490
7491 EXIT();
7492 return VOS_STATUS_SUCCESS;
7493}
7494
7495VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7496{
7497 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7498 VOS_STATUS status;
7499 hdd_adapter_t *pAdapter;
7500
7501 ENTER();
7502
7503 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7504
7505 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7506 {
7507 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007508
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307509 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007510
7511 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7512 pAdapterNode = pNext;
7513 }
7514
7515 EXIT();
7516
7517 return VOS_STATUS_SUCCESS;
7518}
7519
Rajeev Kumarf999e582014-01-09 17:33:29 -08007520
7521#ifdef FEATURE_WLAN_BATCH_SCAN
7522/**---------------------------------------------------------------------------
7523
7524 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7525 structures
7526
7527 \param - pAdapter Pointer to HDD adapter
7528
7529 \return - None
7530
7531 --------------------------------------------------------------------------*/
7532void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7533{
7534 tHddBatchScanRsp *pNode;
7535 tHddBatchScanRsp *pPrev;
7536
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307537 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007538 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307539 hddLog(VOS_TRACE_LEVEL_ERROR,
7540 "%s: Adapter context is Null", __func__);
7541 return;
7542 }
7543
7544 pNode = pAdapter->pBatchScanRsp;
7545 while (pNode)
7546 {
7547 pPrev = pNode;
7548 pNode = pNode->pNext;
7549 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007550 }
7551
7552 pAdapter->pBatchScanRsp = NULL;
7553 pAdapter->numScanList = 0;
7554 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7555 pAdapter->prev_batch_id = 0;
7556
7557 return;
7558}
7559#endif
7560
7561
Jeff Johnson295189b2012-06-20 16:38:30 -07007562VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7563{
7564 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7565 VOS_STATUS status;
7566 hdd_adapter_t *pAdapter;
7567
7568 ENTER();
7569
7570 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7571
7572 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7573 {
7574 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307575 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007576 netif_tx_disable(pAdapter->dev);
7577 netif_carrier_off(pAdapter->dev);
7578
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007579 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7580
Jeff Johnson295189b2012-06-20 16:38:30 -07007581 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307582
Katya Nigam1fd24402015-02-16 14:52:19 +05307583 if(pAdapter->device_mode == WLAN_HDD_IBSS )
7584 hdd_ibss_deinit_tx_rx(pAdapter);
7585
Nirav Shah7e3c8132015-06-22 23:51:42 +05307586 status = hdd_sta_id_hash_detach(pAdapter);
7587 if (status != VOS_STATUS_SUCCESS)
7588 hddLog(VOS_TRACE_LEVEL_ERROR,
7589 FL("sta id hash detach failed for session id %d"),
7590 pAdapter->sessionId);
7591
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307592 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7593
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307594 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7595 {
7596 hdd_wmm_adapter_close( pAdapter );
7597 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7598 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007599
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307600 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7601 {
7602 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7603 }
7604
Rajeev Kumarf999e582014-01-09 17:33:29 -08007605#ifdef FEATURE_WLAN_BATCH_SCAN
7606 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7607 {
7608 hdd_deinit_batch_scan(pAdapter);
7609 }
7610#endif
7611
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307612#ifdef FEATURE_WLAN_TDLS
7613 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307614 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307615 mutex_unlock(&pHddCtx->tdls_lock);
7616#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007617 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7618 pAdapterNode = pNext;
7619 }
7620
7621 EXIT();
7622
7623 return VOS_STATUS_SUCCESS;
7624}
7625
7626VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7627{
7628 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7629 VOS_STATUS status;
7630 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307631 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007632
7633 ENTER();
7634
7635 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7636
7637 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7638 {
7639 pAdapter = pAdapterNode->pAdapter;
7640
Kumar Anand82c009f2014-05-29 00:29:42 -07007641 hdd_wmm_init( pAdapter );
7642
Jeff Johnson295189b2012-06-20 16:38:30 -07007643 switch(pAdapter->device_mode)
7644 {
7645 case WLAN_HDD_INFRA_STATION:
7646 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007647 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307648
7649 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7650
Jeff Johnson295189b2012-06-20 16:38:30 -07007651 hdd_init_station_mode(pAdapter);
7652 /* Open the gates for HDD to receive Wext commands */
7653 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007654 pHddCtx->scan_info.mScanPending = FALSE;
7655 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007656
7657 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +05307658 if (!pHddCtx->isLogpInProgress)
7659 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007660
7661 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307662 if (eConnectionState_Associated == connState ||
7663 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007664 {
7665 union iwreq_data wrqu;
7666 memset(&wrqu, '\0', sizeof(wrqu));
7667 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7668 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7669 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007670 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007671
Jeff Johnson295189b2012-06-20 16:38:30 -07007672 /* indicate disconnected event to nl80211 */
7673 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7674 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007675 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307676 else if (eConnectionState_Connecting == connState)
7677 {
7678 /*
7679 * Indicate connect failure to supplicant if we were in the
7680 * process of connecting
7681 */
7682 cfg80211_connect_result(pAdapter->dev, NULL,
7683 NULL, 0, NULL, 0,
7684 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7685 GFP_KERNEL);
7686 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007687 break;
7688
7689 case WLAN_HDD_SOFTAP:
7690 /* softAP can handle SSR */
7691 break;
7692
7693 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007694 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007695 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007696 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007697 break;
7698
7699 case WLAN_HDD_MONITOR:
7700 /* monitor interface start */
7701 break;
7702 default:
7703 break;
7704 }
7705
7706 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7707 pAdapterNode = pNext;
7708 }
7709
7710 EXIT();
7711
7712 return VOS_STATUS_SUCCESS;
7713}
7714
7715VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7716{
7717 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7718 hdd_adapter_t *pAdapter;
7719 VOS_STATUS status;
7720 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307721 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007722
7723 ENTER();
7724
7725 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7726
7727 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7728 {
7729 pAdapter = pAdapterNode->pAdapter;
7730
7731 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7732 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7733 {
7734 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7735 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7736
Abhishek Singhf4669da2014-05-26 15:07:49 +05307737 hddLog(VOS_TRACE_LEVEL_INFO,
7738 "%s: Set HDD connState to eConnectionState_NotConnected",
7739 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007740 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7741 init_completion(&pAdapter->disconnect_comp_var);
7742 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7743 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7744
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307745 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007746 &pAdapter->disconnect_comp_var,
7747 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307748 if (0 >= ret)
7749 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7750 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007751
7752 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7753 pHddCtx->isAmpAllowed = VOS_FALSE;
7754 sme_RoamConnect(pHddCtx->hHal,
7755 pAdapter->sessionId, &(pWextState->roamProfile),
7756 &roamId);
7757 }
7758
7759 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7760 pAdapterNode = pNext;
7761 }
7762
7763 EXIT();
7764
7765 return VOS_STATUS_SUCCESS;
7766}
7767
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007768void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7769{
7770 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7771 VOS_STATUS status;
7772 hdd_adapter_t *pAdapter;
7773 hdd_station_ctx_t *pHddStaCtx;
7774 hdd_ap_ctx_t *pHddApCtx;
7775 hdd_hostapd_state_t * pHostapdState;
7776 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7777 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7778 const char *p2pMode = "DEV";
7779 const char *ccMode = "Standalone";
7780 int n;
7781
7782 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7783 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7784 {
7785 pAdapter = pAdapterNode->pAdapter;
7786 switch (pAdapter->device_mode) {
7787 case WLAN_HDD_INFRA_STATION:
7788 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7789 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7790 staChannel = pHddStaCtx->conn_info.operationChannel;
7791 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7792 }
7793 break;
7794 case WLAN_HDD_P2P_CLIENT:
7795 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7796 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7797 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7798 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7799 p2pMode = "CLI";
7800 }
7801 break;
7802 case WLAN_HDD_P2P_GO:
7803 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7804 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7805 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7806 p2pChannel = pHddApCtx->operatingChannel;
7807 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7808 }
7809 p2pMode = "GO";
7810 break;
7811 case WLAN_HDD_SOFTAP:
7812 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7813 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7814 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7815 apChannel = pHddApCtx->operatingChannel;
7816 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7817 }
7818 break;
7819 default:
7820 break;
7821 }
7822 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7823 pAdapterNode = pNext;
7824 }
7825 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7826 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7827 }
7828 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7829 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7830 if (p2pChannel > 0) {
7831 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7832 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7833 }
7834 if (apChannel > 0) {
7835 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7836 apChannel, MAC_ADDR_ARRAY(apBssid));
7837 }
7838
7839 if (p2pChannel > 0 && apChannel > 0) {
7840 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7841 }
7842}
7843
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007844bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007845{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007846 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007847}
7848
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007849/* Once SSR is disabled then it cannot be set. */
7850void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007851{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007852 if (HDD_SSR_DISABLED == isSsrRequired)
7853 return;
7854
Jeff Johnson295189b2012-06-20 16:38:30 -07007855 isSsrRequired = value;
7856}
7857
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05307858void hdd_set_pre_close( hdd_context_t *pHddCtx)
7859{
7860 sme_PreClose(pHddCtx->hHal);
7861}
7862
Jeff Johnson295189b2012-06-20 16:38:30 -07007863VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7864 hdd_adapter_list_node_t** ppAdapterNode)
7865{
7866 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307867 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007868 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7869 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307870 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007871 return status;
7872}
7873
7874VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7875 hdd_adapter_list_node_t* pAdapterNode,
7876 hdd_adapter_list_node_t** pNextAdapterNode)
7877{
7878 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307879 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007880 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7881 (hdd_list_node_t*) pAdapterNode,
7882 (hdd_list_node_t**)pNextAdapterNode );
7883
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307884 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007885 return status;
7886}
7887
7888VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7889 hdd_adapter_list_node_t* pAdapterNode)
7890{
7891 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307892 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007893 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7894 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307895 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007896 return status;
7897}
7898
7899VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7900 hdd_adapter_list_node_t** ppAdapterNode)
7901{
7902 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307903 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007904 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7905 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307906 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007907 return status;
7908}
7909
7910VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7911 hdd_adapter_list_node_t* pAdapterNode)
7912{
7913 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307914 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007915 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7916 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307917 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007918 return status;
7919}
7920
7921VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7922 hdd_adapter_list_node_t* pAdapterNode)
7923{
7924 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307925 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007926 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7927 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307928 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007929 return status;
7930}
7931
7932hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7933 tSirMacAddr macAddr )
7934{
7935 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7936 hdd_adapter_t *pAdapter;
7937 VOS_STATUS status;
7938
7939 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7940
7941 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7942 {
7943 pAdapter = pAdapterNode->pAdapter;
7944
7945 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7946 macAddr, sizeof(tSirMacAddr) ) )
7947 {
7948 return pAdapter;
7949 }
7950 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7951 pAdapterNode = pNext;
7952 }
7953
7954 return NULL;
7955
7956}
7957
7958hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7959{
7960 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7961 hdd_adapter_t *pAdapter;
7962 VOS_STATUS status;
7963
7964 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7965
7966 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7967 {
7968 pAdapter = pAdapterNode->pAdapter;
7969
7970 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7971 IFNAMSIZ ) )
7972 {
7973 return pAdapter;
7974 }
7975 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7976 pAdapterNode = pNext;
7977 }
7978
7979 return NULL;
7980
7981}
7982
7983hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7984{
7985 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7986 hdd_adapter_t *pAdapter;
7987 VOS_STATUS status;
7988
7989 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7990
7991 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7992 {
7993 pAdapter = pAdapterNode->pAdapter;
7994
7995 if( pAdapter && (mode == pAdapter->device_mode) )
7996 {
7997 return pAdapter;
7998 }
7999 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8000 pAdapterNode = pNext;
8001 }
8002
8003 return NULL;
8004
8005}
8006
8007//Remove this function later
8008hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
8009{
8010 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8011 hdd_adapter_t *pAdapter;
8012 VOS_STATUS status;
8013
8014 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8015
8016 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8017 {
8018 pAdapter = pAdapterNode->pAdapter;
8019
8020 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
8021 {
8022 return pAdapter;
8023 }
8024
8025 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8026 pAdapterNode = pNext;
8027 }
8028
8029 return NULL;
8030
8031}
8032
Jeff Johnson295189b2012-06-20 16:38:30 -07008033/**---------------------------------------------------------------------------
8034
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308035 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008036
8037 This API returns the operating channel of the requested device mode
8038
8039 \param - pHddCtx - Pointer to the HDD context.
8040 - mode - Device mode for which operating channel is required
8041 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
8042 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
8043 \return - channel number. "0" id the requested device is not found OR it is not connected.
8044 --------------------------------------------------------------------------*/
8045v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
8046{
8047 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8048 VOS_STATUS status;
8049 hdd_adapter_t *pAdapter;
8050 v_U8_t operatingChannel = 0;
8051
8052 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8053
8054 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8055 {
8056 pAdapter = pAdapterNode->pAdapter;
8057
8058 if( mode == pAdapter->device_mode )
8059 {
8060 switch(pAdapter->device_mode)
8061 {
8062 case WLAN_HDD_INFRA_STATION:
8063 case WLAN_HDD_P2P_CLIENT:
8064 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
8065 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
8066 break;
8067 case WLAN_HDD_SOFTAP:
8068 case WLAN_HDD_P2P_GO:
8069 /*softap connection info */
8070 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8071 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
8072 break;
8073 default:
8074 break;
8075 }
8076
8077 break; //Found the device of interest. break the loop
8078 }
8079
8080 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8081 pAdapterNode = pNext;
8082 }
8083 return operatingChannel;
8084}
8085
8086#ifdef WLAN_FEATURE_PACKET_FILTERING
8087/**---------------------------------------------------------------------------
8088
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308089 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008090
8091 This used to set the multicast address list.
8092
8093 \param - dev - Pointer to the WLAN device.
8094 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308095 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07008096
8097 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308098static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008099{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308100 hdd_adapter_t *pAdapter;
8101 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008102 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308103 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008104 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308105
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308106 ENTER();
8107
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308108 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308109 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008110 {
8111 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308112 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008113 return;
8114 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308115 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8116 ret = wlan_hdd_validate_context(pHddCtx);
8117 if (0 != ret)
8118 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308119 return;
8120 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008121 if (dev->flags & IFF_ALLMULTI)
8122 {
8123 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008124 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308125 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008126 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308127 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008128 {
8129 mc_count = netdev_mc_count(dev);
8130 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008131 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07008132 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
8133 {
8134 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008135 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308136 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008137 return;
8138 }
8139
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308140 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07008141
8142 netdev_for_each_mc_addr(ha, dev) {
8143 if (i == mc_count)
8144 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308145 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
8146 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008147 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308148 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308149 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07008150 i++;
8151 }
8152 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308153
8154 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008155 return;
8156}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308157
8158static void hdd_set_multicast_list(struct net_device *dev)
8159{
8160 vos_ssr_protect(__func__);
8161 __hdd_set_multicast_list(dev);
8162 vos_ssr_unprotect(__func__);
8163}
Jeff Johnson295189b2012-06-20 16:38:30 -07008164#endif
8165
8166/**---------------------------------------------------------------------------
8167
8168 \brief hdd_select_queue() -
8169
8170 This function is registered with the Linux OS for network
8171 core to decide which queue to use first.
8172
8173 \param - dev - Pointer to the WLAN device.
8174 - skb - Pointer to OS packet (sk_buff).
8175 \return - ac, Queue Index/access category corresponding to UP in IP header
8176
8177 --------------------------------------------------------------------------*/
8178v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308179 struct sk_buff *skb
8180#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
8181 , void *accel_priv
8182#endif
8183#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8184 , select_queue_fallback_t fallback
8185#endif
8186)
Jeff Johnson295189b2012-06-20 16:38:30 -07008187{
8188 return hdd_wmm_select_queue(dev, skb);
8189}
8190
8191
8192/**---------------------------------------------------------------------------
8193
8194 \brief hdd_wlan_initial_scan() -
8195
8196 This function triggers the initial scan
8197
8198 \param - pAdapter - Pointer to the HDD adapter.
8199
8200 --------------------------------------------------------------------------*/
8201void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8202{
8203 tCsrScanRequest scanReq;
8204 tCsrChannelInfo channelInfo;
8205 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008206 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008207 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8208
8209 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8210 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8211 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8212
8213 if(sme_Is11dSupported(pHddCtx->hHal))
8214 {
8215 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8216 if ( HAL_STATUS_SUCCESS( halStatus ) )
8217 {
8218 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8219 if( !scanReq.ChannelInfo.ChannelList )
8220 {
8221 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8222 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008223 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008224 return;
8225 }
8226 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8227 channelInfo.numOfChannels);
8228 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8229 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008230 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008231 }
8232
8233 scanReq.scanType = eSIR_PASSIVE_SCAN;
8234 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8235 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8236 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8237 }
8238 else
8239 {
8240 scanReq.scanType = eSIR_ACTIVE_SCAN;
8241 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8242 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8243 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8244 }
8245
8246 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8247 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8248 {
8249 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8250 __func__, halStatus );
8251 }
8252
8253 if(sme_Is11dSupported(pHddCtx->hHal))
8254 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8255}
8256
mukul sharmabab477d2015-06-11 17:14:55 +05308257void hdd_purge_cmd_list_all_adapters( hdd_context_t *pHddCtx )
8258{
8259 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8260 VOS_STATUS status;
8261 hdd_adapter_t *pAdapter;
8262
8263 ENTER();
8264
8265 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8266
8267 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8268 {
8269 pAdapter = pAdapterNode->pAdapter;
8270
8271 status = sme_PurgeCmdList(pHddCtx->hHal, pAdapter->sessionId);
8272 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8273 pAdapterNode = pNext;
8274 }
8275
8276 EXIT();
8277}
Jeff Johnson295189b2012-06-20 16:38:30 -07008278/**---------------------------------------------------------------------------
8279
8280 \brief hdd_full_power_callback() - HDD full power callback function
8281
8282 This is the function invoked by SME to inform the result of a full power
8283 request issued by HDD
8284
8285 \param - callbackcontext - Pointer to cookie
8286 \param - status - result of request
8287
8288 \return - None
8289
8290 --------------------------------------------------------------------------*/
8291static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8292{
Jeff Johnson72a40512013-12-19 10:14:15 -08008293 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008294
8295 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308296 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008297
8298 if (NULL == callbackContext)
8299 {
8300 hddLog(VOS_TRACE_LEVEL_ERROR,
8301 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008302 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008303 return;
8304 }
8305
Jeff Johnson72a40512013-12-19 10:14:15 -08008306 /* there is a race condition that exists between this callback
8307 function and the caller since the caller could time out either
8308 before or while this code is executing. we use a spinlock to
8309 serialize these actions */
8310 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008311
8312 if (POWER_CONTEXT_MAGIC != pContext->magic)
8313 {
8314 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008315 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008316 hddLog(VOS_TRACE_LEVEL_WARN,
8317 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008318 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008319 return;
8320 }
8321
Jeff Johnson72a40512013-12-19 10:14:15 -08008322 /* context is valid so caller is still waiting */
8323
8324 /* paranoia: invalidate the magic */
8325 pContext->magic = 0;
8326
8327 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008328 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008329
8330 /* serialization is complete */
8331 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008332}
8333
Katya Nigamf0511f62015-05-05 16:40:57 +05308334void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
8335{
8336 pMonCtx->typeSubtypeBitmap = 0;
8337 if( type%10 ) /* Management Packets */
8338 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
8339 type/=10;
8340 if( type%10 ) /* Control Packets */
8341 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
8342 type/=10;
8343 if( type%10 ) /* Data Packets */
8344 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
8345}
8346
8347VOS_STATUS wlan_hdd_mon_poststartmsg( hdd_mon_ctx_t *pMonCtx )
8348{
8349 vos_msg_t monMsg;
8350
8351 monMsg.type = WDA_MON_START_REQ;
8352 monMsg.reserved = 0;
8353 monMsg.bodyptr = (v_U8_t*)pMonCtx;
8354 monMsg.bodyval = 0;
8355
8356 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8357 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8358 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8359 return VOS_STATUS_E_FAILURE;
8360 }
8361
8362 return VOS_STATUS_SUCCESS;
8363}
8364
8365void wlan_hdd_mon_poststopmsg(void)
8366{
8367 vos_msg_t monMsg;
8368
8369 monMsg.type = WDA_MON_STOP_REQ;
8370 monMsg.reserved = 0;
8371 monMsg.bodyptr = NULL;
8372 monMsg.bodyval = 0;
8373
8374 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8375 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8376 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8377 }
8378}
8379
Katya Nigame7b69a82015-04-28 15:24:06 +05308380void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
8381{
8382 VOS_STATUS vosStatus;
8383 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8384 struct wiphy *wiphy = pHddCtx->wiphy;
8385
8386 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
8387 if(pAdapter == NULL || pVosContext == NULL)
8388 {
8389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
8390 return ;
8391 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308392
8393 wlan_hdd_mon_poststopmsg();
Katya Nigame7b69a82015-04-28 15:24:06 +05308394 hdd_UnregisterWext(pAdapter->dev);
8395
8396 vos_mon_stop( pVosContext );
8397
8398 vosStatus = vos_sched_close( pVosContext );
8399 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8400 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8401 "%s: Failed to close VOSS Scheduler",__func__);
8402 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8403 }
8404
8405 vosStatus = vos_nv_close();
8406 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8407 {
8408 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8409 "%s: Failed to close NV", __func__);
8410 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8411 }
8412
8413 vos_close(pVosContext);
8414
8415 #ifdef WLAN_KD_READY_NOTIFIER
8416 nl_srv_exit(pHddCtx->ptt_pid);
8417 #else
8418 nl_srv_exit();
8419 #endif
8420
8421 if (pHddCtx->cfg_ini)
8422 {
8423 kfree(pHddCtx->cfg_ini);
8424 pHddCtx->cfg_ini= NULL;
8425 }
8426 hdd_close_all_adapters( pHddCtx );
8427
8428 wiphy_free(wiphy) ;
8429
8430}
Jeff Johnson295189b2012-06-20 16:38:30 -07008431/**---------------------------------------------------------------------------
8432
8433 \brief hdd_wlan_exit() - HDD WLAN exit function
8434
8435 This is the driver exit point (invoked during rmmod)
8436
8437 \param - pHddCtx - Pointer to the HDD Context
8438
8439 \return - None
8440
8441 --------------------------------------------------------------------------*/
8442void hdd_wlan_exit(hdd_context_t *pHddCtx)
8443{
8444 eHalStatus halStatus;
8445 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8446 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308447 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008448 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008449 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008450 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308451 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008452
8453 ENTER();
8454
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308455
Katya Nigame7b69a82015-04-28 15:24:06 +05308456 if (VOS_MONITOR_MODE == hdd_get_conparam())
8457 {
8458 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
8459 wlan_hdd_mon_close(pHddCtx);
8460 return;
8461 }
8462 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08008463 {
8464 // Unloading, restart logic is no more required.
8465 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008466
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308467#ifdef FEATURE_WLAN_TDLS
8468 /* At the time of driver unloading; if tdls connection is present;
8469 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8470 * wlan_hdd_tdls_find_peer always checks for valid context;
8471 * as load/unload in progress there can be a race condition.
8472 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8473 * when tdls state is enabled.
8474 * As soon as driver set load/unload flag; tdls flag also needs
8475 * to be disabled so that hdd_rx_packet_cbk won't call
8476 * wlan_hdd_tdls_find_peer.
8477 */
8478 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8479#endif
8480
c_hpothu5ab05e92014-06-13 17:34:05 +05308481 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8482 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008483 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308484 pAdapter = pAdapterNode->pAdapter;
8485 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008486 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308487 /* Disable TX on the interface, after this hard_start_xmit() will
8488 * not be called on that interface
8489 */
8490 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8491 netif_tx_disable(pAdapter->dev);
8492
8493 /* Mark the interface status as "down" for outside world */
8494 netif_carrier_off(pAdapter->dev);
8495
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308496 /* DeInit the adapter. This ensures that all data packets
8497 * are freed.
8498 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308499#ifdef FEATURE_WLAN_TDLS
8500 mutex_lock(&pHddCtx->tdls_lock);
8501#endif
c_hpothu002231a2015-02-05 14:58:51 +05308502 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308503#ifdef FEATURE_WLAN_TDLS
8504 mutex_unlock(&pHddCtx->tdls_lock);
8505#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308506
c_hpothu5ab05e92014-06-13 17:34:05 +05308507 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8508 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8509 {
8510 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8511 hdd_UnregisterWext(pAdapter->dev);
8512 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308513
Jeff Johnson295189b2012-06-20 16:38:30 -07008514 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308515 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8516 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008517 }
mukul sharmabab477d2015-06-11 17:14:55 +05308518
8519 //Purge all sme cmd's for all interface
8520 hdd_purge_cmd_list_all_adapters(pHddCtx);
8521
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308522 // Cancel any outstanding scan requests. We are about to close all
8523 // of our adapters, but an adapter structure is what SME passes back
8524 // to our callback function. Hence if there are any outstanding scan
8525 // requests then there is a race condition between when the adapter
8526 // is closed and when the callback is invoked.We try to resolve that
8527 // race condition here by canceling any outstanding scans before we
8528 // close the adapters.
8529 // Note that the scans may be cancelled in an asynchronous manner,
8530 // so ideally there needs to be some kind of synchronization. Rather
8531 // than introduce a new synchronization here, we will utilize the
8532 // fact that we are about to Request Full Power, and since that is
8533 // synchronized, the expectation is that by the time Request Full
8534 // Power has completed all scans will be cancelled.
8535 if (pHddCtx->scan_info.mScanPending)
8536 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308537 if(NULL != pAdapter)
8538 {
8539 hddLog(VOS_TRACE_LEVEL_INFO,
8540 FL("abort scan mode: %d sessionId: %d"),
8541 pAdapter->device_mode,
8542 pAdapter->sessionId);
8543 }
8544 hdd_abort_mac_scan(pHddCtx,
8545 pHddCtx->scan_info.sessionId,
8546 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308547 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008548 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308549 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008550 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308551 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308552 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8553 {
8554 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8556 "%s: in middle of FTM START", __func__);
8557 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8558 msecs_to_jiffies(20000));
8559 if(!lrc)
8560 {
8561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8562 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8563 }
8564 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008565 wlan_hdd_ftm_close(pHddCtx);
8566 goto free_hdd_ctx;
8567 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308568
Jeff Johnson295189b2012-06-20 16:38:30 -07008569 /* DeRegister with platform driver as client for Suspend/Resume */
8570 vosStatus = hddDeregisterPmOps(pHddCtx);
8571 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8572 {
8573 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8574 VOS_ASSERT(0);
8575 }
8576
8577 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8578 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8579 {
8580 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8581 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008582
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008583 //Stop the traffic monitor timer
8584 if ( VOS_TIMER_STATE_RUNNING ==
8585 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8586 {
8587 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8588 }
8589
8590 // Destroy the traffic monitor timer
8591 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8592 &pHddCtx->tx_rx_trafficTmr)))
8593 {
8594 hddLog(VOS_TRACE_LEVEL_ERROR,
8595 "%s: Cannot deallocate Traffic monitor timer", __func__);
8596 }
8597
Jeff Johnson295189b2012-06-20 16:38:30 -07008598 //Disable IMPS/BMPS as we do not want the device to enter any power
8599 //save mode during shutdown
8600 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8601 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8602 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8603
8604 //Ensure that device is in full power as we will touch H/W during vos_Stop
8605 init_completion(&powerContext.completion);
8606 powerContext.magic = POWER_CONTEXT_MAGIC;
8607
8608 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8609 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8610
8611 if (eHAL_STATUS_SUCCESS != halStatus)
8612 {
8613 if (eHAL_STATUS_PMC_PENDING == halStatus)
8614 {
8615 /* request was sent -- wait for the response */
8616 lrc = wait_for_completion_interruptible_timeout(
8617 &powerContext.completion,
8618 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008619 if (lrc <= 0)
8620 {
8621 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008622 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008623 }
8624 }
8625 else
8626 {
8627 hddLog(VOS_TRACE_LEVEL_ERROR,
8628 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008629 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008630 /* continue -- need to clean up as much as possible */
8631 }
8632 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +05308633 if ((eHAL_STATUS_SUCCESS == halStatus) ||
8634 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
8635 {
8636 /* This will issue a dump command which will clean up
8637 BTQM queues and unblock MC thread */
8638 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
8639 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008640
Jeff Johnson72a40512013-12-19 10:14:15 -08008641 /* either we never sent a request, we sent a request and received a
8642 response or we sent a request and timed out. if we never sent a
8643 request or if we sent a request and got a response, we want to
8644 clear the magic out of paranoia. if we timed out there is a
8645 race condition such that the callback function could be
8646 executing at the same time we are. of primary concern is if the
8647 callback function had already verified the "magic" but had not
8648 yet set the completion variable when a timeout occurred. we
8649 serialize these activities by invalidating the magic while
8650 holding a shared spinlock which will cause us to block if the
8651 callback is currently executing */
8652 spin_lock(&hdd_context_lock);
8653 powerContext.magic = 0;
8654 spin_unlock(&hdd_context_lock);
8655
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +05308656 /* If Device is shutdown, no point for SME to wait for responses
8657 from device. Pre Close SME */
8658 if(wcnss_device_is_shutdown())
8659 {
8660 sme_PreClose(pHddCtx->hHal);
8661 }
Yue Ma0d4891e2013-08-06 17:01:45 -07008662 hdd_debugfs_exit(pHddCtx);
8663
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308664#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +05308665 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308666 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8667#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +05308668 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308669 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8670
Jeff Johnson295189b2012-06-20 16:38:30 -07008671 // Unregister the Net Device Notifier
8672 unregister_netdevice_notifier(&hdd_netdev_notifier);
8673
Jeff Johnson295189b2012-06-20 16:38:30 -07008674 hdd_stop_all_adapters( pHddCtx );
8675
Jeff Johnson295189b2012-06-20 16:38:30 -07008676#ifdef WLAN_BTAMP_FEATURE
8677 vosStatus = WLANBAP_Stop(pVosContext);
8678 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8679 {
8680 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8681 "%s: Failed to stop BAP",__func__);
8682 }
8683#endif //WLAN_BTAMP_FEATURE
8684
8685 //Stop all the modules
8686 vosStatus = vos_stop( pVosContext );
8687 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8688 {
8689 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8690 "%s: Failed to stop VOSS",__func__);
8691 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8692 }
8693
Jeff Johnson295189b2012-06-20 16:38:30 -07008694 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008695 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008696
8697 //Close the scheduler before calling vos_close to make sure no thread is
8698 // scheduled after the each module close is called i.e after all the data
8699 // structures are freed.
8700 vosStatus = vos_sched_close( pVosContext );
8701 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8702 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8703 "%s: Failed to close VOSS Scheduler",__func__);
8704 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8705 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008706#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8707 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308708 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008709#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008710 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308711 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008712
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308713#ifdef CONFIG_ENABLE_LINUX_REG
8714 vosStatus = vos_nv_close();
8715 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8716 {
8717 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8718 "%s: Failed to close NV", __func__);
8719 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8720 }
8721#endif
8722
Jeff Johnson295189b2012-06-20 16:38:30 -07008723 //Close VOSS
8724 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8725 vos_close(pVosContext);
8726
Jeff Johnson295189b2012-06-20 16:38:30 -07008727 //Close Watchdog
8728 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8729 vos_watchdog_close(pVosContext);
8730
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308731 //Clean up HDD Nlink Service
8732 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308733
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308734#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308735 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308736 {
8737 wlan_logging_sock_deactivate_svc();
8738 }
8739#endif
8740
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308741#ifdef WLAN_KD_READY_NOTIFIER
8742 nl_srv_exit(pHddCtx->ptt_pid);
8743#else
8744 nl_srv_exit();
8745#endif /* WLAN_KD_READY_NOTIFIER */
8746
8747
Jeff Johnson295189b2012-06-20 16:38:30 -07008748 hdd_close_all_adapters( pHddCtx );
8749
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +05308750free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -07008751 /* free the power on lock from platform driver */
8752 if (free_riva_power_on_lock("wlan"))
8753 {
8754 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8755 __func__);
8756 }
8757
c_hpothu78c7b602014-05-17 17:35:49 +05308758 //Free up dynamically allocated members inside HDD Adapter
8759 if (pHddCtx->cfg_ini)
8760 {
8761 kfree(pHddCtx->cfg_ini);
8762 pHddCtx->cfg_ini= NULL;
8763 }
8764
Leo Changf04ddad2013-09-18 13:46:38 -07008765 /* FTM mode, WIPHY did not registered
8766 If un-register here, system crash will happen */
8767 if (VOS_FTM_MODE != hdd_get_conparam())
8768 {
8769 wiphy_unregister(wiphy) ;
8770 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008771 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008772 if (hdd_is_ssr_required())
8773 {
8774 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008775 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008776 msleep(5000);
8777 }
8778 hdd_set_ssr_required (VOS_FALSE);
8779}
8780
8781
8782/**---------------------------------------------------------------------------
8783
8784 \brief hdd_update_config_from_nv() - Function to update the contents of
8785 the running configuration with parameters taken from NV storage
8786
8787 \param - pHddCtx - Pointer to the HDD global context
8788
8789 \return - VOS_STATUS_SUCCESS if successful
8790
8791 --------------------------------------------------------------------------*/
8792static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8793{
Jeff Johnson295189b2012-06-20 16:38:30 -07008794 v_BOOL_t itemIsValid = VOS_FALSE;
8795 VOS_STATUS status;
8796 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8797 v_U8_t macLoop;
8798
8799 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8800 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8801 if(status != VOS_STATUS_SUCCESS)
8802 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008803 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008804 return VOS_STATUS_E_FAILURE;
8805 }
8806
8807 if (itemIsValid == VOS_TRUE)
8808 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008809 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008810 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8811 VOS_MAX_CONCURRENCY_PERSONA);
8812 if(status != VOS_STATUS_SUCCESS)
8813 {
8814 /* Get MAC from NV fail, not update CFG info
8815 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008816 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008817 return VOS_STATUS_E_FAILURE;
8818 }
8819
8820 /* If first MAC is not valid, treat all others are not valid
8821 * Then all MACs will be got from ini file */
8822 if(vos_is_macaddr_zero(&macFromNV[0]))
8823 {
8824 /* MAC address in NV file is not configured yet */
8825 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8826 return VOS_STATUS_E_INVAL;
8827 }
8828
8829 /* Get MAC address from NV, update CFG info */
8830 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8831 {
8832 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8833 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308834 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008835 /* This MAC is not valid, skip it
8836 * This MAC will be got from ini file */
8837 }
8838 else
8839 {
8840 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8841 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8842 VOS_MAC_ADDR_SIZE);
8843 }
8844 }
8845 }
8846 else
8847 {
8848 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8849 return VOS_STATUS_E_FAILURE;
8850 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008851
Jeff Johnson295189b2012-06-20 16:38:30 -07008852
8853 return VOS_STATUS_SUCCESS;
8854}
8855
8856/**---------------------------------------------------------------------------
8857
8858 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8859
8860 \param - pAdapter - Pointer to the HDD
8861
8862 \return - None
8863
8864 --------------------------------------------------------------------------*/
8865VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8866{
8867 eHalStatus halStatus;
8868 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308869 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008870
Jeff Johnson295189b2012-06-20 16:38:30 -07008871
8872 // Send ready indication to the HDD. This will kick off the MAC
8873 // into a 'running' state and should kick off an initial scan.
8874 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8875 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8876 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308877 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008878 "code %08d [x%08x]",__func__, halStatus, halStatus );
8879 return VOS_STATUS_E_FAILURE;
8880 }
8881
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308882 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008883 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8884 // And RIVA will crash
8885 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8886 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308887 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8888 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8889
8890
Jeff Johnson295189b2012-06-20 16:38:30 -07008891 return VOS_STATUS_SUCCESS;
8892}
8893
Jeff Johnson295189b2012-06-20 16:38:30 -07008894/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308895void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008896{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308897
8898 vos_wake_lock_acquire(&wlan_wake_lock, reason);
8899
Jeff Johnson295189b2012-06-20 16:38:30 -07008900}
8901
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308902void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008903{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308904
8905 vos_wake_lock_release(&wlan_wake_lock, reason);
8906
Jeff Johnson295189b2012-06-20 16:38:30 -07008907}
8908
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308909void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008910{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308911
8912 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
8913 reason);
8914
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008915}
8916
Jeff Johnson295189b2012-06-20 16:38:30 -07008917/**---------------------------------------------------------------------------
8918
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008919 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8920 information between Host and Riva
8921
8922 This function gets reported version of FW
8923 It also finds the version of Riva headers used to compile the host
8924 It compares the above two and prints a warning if they are different
8925 It gets the SW and HW version string
8926 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8927 indicating the features they support through a bitmap
8928
8929 \param - pHddCtx - Pointer to HDD context
8930
8931 \return - void
8932
8933 --------------------------------------------------------------------------*/
8934
8935void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8936{
8937
8938 tSirVersionType versionCompiled;
8939 tSirVersionType versionReported;
8940 tSirVersionString versionString;
8941 tANI_U8 fwFeatCapsMsgSupported = 0;
8942 VOS_STATUS vstatus;
8943
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008944 memset(&versionCompiled, 0, sizeof(versionCompiled));
8945 memset(&versionReported, 0, sizeof(versionReported));
8946
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008947 /* retrieve and display WCNSS version information */
8948 do {
8949
8950 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8951 &versionCompiled);
8952 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8953 {
8954 hddLog(VOS_TRACE_LEVEL_FATAL,
8955 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008956 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008957 break;
8958 }
8959
8960 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8961 &versionReported);
8962 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8963 {
8964 hddLog(VOS_TRACE_LEVEL_FATAL,
8965 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008966 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008967 break;
8968 }
8969
8970 if ((versionCompiled.major != versionReported.major) ||
8971 (versionCompiled.minor != versionReported.minor) ||
8972 (versionCompiled.version != versionReported.version) ||
8973 (versionCompiled.revision != versionReported.revision))
8974 {
8975 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8976 "Host expected %u.%u.%u.%u\n",
8977 WLAN_MODULE_NAME,
8978 (int)versionReported.major,
8979 (int)versionReported.minor,
8980 (int)versionReported.version,
8981 (int)versionReported.revision,
8982 (int)versionCompiled.major,
8983 (int)versionCompiled.minor,
8984 (int)versionCompiled.version,
8985 (int)versionCompiled.revision);
8986 }
8987 else
8988 {
8989 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8990 WLAN_MODULE_NAME,
8991 (int)versionReported.major,
8992 (int)versionReported.minor,
8993 (int)versionReported.version,
8994 (int)versionReported.revision);
8995 }
8996
8997 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8998 versionString,
8999 sizeof(versionString));
9000 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9001 {
9002 hddLog(VOS_TRACE_LEVEL_FATAL,
9003 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009004 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009005 break;
9006 }
9007
9008 pr_info("%s: WCNSS software version %s\n",
9009 WLAN_MODULE_NAME, versionString);
9010
9011 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
9012 versionString,
9013 sizeof(versionString));
9014 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9015 {
9016 hddLog(VOS_TRACE_LEVEL_FATAL,
9017 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009018 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009019 break;
9020 }
9021
9022 pr_info("%s: WCNSS hardware version %s\n",
9023 WLAN_MODULE_NAME, versionString);
9024
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009025 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
9026 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009027 send the message only if it the riva is 1.1
9028 minor numbers for different riva branches:
9029 0 -> (1.0)Mainline Build
9030 1 -> (1.1)Mainline Build
9031 2->(1.04) Stability Build
9032 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009033 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009034 ((versionReported.minor>=1) && (versionReported.version>=1)))
9035 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
9036 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009037
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009038 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08009039 {
9040#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9041 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
9042 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
9043#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07009044 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
9045 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
9046 {
9047 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
9048 }
9049
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009050 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08009051 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009052
9053 } while (0);
9054
9055}
Neelansh Mittaledafed22014-09-04 18:54:39 +05309056void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
9057{
9058 struct sk_buff *skb;
9059 struct nlmsghdr *nlh;
9060 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309061 int flags = GFP_KERNEL;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309062
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309063 if (in_interrupt() || irqs_disabled() || in_atomic())
9064 flags = GFP_ATOMIC;
9065
9066 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +05309067
9068 if(skb == NULL) {
9069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9070 "%s: alloc_skb failed", __func__);
9071 return;
9072 }
9073
9074 nlh = (struct nlmsghdr *)skb->data;
9075 nlh->nlmsg_pid = 0; /* from kernel */
9076 nlh->nlmsg_flags = 0;
9077 nlh->nlmsg_seq = 0;
9078 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
9079
9080 ani_hdr = NLMSG_DATA(nlh);
9081 ani_hdr->type = type;
9082
9083 switch(type) {
9084 case WLAN_SVC_SAP_RESTART_IND:
9085 ani_hdr->length = 0;
9086 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
9087 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
9088 break;
9089 default:
9090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9091 "Attempt to send unknown nlink message %d", type);
9092 kfree_skb(skb);
9093 return;
9094 }
9095
9096 nl_srv_bcast(skb);
9097
9098 return;
9099}
9100
9101
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009102
9103/**---------------------------------------------------------------------------
9104
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309105 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
9106
9107 \param - pHddCtx - Pointer to the hdd context
9108
9109 \return - true if hardware supports 5GHz
9110
9111 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309112boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309113{
9114 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
9115 * then hardware support 5Ghz.
9116 */
9117 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
9118 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309119 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309120 return true;
9121 }
9122 else
9123 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309124 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309125 __func__);
9126 return false;
9127 }
9128}
9129
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309130/**---------------------------------------------------------------------------
9131
9132 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
9133 generate function
9134
9135 This is generate the random mac address for WLAN interface
9136
9137 \param - pHddCtx - Pointer to HDD context
9138 idx - Start interface index to get auto
9139 generated mac addr.
9140 mac_addr - Mac address
9141
9142 \return - 0 for success, < 0 for failure
9143
9144 --------------------------------------------------------------------------*/
9145
9146static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
9147 int idx, v_MACADDR_t mac_addr)
9148{
9149 int i;
9150 unsigned int serialno;
9151 serialno = wcnss_get_serial_number();
9152
9153 if (0 != serialno)
9154 {
9155 /* MAC address has 3 bytes of OUI so we have a maximum of 3
9156 bytes of the serial number that can be used to generate
9157 the other 3 bytes of the MAC address. Mask off all but
9158 the lower 3 bytes (this will also make sure we don't
9159 overflow in the next step) */
9160 serialno &= 0x00FFFFFF;
9161
9162 /* we need a unique address for each session */
9163 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
9164
9165 /* autogen other Mac addresses */
9166 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
9167 {
9168 /* start with the entire default address */
9169 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
9170 /* then replace the lower 3 bytes */
9171 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
9172 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
9173 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
9174
9175 serialno++;
9176 hddLog(VOS_TRACE_LEVEL_ERROR,
9177 "%s: Derived Mac Addr: "
9178 MAC_ADDRESS_STR, __func__,
9179 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
9180 }
9181
9182 }
9183 else
9184 {
9185 hddLog(LOGE, FL("Failed to Get Serial NO"));
9186 return -1;
9187 }
9188 return 0;
9189}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309190
Katya Nigame7b69a82015-04-28 15:24:06 +05309191int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
9192{
9193 VOS_STATUS status;
9194 v_CONTEXT_t pVosContext= NULL;
9195 hdd_adapter_t *pAdapter= NULL;
9196
9197 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9198
9199 if (NULL == pVosContext)
9200 {
9201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9202 "%s: Trying to open VOSS without a PreOpen", __func__);
9203 VOS_ASSERT(0);
9204 return VOS_STATUS_E_FAILURE;
9205 }
9206
9207 status = vos_nv_open();
9208 if (!VOS_IS_STATUS_SUCCESS(status))
9209 {
9210 /* NV module cannot be initialized */
9211 hddLog( VOS_TRACE_LEVEL_FATAL,
9212 "%s: vos_nv_open failed", __func__);
9213 return VOS_STATUS_E_FAILURE;
9214 }
9215
9216 status = vos_init_wiphy_from_nv_bin();
9217 if (!VOS_IS_STATUS_SUCCESS(status))
9218 {
9219 /* NV module cannot be initialized */
9220 hddLog( VOS_TRACE_LEVEL_FATAL,
9221 "%s: vos_init_wiphy failed", __func__);
9222 goto err_vos_nv_close;
9223 }
9224
9225 status = vos_open( &pVosContext, pHddCtx->parent_dev);
9226 if ( !VOS_IS_STATUS_SUCCESS( status ))
9227 {
9228 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
9229 goto err_vos_nv_close;
9230 }
9231
9232 status = vos_mon_start( pVosContext );
9233 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9234 {
9235 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
9236 goto err_vosclose;
9237 }
9238
9239 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9240 WDA_featureCapsExchange(pVosContext);
9241 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9242
9243 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
9244 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9245 if( pAdapter == NULL )
9246 {
9247 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9248 goto err_close_adapter;
9249 }
9250
9251 //Initialize the nlink service
9252 if(nl_srv_init() != 0)
9253 {
9254 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
9255 goto err_close_adapter;
9256 }
9257 return VOS_STATUS_SUCCESS;
9258
9259err_close_adapter:
9260 hdd_close_all_adapters( pHddCtx );
9261 vos_mon_stop( pVosContext );
9262err_vosclose:
9263 status = vos_sched_close( pVosContext );
9264 if (!VOS_IS_STATUS_SUCCESS(status)) {
9265 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9266 "%s: Failed to close VOSS Scheduler", __func__);
9267 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9268 }
9269 vos_close(pVosContext );
9270
9271err_vos_nv_close:
9272 vos_nv_close();
9273
9274return status;
9275}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309276/**---------------------------------------------------------------------------
9277
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309278 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
9279 completed to flush out the scan results
9280
9281 11d scan is done during driver load and is a passive scan on all
9282 channels supported by the device, 11d scans may find some APs on
9283 frequencies which are forbidden to be used in the regulatory domain
9284 the device is operating in. If these APs are notified to the supplicant
9285 it may try to connect to these APs, thus flush out all the scan results
9286 which are present in SME after 11d scan is done.
9287
9288 \return - eHalStatus
9289
9290 --------------------------------------------------------------------------*/
9291static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
9292 tANI_U32 scanId, eCsrScanStatus status)
9293{
9294 ENTER();
9295
9296 sme_ScanFlushResult(halHandle, 0);
9297
9298 EXIT();
9299
9300 return eHAL_STATUS_SUCCESS;
9301}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309302/**---------------------------------------------------------------------------
9303
9304 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
9305 logging is completed successfully.
9306
9307 \return - None
9308
9309 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309310void hdd_init_frame_logging_done(void *fwlogInitCbContext, VOS_STATUS status)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309311{
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309312 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309313
9314 if (NULL == pHddCtx)
9315 {
9316 hddLog(VOS_TRACE_LEVEL_ERROR,
9317 "%s: HDD context is NULL",__func__);
9318 return;
9319 }
9320
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +05309321 if ((VOS_STATUS_SUCCESS == status) &&
9322 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309323 {
9324 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
9325 pHddCtx->mgmt_frame_logging = TRUE;
9326 }
9327 else
9328 {
9329 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
9330 pHddCtx->mgmt_frame_logging = FALSE;
9331 }
9332
9333 return;
9334}
9335/**---------------------------------------------------------------------------
9336
9337 \brief hdd_init_frame_logging - function to initialize frame logging.
9338 Currently only Mgmt Frames are logged in both TX
9339 and Rx direction and are sent to userspace
9340 application using logger thread when queried.
9341
9342 \return - None
9343
9344 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309345void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309346{
9347 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309348 tpSirFWLoggingInitParam wlanFWLoggingInitParam;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309349
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309350 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
9351 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309352 {
9353 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
9354 return;
9355 }
9356
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309357 wlanFWLoggingInitParam = vos_mem_malloc(sizeof(tSirFWLoggingInitParam));
9358 if(NULL == wlanFWLoggingInitParam)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309359 {
9360 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed ", __func__);
9361 return;
9362 }
9363
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309364 vos_mem_set(wlanFWLoggingInitParam, sizeof(tSirFWLoggingInitParam), 0);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309365
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309366 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s Logging",__func__,
9367 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
9368 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
9369 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309370
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309371 if (pHddCtx->cfg_ini->enableFWLogging ||
9372 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309373 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309374 wlanFWLoggingInitParam->enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309375 }
9376
Sushant Kaushik46804902015-07-08 14:46:03 +05309377 if (pHddCtx->cfg_ini->enableMgmtLogging)
9378 {
9379 wlanFWLoggingInitParam->enableFlag |= WLAN_FRAME_LOG_EN;
9380 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309381 if (pHddCtx->cfg_ini->enableBMUHWtracing)
9382 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309383 wlanFWLoggingInitParam->enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309384 }
9385
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309386 wlanFWLoggingInitParam->frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
9387 wlanFWLoggingInitParam->frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
9388 wlanFWLoggingInitParam->bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
9389 wlanFWLoggingInitParam->continuousFrameLogging =
9390 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309391
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309392 wlanFWLoggingInitParam->enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309393
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309394 wlanFWLoggingInitParam->minLogBufferSize =
9395 pHddCtx->cfg_ini->minLoggingBufferSize;
9396 wlanFWLoggingInitParam->maxLogBufferSize =
9397 pHddCtx->cfg_ini->maxLoggingBufferSize;
9398 wlanFWLoggingInitParam->fwlogInitCallback = hdd_init_frame_logging_done;
9399 wlanFWLoggingInitParam->fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309400
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309401 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309402
9403 if (eHAL_STATUS_SUCCESS != halStatus)
9404 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309405 vos_mem_free(wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309406 }
9407
9408 return;
9409}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309410
9411/**---------------------------------------------------------------------------
9412
Jeff Johnson295189b2012-06-20 16:38:30 -07009413 \brief hdd_wlan_startup() - HDD init function
9414
9415 This is the driver startup code executed once a WLAN device has been detected
9416
9417 \param - dev - Pointer to the underlying device
9418
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009419 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07009420
9421 --------------------------------------------------------------------------*/
9422
9423int hdd_wlan_startup(struct device *dev )
9424{
9425 VOS_STATUS status;
9426 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009427 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009428 hdd_context_t *pHddCtx = NULL;
9429 v_CONTEXT_t pVosContext= NULL;
9430#ifdef WLAN_BTAMP_FEATURE
9431 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
9432 WLANBAP_ConfigType btAmpConfig;
9433 hdd_config_t *pConfig;
9434#endif
9435 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009436 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309437 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009438
9439 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009440 /*
9441 * cfg80211: wiphy allocation
9442 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309443 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009444
9445 if(wiphy == NULL)
9446 {
9447 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009448 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009449 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009450 pHddCtx = wiphy_priv(wiphy);
9451
Jeff Johnson295189b2012-06-20 16:38:30 -07009452 //Initialize the adapter context to zeros.
9453 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
9454
Jeff Johnson295189b2012-06-20 16:38:30 -07009455 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309456 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +05309457 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009458
9459 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9460
Siddharth Bhalcd92b782015-06-29 12:25:40 +05309461 /* register for riva power on lock to platform driver
9462 * Locking power early to ensure FW doesn't reset by kernel while
9463 * host driver is busy initializing itself */
9464 if (req_riva_power_on_lock("wlan"))
9465 {
9466 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9467 __func__);
9468 goto err_free_hdd_context;
9469 }
9470
Jeff Johnson295189b2012-06-20 16:38:30 -07009471 /*Get vos context here bcoz vos_open requires it*/
9472 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9473
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08009474 if(pVosContext == NULL)
9475 {
9476 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
9477 goto err_free_hdd_context;
9478 }
9479
Jeff Johnson295189b2012-06-20 16:38:30 -07009480 //Save the Global VOSS context in adapter context for future.
9481 pHddCtx->pvosContext = pVosContext;
9482
9483 //Save the adapter context in global context for future.
9484 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
9485
Jeff Johnson295189b2012-06-20 16:38:30 -07009486 pHddCtx->parent_dev = dev;
9487
9488 init_completion(&pHddCtx->full_pwr_comp_var);
9489 init_completion(&pHddCtx->standby_comp_var);
9490 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009491 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009492 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05309493 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309494 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07009495
mukul sharma4bd8d2e2015-08-13 20:33:25 +05309496 hdd_init_ll_stats_ctx(pHddCtx);
9497
Amar Singhala49cbc52013-10-08 18:37:44 -07009498#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07009499 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07009500#else
9501 init_completion(&pHddCtx->driver_crda_req);
9502#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009503
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309504 spin_lock_init(&pHddCtx->schedScan_lock);
9505
Jeff Johnson295189b2012-06-20 16:38:30 -07009506 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
9507
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309508#ifdef FEATURE_WLAN_TDLS
9509 /* tdls_lock is initialized before an hdd_open_adapter ( which is
9510 * invoked by other instances also) to protect the concurrent
9511 * access for the Adapters by TDLS module.
9512 */
9513 mutex_init(&pHddCtx->tdls_lock);
9514#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05309515 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05309516 mutex_init(&pHddCtx->wmmLock);
9517
Agarwal Ashish1f422872014-07-22 00:11:55 +05309518 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309519
Agarwal Ashish1f422872014-07-22 00:11:55 +05309520 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009521 // Load all config first as TL config is needed during vos_open
9522 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9523 if(pHddCtx->cfg_ini == NULL)
9524 {
9525 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9526 goto err_free_hdd_context;
9527 }
9528
9529 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9530
9531 // Read and parse the qcom_cfg.ini file
9532 status = hdd_parse_config_ini( pHddCtx );
9533 if ( VOS_STATUS_SUCCESS != status )
9534 {
9535 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9536 __func__, WLAN_INI_FILE);
9537 goto err_config;
9538 }
Arif Hussaind5218912013-12-05 01:10:55 -08009539#ifdef MEMORY_DEBUG
9540 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9541 vos_mem_init();
9542
9543 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9544 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9545#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009546
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309547 /* INI has been read, initialise the configuredMcastBcastFilter with
9548 * INI value as this will serve as the default value
9549 */
9550 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9551 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9552 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309553
9554 if (false == hdd_is_5g_supported(pHddCtx))
9555 {
9556 //5Ghz is not supported.
9557 if (1 != pHddCtx->cfg_ini->nBandCapability)
9558 {
9559 hddLog(VOS_TRACE_LEVEL_INFO,
9560 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9561 pHddCtx->cfg_ini->nBandCapability = 1;
9562 }
9563 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309564
9565 /* If SNR Monitoring is enabled, FW has to parse all beacons
9566 * for calcaluting and storing the average SNR, so set Nth beacon
9567 * filter to 1 to enable FW to parse all the beaocons
9568 */
9569 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9570 {
9571 /* The log level is deliberately set to WARN as overriding
9572 * nthBeaconFilter to 1 will increase power cosumption and this
9573 * might just prove helpful to detect the power issue.
9574 */
9575 hddLog(VOS_TRACE_LEVEL_WARN,
9576 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9577 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9578 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009579 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309580 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009581 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009582 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009583 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009584 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9585 {
9586 hddLog(VOS_TRACE_LEVEL_FATAL,
9587 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9588 goto err_config;
9589 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009590 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009591
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009592 // Update VOS trace levels based upon the cfg.ini
9593 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9594 pHddCtx->cfg_ini->vosTraceEnableBAP);
9595 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9596 pHddCtx->cfg_ini->vosTraceEnableTL);
9597 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9598 pHddCtx->cfg_ini->vosTraceEnableWDI);
9599 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9600 pHddCtx->cfg_ini->vosTraceEnableHDD);
9601 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9602 pHddCtx->cfg_ini->vosTraceEnableSME);
9603 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9604 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309605 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9606 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009607 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9608 pHddCtx->cfg_ini->vosTraceEnableWDA);
9609 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9610 pHddCtx->cfg_ini->vosTraceEnableSYS);
9611 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9612 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009613 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9614 pHddCtx->cfg_ini->vosTraceEnableSAP);
9615 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9616 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009617
Jeff Johnson295189b2012-06-20 16:38:30 -07009618 // Update WDI trace levels based upon the cfg.ini
9619 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9620 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9621 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9622 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9623 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9624 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9625 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9626 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009627
Jeff Johnson88ba7742013-02-27 14:36:02 -08009628 if (VOS_FTM_MODE == hdd_get_conparam())
9629 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009630 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9631 {
9632 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9633 goto err_free_hdd_context;
9634 }
9635 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +05309636 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +05309637 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009638 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009639 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009640
Katya Nigame7b69a82015-04-28 15:24:06 +05309641 if( VOS_MONITOR_MODE == hdd_get_conparam())
9642 {
9643 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
9644 {
9645 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
9646 goto err_free_hdd_context;
9647 }
9648 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
9649 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
9650 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9651 return VOS_STATUS_SUCCESS;
9652 }
9653
Jeff Johnson88ba7742013-02-27 14:36:02 -08009654 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009655 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9656 {
9657 status = vos_watchdog_open(pVosContext,
9658 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9659
9660 if(!VOS_IS_STATUS_SUCCESS( status ))
9661 {
9662 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309663 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009664 }
9665 }
9666
9667 pHddCtx->isLogpInProgress = FALSE;
9668 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9669
Amar Singhala49cbc52013-10-08 18:37:44 -07009670#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009671 /* initialize the NV module. This is required so that
9672 we can initialize the channel information in wiphy
9673 from the NV.bin data. The channel information in
9674 wiphy needs to be initialized before wiphy registration */
9675
9676 status = vos_nv_open();
9677 if (!VOS_IS_STATUS_SUCCESS(status))
9678 {
9679 /* NV module cannot be initialized */
9680 hddLog( VOS_TRACE_LEVEL_FATAL,
9681 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309682 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009683 }
9684
9685 status = vos_init_wiphy_from_nv_bin();
9686 if (!VOS_IS_STATUS_SUCCESS(status))
9687 {
9688 /* NV module cannot be initialized */
9689 hddLog( VOS_TRACE_LEVEL_FATAL,
9690 "%s: vos_init_wiphy failed", __func__);
9691 goto err_vos_nv_close;
9692 }
9693
Amar Singhala49cbc52013-10-08 18:37:44 -07009694#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309695 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309696 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009697 if ( !VOS_IS_STATUS_SUCCESS( status ))
9698 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009699 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309700 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009701 }
9702
Jeff Johnson295189b2012-06-20 16:38:30 -07009703 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9704
9705 if ( NULL == pHddCtx->hHal )
9706 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009707 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009708 goto err_vosclose;
9709 }
9710
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009711 status = vos_preStart( pHddCtx->pvosContext );
9712 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9713 {
9714 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309715 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009716 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009717
Arif Hussaineaf68602013-12-30 23:10:44 -08009718 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9719 {
9720 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9721 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9722 __func__, enable_dfs_chan_scan);
9723 }
9724 if (0 == enable_11d || 1 == enable_11d)
9725 {
9726 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9727 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9728 __func__, enable_11d);
9729 }
9730
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009731 /* Note that the vos_preStart() sequence triggers the cfg download.
9732 The cfg download must occur before we update the SME config
9733 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009734 status = hdd_set_sme_config( pHddCtx );
9735
9736 if ( VOS_STATUS_SUCCESS != status )
9737 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009738 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309739 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009740 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009741
Jeff Johnson295189b2012-06-20 16:38:30 -07009742 /* In the integrated architecture we update the configuration from
9743 the INI file and from NV before vOSS has been started so that
9744 the final contents are available to send down to the cCPU */
9745
9746 // Apply the cfg.ini to cfg.dat
9747 if (FALSE == hdd_update_config_dat(pHddCtx))
9748 {
9749 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309750 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009751 }
9752
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309753 // Get mac addr from platform driver
9754 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9755
9756 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009757 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309758 /* Store the mac addr for first interface */
9759 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9760
9761 hddLog(VOS_TRACE_LEVEL_ERROR,
9762 "%s: WLAN Mac Addr: "
9763 MAC_ADDRESS_STR, __func__,
9764 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9765
9766 /* Here, passing Arg2 as 1 because we do not want to change the
9767 last 3 bytes (means non OUI bytes) of first interface mac
9768 addr.
9769 */
9770 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9771 {
9772 hddLog(VOS_TRACE_LEVEL_ERROR,
9773 "%s: Failed to generate wlan interface mac addr "
9774 "using MAC from ini file ", __func__);
9775 }
9776 }
9777 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9778 {
9779 // Apply the NV to cfg.dat
9780 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009781#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9782 /* There was not a valid set of MAC Addresses in NV. See if the
9783 default addresses were modified by the cfg.ini settings. If so,
9784 we'll use them, but if not, we'll autogenerate a set of MAC
9785 addresses based upon the device serial number */
9786
9787 static const v_MACADDR_t default_address =
9788 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009789
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309790 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9791 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009792 {
9793 /* cfg.ini has the default address, invoke autogen logic */
9794
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309795 /* Here, passing Arg2 as 0 because we want to change the
9796 last 3 bytes (means non OUI bytes) of all the interfaces
9797 mac addr.
9798 */
9799 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9800 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009801 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309802 hddLog(VOS_TRACE_LEVEL_ERROR,
9803 "%s: Failed to generate wlan interface mac addr "
9804 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9805 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009806 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009807 }
9808 else
9809#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9810 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009811 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009812 "%s: Invalid MAC address in NV, using MAC from ini file "
9813 MAC_ADDRESS_STR, __func__,
9814 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9815 }
9816 }
9817 {
9818 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309819
9820 /* Set the MAC Address Currently this is used by HAL to
9821 * add self sta. Remove this once self sta is added as
9822 * part of session open.
9823 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009824 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9825 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9826 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309827
Jeff Johnson295189b2012-06-20 16:38:30 -07009828 if (!HAL_STATUS_SUCCESS( halStatus ))
9829 {
9830 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9831 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309832 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009833 }
9834 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009835
9836 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9837 Note: Firmware image will be read and downloaded inside vos_start API */
9838 status = vos_start( pHddCtx->pvosContext );
9839 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9840 {
9841 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309842 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009843 }
9844
Leo Chang6cec3e22014-01-21 15:33:49 -08009845#ifdef FEATURE_WLAN_CH_AVOID
9846 /* Plug in avoid channel notification callback
9847 * This should happen before ADD_SELF_STA
9848 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309849
9850 /* check the Channel Avoidance is enabled */
9851 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9852 {
9853 sme_AddChAvoidCallback(pHddCtx->hHal,
9854 hdd_hostapd_ch_avoid_cb);
9855 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009856#endif /* FEATURE_WLAN_CH_AVOID */
9857
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009858 /* Exchange capability info between Host and FW and also get versioning info from FW */
9859 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009860
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309861#ifdef CONFIG_ENABLE_LINUX_REG
9862 status = wlan_hdd_init_channels(pHddCtx);
9863 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9864 {
9865 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9866 __func__);
9867 goto err_vosstop;
9868 }
9869#endif
9870
Jeff Johnson295189b2012-06-20 16:38:30 -07009871 status = hdd_post_voss_start_config( pHddCtx );
9872 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9873 {
9874 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9875 __func__);
9876 goto err_vosstop;
9877 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009878
9879#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309880 wlan_hdd_cfg80211_update_reg_info( wiphy );
9881
9882 /* registration of wiphy dev with cfg80211 */
9883 if (0 > wlan_hdd_cfg80211_register(wiphy))
9884 {
9885 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9886 goto err_vosstop;
9887 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009888#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009889
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309890#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309891 /* registration of wiphy dev with cfg80211 */
9892 if (0 > wlan_hdd_cfg80211_register(wiphy))
9893 {
9894 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9895 goto err_vosstop;
9896 }
9897
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309898 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309899 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9900 {
9901 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9902 __func__);
9903 goto err_unregister_wiphy;
9904 }
9905#endif
9906
c_hpothu4a298be2014-12-22 21:12:51 +05309907 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9908
Jeff Johnson295189b2012-06-20 16:38:30 -07009909 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9910 {
9911 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9912 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9913 }
9914 else
9915 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009916 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9917 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9918 if (pAdapter != NULL)
9919 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309920 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009921 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309922 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9923 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9924 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009925
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309926 /* Generate the P2P Device Address. This consists of the device's
9927 * primary MAC address with the locally administered bit set.
9928 */
9929 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009930 }
9931 else
9932 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309933 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9934 if (p2p_dev_addr != NULL)
9935 {
9936 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9937 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9938 }
9939 else
9940 {
9941 hddLog(VOS_TRACE_LEVEL_FATAL,
9942 "%s: Failed to allocate mac_address for p2p_device",
9943 __func__);
9944 goto err_close_adapter;
9945 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009946 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009947
9948 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9949 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9950 if ( NULL == pP2pAdapter )
9951 {
9952 hddLog(VOS_TRACE_LEVEL_FATAL,
9953 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009954 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009955 goto err_close_adapter;
9956 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009957 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009958 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009959
9960 if( pAdapter == NULL )
9961 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009962 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9963 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009964 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009965
Arif Hussain66559122013-11-21 10:11:40 -08009966 if (country_code)
9967 {
9968 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009969 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009970 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9971#ifndef CONFIG_ENABLE_LINUX_REG
9972 hdd_checkandupdate_phymode(pAdapter, country_code);
9973#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009974 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9975 (void *)(tSmeChangeCountryCallback)
9976 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009977 country_code,
9978 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309979 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009980 if (eHAL_STATUS_SUCCESS == ret)
9981 {
Arif Hussaincb607082013-12-20 11:57:42 -08009982 ret = wait_for_completion_interruptible_timeout(
9983 &pAdapter->change_country_code,
9984 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9985
9986 if (0 >= ret)
9987 {
9988 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9989 "%s: SME while setting country code timed out", __func__);
9990 }
Arif Hussain66559122013-11-21 10:11:40 -08009991 }
9992 else
9993 {
Arif Hussaincb607082013-12-20 11:57:42 -08009994 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9995 "%s: SME Change Country code from module param fail ret=%d",
9996 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009997 }
9998 }
9999
Jeff Johnson295189b2012-06-20 16:38:30 -070010000#ifdef WLAN_BTAMP_FEATURE
10001 vStatus = WLANBAP_Open(pVosContext);
10002 if(!VOS_IS_STATUS_SUCCESS(vStatus))
10003 {
10004 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10005 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070010006 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010007 }
10008
10009 vStatus = BSL_Init(pVosContext);
10010 if(!VOS_IS_STATUS_SUCCESS(vStatus))
10011 {
10012 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10013 "%s: Failed to Init BSL",__func__);
10014 goto err_bap_close;
10015 }
10016 vStatus = WLANBAP_Start(pVosContext);
10017 if (!VOS_IS_STATUS_SUCCESS(vStatus))
10018 {
10019 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10020 "%s: Failed to start TL",__func__);
10021 goto err_bap_close;
10022 }
10023
10024 pConfig = pHddCtx->cfg_ini;
10025 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
10026 status = WLANBAP_SetConfig(&btAmpConfig);
10027
10028#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070010029
Mihir Shete9c238772014-10-15 14:35:16 +053010030 /*
10031 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
10032 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
10033 * which is greater than 0xf. So the below check is safe to make
10034 * sure that there is no entry for UapsdMask in the ini
10035 */
10036 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
10037 {
10038 if(IS_DYNAMIC_WMM_PS_ENABLED)
10039 {
10040 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
10041 __func__);
10042 pHddCtx->cfg_ini->UapsdMask =
10043 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
10044 }
10045 else
10046 {
10047 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
10048 __func__);
10049 pHddCtx->cfg_ini->UapsdMask =
10050 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
10051 }
10052 }
10053
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070010054#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
10055 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
10056 {
10057 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
10058 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
10059 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
10060 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
10061 }
10062#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010063
Agarwal Ashish4b87f922014-06-18 03:03:21 +053010064 wlan_hdd_tdls_init(pHddCtx);
10065
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053010066 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
10067
Jeff Johnson295189b2012-06-20 16:38:30 -070010068 /* Register with platform driver as client for Suspend/Resume */
10069 status = hddRegisterPmOps(pHddCtx);
10070 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10071 {
10072 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
10073#ifdef WLAN_BTAMP_FEATURE
10074 goto err_bap_stop;
10075#else
Jeff Johnsone7245742012-09-05 17:12:55 -070010076 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010077#endif //WLAN_BTAMP_FEATURE
10078 }
10079
Yue Ma0d4891e2013-08-06 17:01:45 -070010080 /* Open debugfs interface */
10081 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
10082 {
10083 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10084 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070010085 }
10086
Jeff Johnson295189b2012-06-20 16:38:30 -070010087 /* Register TM level change handler function to the platform */
10088 status = hddDevTmRegisterNotifyCallback(pHddCtx);
10089 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10090 {
10091 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
10092 goto err_unregister_pmops;
10093 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010094
Jeff Johnson295189b2012-06-20 16:38:30 -070010095 // register net device notifier for device change notification
10096 ret = register_netdevice_notifier(&hdd_netdev_notifier);
10097
10098 if(ret < 0)
10099 {
10100 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010101 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070010102 }
10103
10104 //Initialize the nlink service
10105 if(nl_srv_init() != 0)
10106 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010107 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010108 goto err_reg_netdev;
10109 }
10110
Leo Chang4ce1cc52013-10-21 18:27:15 -070010111#ifdef WLAN_KD_READY_NOTIFIER
10112 pHddCtx->kd_nl_init = 1;
10113#endif /* WLAN_KD_READY_NOTIFIER */
10114
Jeff Johnson295189b2012-06-20 16:38:30 -070010115 //Initialize the BTC service
10116 if(btc_activate_service(pHddCtx) != 0)
10117 {
10118 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
10119 goto err_nl_srv;
10120 }
10121
10122#ifdef PTT_SOCK_SVC_ENABLE
10123 //Initialize the PTT service
10124 if(ptt_sock_activate_svc(pHddCtx) != 0)
10125 {
10126 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
10127 goto err_nl_srv;
10128 }
10129#endif
10130
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010131#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10132 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
10133 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053010134 if(wlan_logging_sock_activate_svc(
10135 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
10136 pHddCtx->cfg_ini->wlanLoggingNumBuf))
10137 {
10138 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
10139 " failed", __func__);
10140 goto err_nl_srv;
10141 }
10142 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
10143 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053010144 if (!pHddCtx->cfg_ini->gEnableDebugLog)
10145 pHddCtx->cfg_ini->gEnableDebugLog =
10146 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010147 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010148
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010149 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
10150 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053010151 pHddCtx->cfg_ini->enableMgmtLogging ||
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010152 pHddCtx->cfg_ini->enableContFWLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010153 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010154 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010155 }
10156 else
10157 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010158 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010159 }
10160
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010161#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010162
10163
Sushant Kaushik215778f2015-05-21 14:05:36 +053010164 if (vos_is_multicast_logging())
10165 wlan_logging_set_log_level();
10166
Jeff Johnson295189b2012-06-20 16:38:30 -070010167 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010168 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070010169 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070010170 /* Action frame registered in one adapter which will
10171 * applicable to all interfaces
10172 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053010173 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010174 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010175
10176 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053010177 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010178
Jeff Johnsone7245742012-09-05 17:12:55 -070010179#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10180 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010181 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070010182 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010183
Jeff Johnsone7245742012-09-05 17:12:55 -070010184#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010185 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010186 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010187 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010188
Jeff Johnsone7245742012-09-05 17:12:55 -070010189
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010190 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
10191 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010192
Katya Nigam5c306ea2014-06-19 15:39:54 +053010193 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010194 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010195 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053010196
10197#ifdef FEATURE_WLAN_SCAN_PNO
10198 /*SME must send channel update configuration to RIVA*/
10199 sme_UpdateChannelConfig(pHddCtx->hHal);
10200#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053010201 /* Send the update default channel list to the FW*/
10202 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053010203
10204 /* Fwr capabilities received, Set the Dot11 mode */
10205 sme_SetDefDot11Mode(pHddCtx->hHal);
10206
Abhishek Singha306a442013-11-07 18:39:01 +053010207#ifndef CONFIG_ENABLE_LINUX_REG
10208 /*updating wiphy so that regulatory user hints can be processed*/
10209 if (wiphy)
10210 {
10211 regulatory_hint(wiphy, "00");
10212 }
10213#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010214 // Initialize the restart logic
10215 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053010216
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010217 //Register the traffic monitor timer now
10218 if ( pHddCtx->cfg_ini->dynSplitscan)
10219 {
10220 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
10221 VOS_TIMER_TYPE_SW,
10222 hdd_tx_rx_pkt_cnt_stat_timer_handler,
10223 (void *)pHddCtx);
10224 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053010225 wlan_hdd_cfg80211_nan_init(pHddCtx);
10226
Dino Mycle6fb96c12014-06-10 11:52:40 +053010227#ifdef WLAN_FEATURE_EXTSCAN
10228 sme_EXTScanRegisterCallback(pHddCtx->hHal,
10229 wlan_hdd_cfg80211_extscan_callback,
10230 pHddCtx);
10231#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010232
10233#ifdef WLAN_NS_OFFLOAD
10234 // Register IPv6 notifier to notify if any change in IP
10235 // So that we can reconfigure the offload parameters
10236 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
10237 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10238 if (ret)
10239 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010240 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010241 }
10242 else
10243 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010244 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010245 }
10246#endif
10247
10248 // Register IPv4 notifier to notify if any change in IP
10249 // So that we can reconfigure the offload parameters
10250 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
10251 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10252 if (ret)
10253 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010254 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010255 }
10256 else
10257 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010258 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010259 }
10260
Jeff Johnson295189b2012-06-20 16:38:30 -070010261 goto success;
10262
10263err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -070010264#ifdef WLAN_KD_READY_NOTIFIER
10265 nl_srv_exit(pHddCtx->ptt_pid);
10266#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010267 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -070010268#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -070010269err_reg_netdev:
10270 unregister_netdevice_notifier(&hdd_netdev_notifier);
10271
Jeff Johnson295189b2012-06-20 16:38:30 -070010272err_unregister_pmops:
10273 hddDevTmUnregisterNotifyCallback(pHddCtx);
10274 hddDeregisterPmOps(pHddCtx);
10275
Yue Ma0d4891e2013-08-06 17:01:45 -070010276 hdd_debugfs_exit(pHddCtx);
10277
Jeff Johnson295189b2012-06-20 16:38:30 -070010278#ifdef WLAN_BTAMP_FEATURE
10279err_bap_stop:
10280 WLANBAP_Stop(pVosContext);
10281#endif
10282
10283#ifdef WLAN_BTAMP_FEATURE
10284err_bap_close:
10285 WLANBAP_Close(pVosContext);
10286#endif
10287
Jeff Johnson295189b2012-06-20 16:38:30 -070010288err_close_adapter:
10289 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010290#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010291err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010292#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010293 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010294err_vosstop:
10295 vos_stop(pVosContext);
10296
Amar Singhala49cbc52013-10-08 18:37:44 -070010297err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070010298 status = vos_sched_close( pVosContext );
10299 if (!VOS_IS_STATUS_SUCCESS(status)) {
10300 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10301 "%s: Failed to close VOSS Scheduler", __func__);
10302 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
10303 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010304 vos_close(pVosContext );
10305
Amar Singhal0a402232013-10-11 20:57:16 -070010306err_vos_nv_close:
10307
c_hpothue6a36282014-03-19 12:27:38 +053010308#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070010309 vos_nv_close();
10310
c_hpothu70f8d812014-03-22 22:59:23 +053010311#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010312
10313err_wdclose:
10314 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10315 vos_watchdog_close(pVosContext);
10316
Jeff Johnson295189b2012-06-20 16:38:30 -070010317err_config:
10318 kfree(pHddCtx->cfg_ini);
10319 pHddCtx->cfg_ini= NULL;
10320
10321err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010322 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010323 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010324 wiphy_free(wiphy) ;
10325 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010326 VOS_BUG(1);
10327
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080010328 if (hdd_is_ssr_required())
10329 {
10330 /* WDI timeout had happened during load, so SSR is needed here */
10331 subsystem_restart("wcnss");
10332 msleep(5000);
10333 }
10334 hdd_set_ssr_required (VOS_FALSE);
10335
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010336 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010337
10338success:
10339 EXIT();
10340 return 0;
10341}
10342
10343/**---------------------------------------------------------------------------
10344
Jeff Johnson32d95a32012-09-10 13:15:23 -070010345 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070010346
Jeff Johnson32d95a32012-09-10 13:15:23 -070010347 This is the driver entry point - called in different timeline depending
10348 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070010349
10350 \param - None
10351
10352 \return - 0 for success, non zero for failure
10353
10354 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070010355static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010356{
10357 VOS_STATUS status;
10358 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010359 struct device *dev = NULL;
10360 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010361#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10362 int max_retries = 0;
10363#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010364#ifdef HAVE_CBC_DONE
10365 int max_cbc_retries = 0;
10366#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010367
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010368#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10369 wlan_logging_sock_init_svc();
10370#endif
10371
Jeff Johnson295189b2012-06-20 16:38:30 -070010372 ENTER();
10373
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010374 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010375
10376 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
10377 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
10378
Jeff Johnson295189b2012-06-20 16:38:30 -070010379#ifdef ANI_BUS_TYPE_PCI
10380
10381 dev = wcnss_wlan_get_device();
10382
10383#endif // ANI_BUS_TYPE_PCI
10384
10385#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010386
10387#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10388 /* wait until WCNSS driver downloads NV */
10389 while (!wcnss_device_ready() && 5 >= ++max_retries) {
10390 msleep(1000);
10391 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010392
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010393 if (max_retries >= 5) {
10394 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010395 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010396#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10397 wlan_logging_sock_deinit_svc();
10398#endif
10399
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010400 return -ENODEV;
10401 }
10402#endif
10403
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010404#ifdef HAVE_CBC_DONE
10405 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
10406 msleep(1000);
10407 }
10408 if (max_cbc_retries >= 10) {
10409 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
10410 }
10411#endif
10412
Jeff Johnson295189b2012-06-20 16:38:30 -070010413 dev = wcnss_wlan_get_device();
10414#endif // ANI_BUS_TYPE_PLATFORM
10415
10416
10417 do {
10418 if (NULL == dev) {
10419 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
10420 ret_status = -1;
10421 break;
10422 }
10423
Jeff Johnson295189b2012-06-20 16:38:30 -070010424#ifdef TIMER_MANAGER
10425 vos_timer_manager_init();
10426#endif
10427
10428 /* Preopen VOSS so that it is ready to start at least SAL */
10429 status = vos_preOpen(&pVosContext);
10430
10431 if (!VOS_IS_STATUS_SUCCESS(status))
10432 {
10433 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
10434 ret_status = -1;
10435 break;
10436 }
10437
Sushant Kaushik02beb352015-06-04 15:15:01 +053010438 hddTraceInit();
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010439#ifndef MODULE
10440 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
10441 */
10442 hdd_set_conparam((v_UINT_t)con_mode);
10443#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010444
10445 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010446 if (hdd_wlan_startup(dev))
10447 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010448 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010449 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010450 vos_preClose( &pVosContext );
10451 ret_status = -1;
10452 break;
10453 }
10454
Jeff Johnson295189b2012-06-20 16:38:30 -070010455 } while (0);
10456
10457 if (0 != ret_status)
10458 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010459#ifdef TIMER_MANAGER
10460 vos_timer_exit();
10461#endif
10462#ifdef MEMORY_DEBUG
10463 vos_mem_exit();
10464#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010465 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010466#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10467 wlan_logging_sock_deinit_svc();
10468#endif
10469
Jeff Johnson295189b2012-06-20 16:38:30 -070010470 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
10471 }
10472 else
10473 {
10474 //Send WLAN UP indication to Nlink Service
10475 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
10476
10477 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070010478 }
10479
10480 EXIT();
10481
10482 return ret_status;
10483}
10484
Jeff Johnson32d95a32012-09-10 13:15:23 -070010485/**---------------------------------------------------------------------------
10486
10487 \brief hdd_module_init() - Init Function
10488
10489 This is the driver entry point (invoked when module is loaded using insmod)
10490
10491 \param - None
10492
10493 \return - 0 for success, non zero for failure
10494
10495 --------------------------------------------------------------------------*/
10496#ifdef MODULE
10497static int __init hdd_module_init ( void)
10498{
10499 return hdd_driver_init();
10500}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010501#else /* #ifdef MODULE */
10502static int __init hdd_module_init ( void)
10503{
10504 /* Driver initialization is delayed to fwpath_changed_handler */
10505 return 0;
10506}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010507#endif /* #ifdef MODULE */
10508
Jeff Johnson295189b2012-06-20 16:38:30 -070010509
10510/**---------------------------------------------------------------------------
10511
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010512 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070010513
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010514 This is the driver exit point (invoked when module is unloaded using rmmod
10515 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070010516
10517 \param - None
10518
10519 \return - None
10520
10521 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010522static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010523{
10524 hdd_context_t *pHddCtx = NULL;
10525 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053010526 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053010527 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010528
10529 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
10530
10531 //Get the global vos context
10532 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10533
10534 if(!pVosContext)
10535 {
10536 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10537 goto done;
10538 }
10539
10540 //Get the HDD context.
10541 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10542
10543 if(!pHddCtx)
10544 {
10545 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10546 }
Katya Nigame7b69a82015-04-28 15:24:06 +053010547 else if (VOS_MONITOR_MODE == hdd_get_conparam())
10548 {
10549 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
10550 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10551 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
10552 hdd_wlan_exit(pHddCtx);
10553 vos_preClose( &pVosContext );
10554 goto done;
10555 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010556 else
10557 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053010558 /* We wait for active entry threads to exit from driver
10559 * by waiting until rtnl_lock is available.
10560 */
10561 rtnl_lock();
10562 rtnl_unlock();
10563
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010564 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10565 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10566 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10567 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010569 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010570 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10571 msecs_to_jiffies(30000));
10572 if(!rc)
10573 {
10574 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10575 "%s:SSR timedout, fatal error", __func__);
10576 VOS_BUG(0);
10577 }
10578 }
10579
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010580 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10581 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010582
c_hpothu8adb97b2014-12-08 19:38:20 +053010583 /* Driver Need to send country code 00 in below condition
10584 * 1) If gCountryCodePriority is set to 1; and last country
10585 * code set is through 11d. This needs to be done in case
10586 * when NV country code is 00.
10587 * This Needs to be done as when kernel store last country
10588 * code and if stored country code is not through 11d,
10589 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10590 * in next load/unload as soon as we get any country through
10591 * 11d. In sme_HandleChangeCountryCodeByUser
10592 * pMsg->countryCode will be last countryCode and
10593 * pMac->scan.countryCode11d will be country through 11d so
10594 * due to mismatch driver will disable 11d.
10595 *
10596 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010597
c_hpothu8adb97b2014-12-08 19:38:20 +053010598 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010599 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010600 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010601 {
10602 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010603 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010604 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10605 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010606
c_hpothu8adb97b2014-12-08 19:38:20 +053010607 //Do all the cleanup before deregistering the driver
10608 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010609 }
10610
Jeff Johnson295189b2012-06-20 16:38:30 -070010611 vos_preClose( &pVosContext );
10612
10613#ifdef TIMER_MANAGER
10614 vos_timer_exit();
10615#endif
10616#ifdef MEMORY_DEBUG
10617 vos_mem_exit();
10618#endif
10619
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010620#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10621 wlan_logging_sock_deinit_svc();
10622#endif
10623
Jeff Johnson295189b2012-06-20 16:38:30 -070010624done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010625 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010626
Jeff Johnson295189b2012-06-20 16:38:30 -070010627 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10628}
10629
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010630/**---------------------------------------------------------------------------
10631
10632 \brief hdd_module_exit() - Exit function
10633
10634 This is the driver exit point (invoked when module is unloaded using rmmod)
10635
10636 \param - None
10637
10638 \return - None
10639
10640 --------------------------------------------------------------------------*/
10641static void __exit hdd_module_exit(void)
10642{
10643 hdd_driver_exit();
10644}
10645
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010646#ifdef MODULE
10647static int fwpath_changed_handler(const char *kmessage,
10648 struct kernel_param *kp)
10649{
Jeff Johnson76052702013-04-16 13:55:05 -070010650 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010651}
10652
10653static int con_mode_handler(const char *kmessage,
10654 struct kernel_param *kp)
10655{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010656 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010657}
10658#else /* #ifdef MODULE */
10659/**---------------------------------------------------------------------------
10660
Jeff Johnson76052702013-04-16 13:55:05 -070010661 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010662
Jeff Johnson76052702013-04-16 13:55:05 -070010663 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010664 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010665 - invoked when module parameter fwpath is modified from userspace to signal
10666 initializing the WLAN driver or when con_mode is modified from userspace
10667 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010668
10669 \return - 0 for success, non zero for failure
10670
10671 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010672static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010673{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010674 int ret_status;
10675
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010676 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010677 ret_status = hdd_driver_init();
10678 wlan_hdd_inited = ret_status ? 0 : 1;
10679 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010680 }
10681
10682 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010683
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010684 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010685
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010686 ret_status = hdd_driver_init();
10687 wlan_hdd_inited = ret_status ? 0 : 1;
10688 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010689}
10690
Jeff Johnson295189b2012-06-20 16:38:30 -070010691/**---------------------------------------------------------------------------
10692
Jeff Johnson76052702013-04-16 13:55:05 -070010693 \brief fwpath_changed_handler() - Handler Function
10694
10695 Handle changes to the fwpath parameter
10696
10697 \return - 0 for success, non zero for failure
10698
10699 --------------------------------------------------------------------------*/
10700static int fwpath_changed_handler(const char *kmessage,
10701 struct kernel_param *kp)
10702{
10703 int ret;
10704
10705 ret = param_set_copystring(kmessage, kp);
10706 if (0 == ret)
10707 ret = kickstart_driver();
10708 return ret;
10709}
10710
10711/**---------------------------------------------------------------------------
10712
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010713 \brief con_mode_handler() -
10714
10715 Handler function for module param con_mode when it is changed by userspace
10716 Dynamically linked - do nothing
10717 Statically linked - exit and init driver, as in rmmod and insmod
10718
Jeff Johnson76052702013-04-16 13:55:05 -070010719 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010720
Jeff Johnson76052702013-04-16 13:55:05 -070010721 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010722
10723 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010724static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010725{
Jeff Johnson76052702013-04-16 13:55:05 -070010726 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010727
Jeff Johnson76052702013-04-16 13:55:05 -070010728 ret = param_set_int(kmessage, kp);
10729 if (0 == ret)
10730 ret = kickstart_driver();
10731 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010732}
10733#endif /* #ifdef MODULE */
10734
10735/**---------------------------------------------------------------------------
10736
Jeff Johnson295189b2012-06-20 16:38:30 -070010737 \brief hdd_get_conparam() -
10738
10739 This is the driver exit point (invoked when module is unloaded using rmmod)
10740
10741 \param - None
10742
10743 \return - tVOS_CON_MODE
10744
10745 --------------------------------------------------------------------------*/
10746tVOS_CON_MODE hdd_get_conparam ( void )
10747{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010748#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010749 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010750#else
10751 return (tVOS_CON_MODE)curr_con_mode;
10752#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010753}
10754void hdd_set_conparam ( v_UINT_t newParam )
10755{
10756 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010757#ifndef MODULE
10758 curr_con_mode = con_mode;
10759#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010760}
10761/**---------------------------------------------------------------------------
10762
10763 \brief hdd_softap_sta_deauth() - function
10764
10765 This to take counter measure to handle deauth req from HDD
10766
10767 \param - pAdapter - Pointer to the HDD
10768
10769 \param - enable - boolean value
10770
10771 \return - None
10772
10773 --------------------------------------------------------------------------*/
10774
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010775VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10776 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010777{
Jeff Johnson295189b2012-06-20 16:38:30 -070010778 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010779 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010780
10781 ENTER();
10782
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010783 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10784 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010785
10786 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010787 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010788 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010789
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010790 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010791
10792 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010793 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010794}
10795
10796/**---------------------------------------------------------------------------
10797
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010798 \brief hdd_del_all_sta() - function
10799
10800 This function removes all the stations associated on stopping AP/P2P GO.
10801
10802 \param - pAdapter - Pointer to the HDD
10803
10804 \return - None
10805
10806 --------------------------------------------------------------------------*/
10807
10808int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10809{
10810 v_U16_t i;
10811 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010812 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10813 ptSapContext pSapCtx = NULL;
10814 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10815 if(pSapCtx == NULL){
10816 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10817 FL("psapCtx is NULL"));
10818 return 1;
10819 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010820 ENTER();
10821
10822 hddLog(VOS_TRACE_LEVEL_INFO,
10823 "%s: Delete all STAs associated.",__func__);
10824 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10825 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10826 )
10827 {
10828 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10829 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010830 if ((pSapCtx->aStaInfo[i].isUsed) &&
10831 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010832 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010833 struct tagCsrDelStaParams delStaParams;
10834
10835 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010836 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010837 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10838 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010839 &delStaParams);
10840 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010841 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010842 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010843 }
10844 }
10845 }
10846
10847 EXIT();
10848 return 0;
10849}
10850
10851/**---------------------------------------------------------------------------
10852
Jeff Johnson295189b2012-06-20 16:38:30 -070010853 \brief hdd_softap_sta_disassoc() - function
10854
10855 This to take counter measure to handle deauth req from HDD
10856
10857 \param - pAdapter - Pointer to the HDD
10858
10859 \param - enable - boolean value
10860
10861 \return - None
10862
10863 --------------------------------------------------------------------------*/
10864
10865void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10866{
10867 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10868
10869 ENTER();
10870
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010871 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010872
10873 //Ignore request to disassoc bcmc station
10874 if( pDestMacAddress[0] & 0x1 )
10875 return;
10876
10877 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10878}
10879
10880void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10881{
10882 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10883
10884 ENTER();
10885
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010886 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010887
10888 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10889}
10890
Jeff Johnson295189b2012-06-20 16:38:30 -070010891/**---------------------------------------------------------------------------
10892 *
10893 * \brief hdd_get__concurrency_mode() -
10894 *
10895 *
10896 * \param - None
10897 *
10898 * \return - CONCURRENCY MODE
10899 *
10900 * --------------------------------------------------------------------------*/
10901tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10902{
10903 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10904 hdd_context_t *pHddCtx;
10905
10906 if (NULL != pVosContext)
10907 {
10908 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10909 if (NULL != pHddCtx)
10910 {
10911 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10912 }
10913 }
10914
10915 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010916 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010917 return VOS_STA;
10918}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010919v_BOOL_t
10920wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10921{
10922 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010923
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010924 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10925 if (pAdapter == NULL)
10926 {
10927 hddLog(VOS_TRACE_LEVEL_INFO,
10928 FL("GO doesn't exist"));
10929 return TRUE;
10930 }
10931 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10932 {
10933 hddLog(VOS_TRACE_LEVEL_INFO,
10934 FL("GO started"));
10935 return TRUE;
10936 }
10937 else
10938 /* wait till GO changes its interface to p2p device */
10939 hddLog(VOS_TRACE_LEVEL_INFO,
10940 FL("Del_bss called, avoid apps suspend"));
10941 return FALSE;
10942
10943}
Jeff Johnson295189b2012-06-20 16:38:30 -070010944/* Decide whether to allow/not the apps power collapse.
10945 * Allow apps power collapse if we are in connected state.
10946 * if not, allow only if we are in IMPS */
10947v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10948{
10949 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010950 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010951 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010952 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10953 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10954 hdd_adapter_t *pAdapter = NULL;
10955 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010956 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010957
Jeff Johnson295189b2012-06-20 16:38:30 -070010958 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10959 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010960
Yathish9f22e662012-12-10 14:21:35 -080010961 concurrent_state = hdd_get_concurrency_mode();
10962
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010963 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10964 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10965 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010966#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010967
Yathish9f22e662012-12-10 14:21:35 -080010968 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010969 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010970 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10971 return TRUE;
10972#endif
10973
Jeff Johnson295189b2012-06-20 16:38:30 -070010974 /*loop through all adapters. TBD fix for Concurrency */
10975 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10976 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10977 {
10978 pAdapter = pAdapterNode->pAdapter;
10979 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10980 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10981 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010982 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010983 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010984 && pmcState != STOPPED && pmcState != STANDBY &&
10985 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010986 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10987 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010988 {
Mukul Sharma4be88422015-03-09 20:29:07 +053010989 if(pmcState == FULL_POWER &&
10990 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
10991 {
10992 /*
10993 * When SCO indication comes from Coex module , host will
10994 * enter in to full power mode, but this should not prevent
10995 * apps processor power collapse.
10996 */
10997 hddLog(LOG1,
10998 FL("Allow apps power collapse"
10999 "even when sco indication is set"));
11000 return TRUE;
11001 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080011002 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080011003 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
11004 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070011005 return FALSE;
11006 }
11007 }
11008 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11009 pAdapterNode = pNext;
11010 }
11011 return TRUE;
11012}
11013
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080011014/* Decides whether to send suspend notification to Riva
11015 * if any adapter is in BMPS; then it is required */
11016v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
11017{
11018 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
11019 hdd_config_t *pConfig = pHddCtx->cfg_ini;
11020
11021 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
11022 {
11023 return TRUE;
11024 }
11025 return FALSE;
11026}
11027
Jeff Johnson295189b2012-06-20 16:38:30 -070011028void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11029{
11030 switch(mode)
11031 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011032 case VOS_STA_MODE:
11033 case VOS_P2P_CLIENT_MODE:
11034 case VOS_P2P_GO_MODE:
11035 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070011036 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011037 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070011038 break;
11039 default:
11040 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011041 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011042 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11043 "Number of open sessions for mode %d = %d"),
11044 pHddCtx->concurrency_mode, mode,
11045 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011046}
11047
11048
11049void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11050{
11051 switch(mode)
11052 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011053 case VOS_STA_MODE:
11054 case VOS_P2P_CLIENT_MODE:
11055 case VOS_P2P_GO_MODE:
11056 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053011057 pHddCtx->no_of_open_sessions[mode]--;
11058 if (!(pHddCtx->no_of_open_sessions[mode]))
11059 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070011060 break;
11061 default:
11062 break;
11063 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011064 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11065 "Number of open sessions for mode %d = %d"),
11066 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
11067
11068}
11069/**---------------------------------------------------------------------------
11070 *
11071 * \brief wlan_hdd_incr_active_session()
11072 *
11073 * This function increments the number of active sessions
11074 * maintained per device mode
11075 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
11076 * Incase of SAP/P2P GO upon bss start it is incremented
11077 *
11078 * \param pHddCtx - HDD Context
11079 * \param mode - device mode
11080 *
11081 * \return - None
11082 *
11083 * --------------------------------------------------------------------------*/
11084void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11085{
11086 switch (mode) {
11087 case VOS_STA_MODE:
11088 case VOS_P2P_CLIENT_MODE:
11089 case VOS_P2P_GO_MODE:
11090 case VOS_STA_SAP_MODE:
11091 pHddCtx->no_of_active_sessions[mode]++;
11092 break;
11093 default:
11094 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11095 break;
11096 }
11097 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11098 mode,
11099 pHddCtx->no_of_active_sessions[mode]);
11100}
11101
11102/**---------------------------------------------------------------------------
11103 *
11104 * \brief wlan_hdd_decr_active_session()
11105 *
11106 * This function decrements the number of active sessions
11107 * maintained per device mode
11108 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
11109 * Incase of SAP/P2P GO upon bss stop it is decremented
11110 *
11111 * \param pHddCtx - HDD Context
11112 * \param mode - device mode
11113 *
11114 * \return - None
11115 *
11116 * --------------------------------------------------------------------------*/
11117void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11118{
11119 switch (mode) {
11120 case VOS_STA_MODE:
11121 case VOS_P2P_CLIENT_MODE:
11122 case VOS_P2P_GO_MODE:
11123 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053011124 if (pHddCtx->no_of_active_sessions[mode] > 0)
11125 pHddCtx->no_of_active_sessions[mode]--;
11126 else
11127 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
11128 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053011129 break;
11130 default:
11131 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11132 break;
11133 }
11134 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11135 mode,
11136 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011137}
11138
Jeff Johnsone7245742012-09-05 17:12:55 -070011139/**---------------------------------------------------------------------------
11140 *
11141 * \brief wlan_hdd_restart_init
11142 *
11143 * This function initalizes restart timer/flag. An internal function.
11144 *
11145 * \param - pHddCtx
11146 *
11147 * \return - None
11148 *
11149 * --------------------------------------------------------------------------*/
11150
11151static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
11152{
11153 /* Initialize */
11154 pHddCtx->hdd_restart_retries = 0;
11155 atomic_set(&pHddCtx->isRestartInProgress, 0);
11156 vos_timer_init(&pHddCtx->hdd_restart_timer,
11157 VOS_TIMER_TYPE_SW,
11158 wlan_hdd_restart_timer_cb,
11159 pHddCtx);
11160}
11161/**---------------------------------------------------------------------------
11162 *
11163 * \brief wlan_hdd_restart_deinit
11164 *
11165 * This function cleans up the resources used. An internal function.
11166 *
11167 * \param - pHddCtx
11168 *
11169 * \return - None
11170 *
11171 * --------------------------------------------------------------------------*/
11172
11173static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
11174{
11175
11176 VOS_STATUS vos_status;
11177 /* Block any further calls */
11178 atomic_set(&pHddCtx->isRestartInProgress, 1);
11179 /* Cleanup */
11180 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
11181 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011182 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011183 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
11184 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011185 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011186
11187}
11188
11189/**---------------------------------------------------------------------------
11190 *
11191 * \brief wlan_hdd_framework_restart
11192 *
11193 * This function uses a cfg80211 API to start a framework initiated WLAN
11194 * driver module unload/load.
11195 *
11196 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
11197 *
11198 *
11199 * \param - pHddCtx
11200 *
11201 * \return - VOS_STATUS_SUCCESS: Success
11202 * VOS_STATUS_E_EMPTY: Adapter is Empty
11203 * VOS_STATUS_E_NOMEM: No memory
11204
11205 * --------------------------------------------------------------------------*/
11206
11207static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
11208{
11209 VOS_STATUS status = VOS_STATUS_SUCCESS;
11210 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011211 int len = (sizeof (struct ieee80211_mgmt));
11212 struct ieee80211_mgmt *mgmt = NULL;
11213
11214 /* Prepare the DEAUTH managment frame with reason code */
11215 mgmt = kzalloc(len, GFP_KERNEL);
11216 if(mgmt == NULL)
11217 {
11218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11219 "%s: memory allocation failed (%d bytes)", __func__, len);
11220 return VOS_STATUS_E_NOMEM;
11221 }
11222 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070011223
11224 /* Iterate over all adapters/devices */
11225 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011226 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
11227 {
11228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11229 FL("fail to get adapter: %p %d"), pAdapterNode, status);
11230 goto end;
11231 }
11232
Jeff Johnsone7245742012-09-05 17:12:55 -070011233 do
11234 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011235 if(pAdapterNode->pAdapter &&
11236 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070011237 {
11238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11239 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
11240 pAdapterNode->pAdapter->dev->name,
11241 pAdapterNode->pAdapter->device_mode,
11242 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011243 /*
11244 * CFG80211 event to restart the driver
11245 *
11246 * 'cfg80211_send_unprot_deauth' sends a
11247 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
11248 * of SME(Linux Kernel) state machine.
11249 *
11250 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
11251 * the driver.
11252 *
11253 */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011254#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
11255 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
11256#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011257 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011258#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011259 }
11260 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11261 pAdapterNode = pNext;
11262 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
11263
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011264 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011265 /* Free the allocated management frame */
11266 kfree(mgmt);
11267
Jeff Johnsone7245742012-09-05 17:12:55 -070011268 /* Retry until we unload or reach max count */
11269 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
11270 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
11271
11272 return status;
11273
11274}
11275/**---------------------------------------------------------------------------
11276 *
11277 * \brief wlan_hdd_restart_timer_cb
11278 *
11279 * Restart timer callback. An internal function.
11280 *
11281 * \param - User data:
11282 *
11283 * \return - None
11284 *
11285 * --------------------------------------------------------------------------*/
11286
11287void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
11288{
11289 hdd_context_t *pHddCtx = usrDataForCallback;
11290 wlan_hdd_framework_restart(pHddCtx);
11291 return;
11292
11293}
11294
11295
11296/**---------------------------------------------------------------------------
11297 *
11298 * \brief wlan_hdd_restart_driver
11299 *
11300 * This function sends an event to supplicant to restart the WLAN driver.
11301 *
11302 * This function is called from vos_wlanRestart.
11303 *
11304 * \param - pHddCtx
11305 *
11306 * \return - VOS_STATUS_SUCCESS: Success
11307 * VOS_STATUS_E_EMPTY: Adapter is Empty
11308 * VOS_STATUS_E_ALREADY: Request already in progress
11309
11310 * --------------------------------------------------------------------------*/
11311VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
11312{
11313 VOS_STATUS status = VOS_STATUS_SUCCESS;
11314
11315 /* A tight check to make sure reentrancy */
11316 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
11317 {
Mihir Shetefd528652014-06-23 19:07:50 +053011318 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070011319 "%s: WLAN restart is already in progress", __func__);
11320
11321 return VOS_STATUS_E_ALREADY;
11322 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070011323 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080011324#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053011325 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070011326#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011327
Jeff Johnsone7245742012-09-05 17:12:55 -070011328 return status;
11329}
11330
Mihir Shetee1093ba2014-01-21 20:13:32 +053011331/**---------------------------------------------------------------------------
11332 *
11333 * \brief wlan_hdd_init_channels
11334 *
11335 * This function is used to initialize the channel list in CSR
11336 *
11337 * This function is called from hdd_wlan_startup
11338 *
11339 * \param - pHddCtx: HDD context
11340 *
11341 * \return - VOS_STATUS_SUCCESS: Success
11342 * VOS_STATUS_E_FAULT: Failure reported by SME
11343
11344 * --------------------------------------------------------------------------*/
11345static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
11346{
11347 eHalStatus status;
11348
11349 status = sme_InitChannels(pHddCtx->hHal);
11350 if (HAL_STATUS_SUCCESS(status))
11351 {
11352 return VOS_STATUS_SUCCESS;
11353 }
11354 else
11355 {
11356 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
11357 __func__, status);
11358 return VOS_STATUS_E_FAULT;
11359 }
11360}
11361
Mihir Shete04206452014-11-20 17:50:58 +053011362#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011363VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011364{
11365 eHalStatus status;
11366
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011367 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011368 if (HAL_STATUS_SUCCESS(status))
11369 {
11370 return VOS_STATUS_SUCCESS;
11371 }
11372 else
11373 {
11374 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
11375 __func__, status);
11376 return VOS_STATUS_E_FAULT;
11377 }
11378}
Mihir Shete04206452014-11-20 17:50:58 +053011379#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070011380/*
11381 * API to find if there is any STA or P2P-Client is connected
11382 */
11383VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
11384{
11385 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
11386}
Jeff Johnsone7245742012-09-05 17:12:55 -070011387
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011388
11389/*
11390 * API to find if the firmware will send logs using DXE channel
11391 */
11392v_U8_t hdd_is_fw_logging_enabled(void)
11393{
11394 hdd_context_t *pHddCtx;
11395
11396 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11397 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11398
Sachin Ahuja084313e2015-05-21 17:57:10 +053011399 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011400}
11401
Agarwal Ashish57e84372014-12-05 18:26:53 +053011402/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053011403 * API to find if the firmware will send trace logs using DXE channel
11404 */
11405v_U8_t hdd_is_fw_ev_logging_enabled(void)
11406{
11407 hdd_context_t *pHddCtx;
11408
11409 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11410 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11411
11412 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
11413}
11414/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053011415 * API to find if there is any session connected
11416 */
11417VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
11418{
11419 return sme_is_any_session_connected(pHddCtx->hHal);
11420}
11421
11422
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011423int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
11424{
11425 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11426 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053011427 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053011428 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011429
11430 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053011431 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011432 if (pScanInfo->mScanPending)
11433 {
c_hpothua3d45d52015-01-05 14:11:17 +053011434 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
11435 eCSR_SCAN_ABORT_DEFAULT);
11436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11437 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011438
c_hpothua3d45d52015-01-05 14:11:17 +053011439 /* If there is active scan command lets wait for the completion else
11440 * there is no need to wait as scan command might be in the SME pending
11441 * command list.
11442 */
11443 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
11444 {
c_hpothua3d45d52015-01-05 14:11:17 +053011445 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011446 &pScanInfo->abortscan_event_var,
11447 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053011448 if (0 >= status)
11449 {
11450 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053011451 "%s: Timeout or Interrupt occurred while waiting for abort"
11452 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053011453 return -ETIMEDOUT;
11454 }
11455 }
11456 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
11457 {
11458 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11459 FL("hdd_abort_mac_scan failed"));
11460 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011461 }
11462 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053011463 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011464}
11465
c_hpothu225aa7c2014-10-22 17:45:13 +053011466VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
11467{
11468 hdd_adapter_t *pAdapter;
11469 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11470 VOS_STATUS vosStatus;
11471
11472 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11473 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11474 {
11475 pAdapter = pAdapterNode->pAdapter;
11476 if (NULL != pAdapter)
11477 {
11478 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
11479 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
11480 WLAN_HDD_P2P_GO == pAdapter->device_mode)
11481 {
11482 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
11483 pAdapter->device_mode);
11484 if (VOS_STATUS_SUCCESS !=
11485 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
11486 {
11487 hddLog(LOGE, FL("failed to abort ROC"));
11488 return VOS_STATUS_E_FAILURE;
11489 }
11490 }
11491 }
11492 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11493 pAdapterNode = pNext;
11494 }
11495 return VOS_STATUS_SUCCESS;
11496}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053011497
Mihir Shete0be28772015-02-17 18:42:14 +053011498hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
11499{
11500 hdd_adapter_t *pAdapter;
11501 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11502 hdd_cfg80211_state_t *cfgState;
11503 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
11504 VOS_STATUS vosStatus;
11505
11506 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
11507 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11508 {
11509 pAdapter = pAdapterNode->pAdapter;
11510 if (NULL != pAdapter)
11511 {
11512 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
11513 pRemainChanCtx = cfgState->remain_on_chan_ctx;
11514 if (pRemainChanCtx)
11515 break;
11516 }
11517 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
11518 pAdapterNode = pNext;
11519 }
11520 return pRemainChanCtx;
11521}
11522
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053011523/**
11524 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
11525 *
11526 * @pHddCtx: HDD context within host driver
11527 * @dfsScanMode: dfsScanMode passed from ioctl
11528 *
11529 */
11530
11531VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
11532 tANI_U8 dfsScanMode)
11533{
11534 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11535 hdd_adapter_t *pAdapter;
11536 VOS_STATUS vosStatus;
11537 hdd_station_ctx_t *pHddStaCtx;
11538 eHalStatus status = eHAL_STATUS_SUCCESS;
11539
11540 if(!pHddCtx)
11541 {
11542 hddLog(LOGE, FL("HDD context is Null"));
11543 return eHAL_STATUS_FAILURE;
11544 }
11545
11546 if (pHddCtx->scan_info.mScanPending)
11547 {
11548 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
11549 pHddCtx->scan_info.sessionId);
11550 hdd_abort_mac_scan(pHddCtx,
11551 pHddCtx->scan_info.sessionId,
11552 eCSR_SCAN_ABORT_DEFAULT);
11553 }
11554
11555 if (!dfsScanMode)
11556 {
11557 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11558 while ((NULL != pAdapterNode) &&
11559 (VOS_STATUS_SUCCESS == vosStatus))
11560 {
11561 pAdapter = pAdapterNode->pAdapter;
11562
11563 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11564 {
11565 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11566
11567 if(!pHddStaCtx)
11568 {
11569 hddLog(LOGE, FL("HDD STA context is Null"));
11570 return eHAL_STATUS_FAILURE;
11571 }
11572
11573 /* if STA is already connected on DFS channel,
11574 disconnect immediately*/
11575 if (hdd_connIsConnected(pHddStaCtx) &&
11576 (NV_CHANNEL_DFS ==
11577 vos_nv_getChannelEnabledState(
11578 pHddStaCtx->conn_info.operationChannel)))
11579 {
11580 status = sme_RoamDisconnect(pHddCtx->hHal,
11581 pAdapter->sessionId,
11582 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11583 hddLog(LOG1, FL("Client connected on DFS channel %d,"
11584 "sme_RoamDisconnect returned with status: %d"
11585 "for sessionid: %d"), pHddStaCtx->conn_info.
11586 operationChannel, status, pAdapter->sessionId);
11587 }
11588 }
11589
11590 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
11591 &pNext);
11592 pAdapterNode = pNext;
11593 }
11594 }
11595
11596 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
11597 sme_UpdateDFSRoamMode(pHddCtx->hHal,
11598 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
11599
11600 status = sme_HandleDFSChanScan(pHddCtx->hHal);
11601 if (!HAL_STATUS_SUCCESS(status))
11602 {
11603 hddLog(LOGE,
11604 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
11605 return status;
11606 }
11607
11608 return status;
11609}
11610
Nirav Shah7e3c8132015-06-22 23:51:42 +053011611static int hdd_log2_ceil(unsigned value)
11612{
11613 /* need to switch to unsigned math so that negative values
11614 * will right-shift towards 0 instead of -1
11615 */
11616 unsigned tmp = value;
11617 int log2 = -1;
11618
11619 if (value == 0)
11620 return 0;
11621
11622 while (tmp) {
11623 log2++;
11624 tmp >>= 1;
11625 }
11626 if (1U << log2 != value)
11627 log2++;
11628
11629 return log2;
11630}
11631
11632/**
11633 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
11634 * @pAdapter: adapter handle
11635 *
11636 * Return: vos status
11637 */
11638VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
11639{
11640 int hash_elem, log2, i;
11641
11642 spin_lock_bh( &pAdapter->sta_hash_lock);
11643 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
11644 spin_unlock_bh( &pAdapter->sta_hash_lock);
11645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11646 "%s: hash already attached for session id %d",
11647 __func__, pAdapter->sessionId);
11648 return VOS_STATUS_SUCCESS;
11649 }
11650 spin_unlock_bh( &pAdapter->sta_hash_lock);
11651
11652 hash_elem = WLAN_MAX_STA_COUNT;
11653 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
11654 log2 = hdd_log2_ceil(hash_elem);
11655 hash_elem = 1 << log2;
11656
11657 pAdapter->sta_id_hash.mask = hash_elem - 1;
11658 pAdapter->sta_id_hash.idx_bits = log2;
11659 pAdapter->sta_id_hash.bins =
11660 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
11661 if (!pAdapter->sta_id_hash.bins) {
11662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11663 "%s: malloc failed for session %d",
11664 __func__, pAdapter->sessionId);
11665 return VOS_STATUS_E_NOMEM;
11666 }
11667
11668 for (i = 0; i < hash_elem; i++)
11669 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
11670
11671 spin_lock_bh( &pAdapter->sta_hash_lock);
11672 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
11673 spin_unlock_bh( &pAdapter->sta_hash_lock);
11674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11675 "%s: Station ID Hash attached for session id %d",
11676 __func__, pAdapter->sessionId);
11677
11678 return VOS_STATUS_SUCCESS;
11679}
11680
11681/**
11682 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
11683 * @pAdapter: adapter handle
11684 *
11685 * Return: vos status
11686 */
11687VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
11688{
11689 int hash_elem, i;
11690 v_SIZE_t size;
11691
11692 spin_lock_bh( &pAdapter->sta_hash_lock);
11693 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11694 spin_unlock_bh( &pAdapter->sta_hash_lock);
11695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11696 "%s: hash not initialized for session id %d",
11697 __func__, pAdapter->sessionId);
11698 return VOS_STATUS_SUCCESS;
11699 }
11700
11701 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
11702 spin_unlock_bh( &pAdapter->sta_hash_lock);
11703
11704 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
11705
11706 /* free all station info*/
11707 for (i = 0; i < hash_elem; i++) {
11708 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
11709 if (size != 0) {
11710 VOS_STATUS status;
11711 hdd_staid_hash_node_t *sta_info_node = NULL;
11712 hdd_staid_hash_node_t *next_node = NULL;
11713 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
11714 (hdd_list_node_t**) &sta_info_node );
11715
11716 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11717 {
11718 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
11719 &sta_info_node->node);
11720 vos_mem_free(sta_info_node);
11721
11722 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
11723 (hdd_list_node_t*)sta_info_node,
11724 (hdd_list_node_t**)&next_node);
11725 sta_info_node = next_node;
11726 }
11727 }
11728 }
11729
11730 vos_mem_free(pAdapter->sta_id_hash.bins);
11731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11732 "%s: Station ID Hash detached for session id %d",
11733 __func__, pAdapter->sessionId);
11734 return VOS_STATUS_SUCCESS;
11735}
11736
11737/**
11738 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
11739 * @pAdapter: adapter handle
11740 * @mac_addr_in: input mac address
11741 *
11742 * Return: index derived from mac address
11743 */
11744int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
11745 v_MACADDR_t *mac_addr_in)
11746{
11747 uint16 index;
11748 struct hdd_align_mac_addr_t * mac_addr =
11749 (struct hdd_align_mac_addr_t *)mac_addr_in;
11750
11751 index = mac_addr->bytes_ab ^
11752 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
11753 index ^= index >> pAdapter->sta_id_hash.idx_bits;
11754 index &= pAdapter->sta_id_hash.mask;
11755 return index;
11756}
11757
11758/**
11759 * hdd_sta_id_hash_add_entry() - add entry in hash
11760 * @pAdapter: adapter handle
11761 * @sta_id: station id
11762 * @mac_addr: mac address
11763 *
11764 * Return: vos status
11765 */
11766VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
11767 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11768{
11769 uint16 index;
11770 hdd_staid_hash_node_t *sta_info_node = NULL;
11771
Nirav Shah7e3c8132015-06-22 23:51:42 +053011772 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11773 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
11774 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053011775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11776 "%s: malloc failed", __func__);
11777 return VOS_STATUS_E_NOMEM;
11778 }
11779
11780 sta_info_node->sta_id = sta_id;
11781 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
11782
Nirav Shah303ed5c2015-08-24 10:29:25 +053011783 spin_lock_bh( &pAdapter->sta_hash_lock);
11784 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11785 spin_unlock_bh( &pAdapter->sta_hash_lock);
11786 vos_mem_free(sta_info_node);
11787 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11788 "%s: hash is not initialized for session id %d",
11789 __func__, pAdapter->sessionId);
11790 return VOS_STATUS_E_FAILURE;
11791 }
11792
Nirav Shah7e3c8132015-06-22 23:51:42 +053011793 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
11794 (hdd_list_node_t*) sta_info_node );
11795 spin_unlock_bh( &pAdapter->sta_hash_lock);
11796 return VOS_STATUS_SUCCESS;
11797}
11798
11799/**
11800 * hdd_sta_id_hash_remove_entry() - remove entry from hash
11801 * @pAdapter: adapter handle
11802 * @sta_id: station id
11803 * @mac_addr: mac address
11804 *
11805 * Return: vos status
11806 */
11807VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
11808 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11809{
11810 uint16 index;
11811 VOS_STATUS status;
11812 hdd_staid_hash_node_t *sta_info_node = NULL;
11813 hdd_staid_hash_node_t *next_node = NULL;
11814
11815 spin_lock_bh( &pAdapter->sta_hash_lock);
11816 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11817 spin_unlock_bh( &pAdapter->sta_hash_lock);
11818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11819 "%s: hash is not initialized for session id %d",
11820 __func__, pAdapter->sessionId);
11821 return VOS_STATUS_E_FAILURE;
11822 }
11823
11824 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11825 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11826 (hdd_list_node_t**) &sta_info_node );
11827
11828 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11829 {
11830 if (sta_info_node->sta_id == sta_id) {
11831 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
11832 &sta_info_node->node);
11833 vos_mem_free(sta_info_node);
11834 break;
11835 }
11836 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
11837 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
11838 sta_info_node = next_node;
11839 }
11840 spin_unlock_bh( &pAdapter->sta_hash_lock);
11841 return status;
11842}
11843
11844/**
11845 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
11846 * @pAdapter: adapter handle
11847 * @mac_addr_in: mac address
11848 *
11849 * Return: station id
11850 */
11851int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
11852 v_MACADDR_t *mac_addr_in)
11853{
11854 uint8 is_found = 0;
11855 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
11856 uint16 index;
11857 VOS_STATUS status;
11858 hdd_staid_hash_node_t *sta_info_node = NULL;
11859 hdd_staid_hash_node_t *next_node = NULL;
11860
11861 spin_lock_bh( &pAdapter->sta_hash_lock);
11862 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11863 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053011864 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053011865 FL("hash is not initialized for session id %d"),
11866 pAdapter->sessionId);
11867 return HDD_WLAN_INVALID_STA_ID;
11868 }
11869
11870 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
11871 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11872 (hdd_list_node_t**) &sta_info_node );
11873
11874 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11875 {
11876 if (vos_mem_compare(&sta_info_node->mac_addr,
11877 mac_addr_in, sizeof(v_MACADDR_t))) {
11878 is_found = 1;
11879 sta_id = sta_info_node->sta_id;
11880 break;
11881 }
11882 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
11883 (hdd_list_node_t*)sta_info_node,
11884 (hdd_list_node_t**)&next_node);
11885 sta_info_node = next_node;
11886 }
11887 spin_unlock_bh( &pAdapter->sta_hash_lock);
11888 return sta_id;
11889}
11890
Jeff Johnson295189b2012-06-20 16:38:30 -070011891//Register the module init/exit functions
11892module_init(hdd_module_init);
11893module_exit(hdd_module_exit);
11894
11895MODULE_LICENSE("Dual BSD/GPL");
11896MODULE_AUTHOR("Qualcomm Atheros, Inc.");
11897MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
11898
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011899module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
11900 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011901
Jeff Johnson76052702013-04-16 13:55:05 -070011902module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011903 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080011904
11905module_param(enable_dfs_chan_scan, int,
11906 S_IRUSR | S_IRGRP | S_IROTH);
11907
11908module_param(enable_11d, int,
11909 S_IRUSR | S_IRGRP | S_IROTH);
11910
11911module_param(country_code, charp,
11912 S_IRUSR | S_IRGRP | S_IROTH);