blob: 7bd1b1932dcbbdd3032b54d523fe72c7c6e1e9fc [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
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800197#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -0700198static struct wake_lock wlan_wake_lock;
Jeff Johnsone7245742012-09-05 17:12:55 -0700199#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700200/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700201static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700202
203//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700204static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
205static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
206static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
207void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800208void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700209
Jeff Johnson295189b2012-06-20 16:38:30 -0700210v_U16_t hdd_select_queue(struct net_device *dev,
211 struct sk_buff *skb);
212
213#ifdef WLAN_FEATURE_PACKET_FILTERING
214static void hdd_set_multicast_list(struct net_device *dev);
215#endif
216
217void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
218
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800219#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800220void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
221static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700222static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
223 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
224 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700225static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
226 tANI_U8 *pTargetApBssid,
227 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800228#endif
Ratheesh S P21280412015-05-19 14:21:52 +0530229
230/* Store WLAN driver info in a global variable such that crash debugger
231 can extract it from driver debug symbol and crashdump for post processing */
232tANI_U8 g_wlan_driver[ ] = "pronto_driver";
233
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800234#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700235VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800236#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700237
Mihir Shetee1093ba2014-01-21 20:13:32 +0530238static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530239const char * hdd_device_modetoString(v_U8_t device_mode)
240{
241 switch(device_mode)
242 {
243 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
244 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
245 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
246 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
247 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
248 CASE_RETURN_STRING( WLAN_HDD_FTM );
249 CASE_RETURN_STRING( WLAN_HDD_IBSS );
250 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
251 default:
252 return "device_mode Unknown";
253 }
254}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530255
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530256static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700257 unsigned long state,
258 void *ndev)
259{
260 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700261 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700262 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700263#ifdef WLAN_BTAMP_FEATURE
264 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700265#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530266 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700267
268 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700269 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700270 (strncmp(dev->name, "p2p", 3)))
271 return NOTIFY_DONE;
272
Jeff Johnson295189b2012-06-20 16:38:30 -0700273 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700274 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700275
Jeff Johnson27cee452013-03-27 11:10:24 -0700276 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700277 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800278 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700279 VOS_ASSERT(0);
280 return NOTIFY_DONE;
281 }
282
Jeff Johnson27cee452013-03-27 11:10:24 -0700283 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
284 if (NULL == pHddCtx)
285 {
286 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
287 VOS_ASSERT(0);
288 return NOTIFY_DONE;
289 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800290 if (pHddCtx->isLogpInProgress)
291 return NOTIFY_DONE;
292
Jeff Johnson27cee452013-03-27 11:10:24 -0700293
294 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
295 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700296
297 switch (state) {
298 case NETDEV_REGISTER:
299 break;
300
301 case NETDEV_UNREGISTER:
302 break;
303
304 case NETDEV_UP:
305 break;
306
307 case NETDEV_DOWN:
308 break;
309
310 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700311 if(TRUE == pAdapter->isLinkUpSvcNeeded)
312 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700313 break;
314
315 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530316 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530317 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530318 {
319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
320 "%s: Timeout occurred while waiting for abortscan %ld",
321 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700322 }
323 else
324 {
325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530326 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700327 }
328#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700330 status = WLANBAP_StopAmp();
331 if(VOS_STATUS_SUCCESS != status )
332 {
333 pHddCtx->isAmpAllowed = VOS_TRUE;
334 hddLog(VOS_TRACE_LEVEL_FATAL,
335 "%s: Failed to stop AMP", __func__);
336 }
337 else
338 {
339 //a state m/c implementation in PAL is TBD to avoid this delay
340 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700341 if ( pHddCtx->isAmpAllowed )
342 {
343 WLANBAP_DeregisterFromHCI();
344 pHddCtx->isAmpAllowed = VOS_FALSE;
345 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700346 }
347#endif //WLAN_BTAMP_FEATURE
348 break;
349
350 default:
351 break;
352 }
353
354 return NOTIFY_DONE;
355}
356
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530357static int hdd_netdev_notifier_call(struct notifier_block * nb,
358 unsigned long state,
359 void *ndev)
360{
361 int ret;
362 vos_ssr_protect(__func__);
363 ret = __hdd_netdev_notifier_call( nb, state, ndev);
364 vos_ssr_unprotect(__func__);
365 return ret;
366}
367
Jeff Johnson295189b2012-06-20 16:38:30 -0700368struct notifier_block hdd_netdev_notifier = {
369 .notifier_call = hdd_netdev_notifier_call,
370};
371
372/*---------------------------------------------------------------------------
373 * Function definitions
374 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700375void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
376void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700377//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700378static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700379#ifndef MODULE
380/* current con_mode - used only for statically linked driver
381 * con_mode is changed by userspace to indicate a mode change which will
382 * result in calling the module exit and init functions. The module
383 * exit function will clean up based on the value of con_mode prior to it
384 * being changed by userspace. So curr_con_mode records the current con_mode
385 * for exit when con_mode becomes the next mode for init
386 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700387static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700388#endif
389
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800390/**---------------------------------------------------------------------------
391
392 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
393
394 Called immediately after the cfg.ini is read in order to configure
395 the desired trace levels.
396
397 \param - moduleId - module whose trace level is being configured
398 \param - bitmask - bitmask of log levels to be enabled
399
400 \return - void
401
402 --------------------------------------------------------------------------*/
403static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
404{
405 wpt_tracelevel level;
406
407 /* if the bitmask is the default value, then a bitmask was not
408 specified in cfg.ini, so leave the logging level alone (it
409 will remain at the "compiled in" default value) */
410 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
411 {
412 return;
413 }
414
415 /* a mask was specified. start by disabling all logging */
416 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
417
418 /* now cycle through the bitmask until all "set" bits are serviced */
419 level = VOS_TRACE_LEVEL_FATAL;
420 while (0 != bitmask)
421 {
422 if (bitmask & 1)
423 {
424 vos_trace_setValue(moduleId, level, 1);
425 }
426 level++;
427 bitmask >>= 1;
428 }
429}
430
431
Jeff Johnson295189b2012-06-20 16:38:30 -0700432/**---------------------------------------------------------------------------
433
434 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
435
436 Called immediately after the cfg.ini is read in order to configure
437 the desired trace levels in the WDI.
438
439 \param - moduleId - module whose trace level is being configured
440 \param - bitmask - bitmask of log levels to be enabled
441
442 \return - void
443
444 --------------------------------------------------------------------------*/
445static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
446{
447 wpt_tracelevel level;
448
449 /* if the bitmask is the default value, then a bitmask was not
450 specified in cfg.ini, so leave the logging level alone (it
451 will remain at the "compiled in" default value) */
452 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
453 {
454 return;
455 }
456
457 /* a mask was specified. start by disabling all logging */
458 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
459
460 /* now cycle through the bitmask until all "set" bits are serviced */
461 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
462 while (0 != bitmask)
463 {
464 if (bitmask & 1)
465 {
466 wpalTraceSetLevel(moduleId, level, 1);
467 }
468 level++;
469 bitmask >>= 1;
470 }
471}
Jeff Johnson295189b2012-06-20 16:38:30 -0700472
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530473/*
474 * FUNCTION: wlan_hdd_validate_context
475 * This function is used to check the HDD context
476 */
477int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
478{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530479
480 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
481 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530483 "%s: HDD context is Null", __func__);
484 return -ENODEV;
485 }
486
487 if (pHddCtx->isLogpInProgress)
488 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530489 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530490 "%s: LOGP %s. Ignore!!", __func__,
491 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
492 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530493 return -EAGAIN;
494 }
495
Mihir Shete18156292014-03-11 15:38:30 +0530496 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530497 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530498 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530499 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
500 return -EAGAIN;
501 }
502 return 0;
503}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700504#ifdef CONFIG_ENABLE_LINUX_REG
505void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
506{
507 hdd_adapter_t *pAdapter = NULL;
508 hdd_station_ctx_t *pHddStaCtx = NULL;
509 eCsrPhyMode phyMode;
510 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530511
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700512 if (NULL == pHddCtx)
513 {
514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
515 "HDD Context is null !!");
516 return ;
517 }
518
519 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
520 if (NULL == pAdapter)
521 {
522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
523 "pAdapter is null !!");
524 return ;
525 }
526
527 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
528 if (NULL == pHddStaCtx)
529 {
530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
531 "pHddStaCtx is null !!");
532 return ;
533 }
534
535 cfg_param = pHddCtx->cfg_ini;
536 if (NULL == cfg_param)
537 {
538 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
539 "cfg_params not available !!");
540 return ;
541 }
542
543 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
544
545 if (!pHddCtx->isVHT80Allowed)
546 {
547 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
548 (eCSR_DOT11_MODE_11ac == phyMode) ||
549 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
550 {
551 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
552 "Setting phymode to 11n!!");
553 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
554 }
555 }
556 else
557 {
558 /*New country Supports 11ac as well resetting value back from .ini*/
559 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
560 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
561 return ;
562 }
563
564 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
565 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
566 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
567 {
568 VOS_STATUS vosStatus;
569
570 // need to issue a disconnect to CSR.
571 INIT_COMPLETION(pAdapter->disconnect_comp_var);
572 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
573 pAdapter->sessionId,
574 eCSR_DISCONNECT_REASON_UNSPECIFIED );
575
576 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530577 {
578 long ret;
579
580 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700581 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530582 if (0 >= ret)
583 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
584 ret);
585 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700586
587 }
588}
589#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530590void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
591{
592 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
593 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
594 hdd_config_t *cfg_param;
595 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530596 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530597
598 if (NULL == pHddCtx)
599 {
600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
601 "HDD Context is null !!");
602 return ;
603 }
604
605 cfg_param = pHddCtx->cfg_ini;
606
607 if (NULL == cfg_param)
608 {
609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
610 "cfg_params not available !!");
611 return ;
612 }
613
614 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
615
616 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
617 {
618 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
619 (eCSR_DOT11_MODE_11ac == phyMode) ||
620 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
621 {
622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
623 "Setting phymode to 11n!!");
624 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
625 }
626 }
627 else
628 {
629 /*New country Supports 11ac as well resetting value back from .ini*/
630 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
631 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
632 return ;
633 }
634
635 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
636 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
637 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
638 {
639 VOS_STATUS vosStatus;
640
641 // need to issue a disconnect to CSR.
642 INIT_COMPLETION(pAdapter->disconnect_comp_var);
643 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
644 pAdapter->sessionId,
645 eCSR_DISCONNECT_REASON_UNSPECIFIED );
646
647 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530648 {
649 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530650 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530651 if (ret <= 0)
652 {
653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
654 "wait on disconnect_comp_var is failed %ld", ret);
655 }
656 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530657
658 }
659}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700660#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530661
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700662void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
663{
664 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
665 hdd_config_t *cfg_param;
666
667 if (NULL == pHddCtx)
668 {
669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
670 "HDD Context is null !!");
671 return ;
672 }
673
674 cfg_param = pHddCtx->cfg_ini;
675
676 if (NULL == cfg_param)
677 {
678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
679 "cfg_params not available !!");
680 return ;
681 }
682
Agarwal Ashish738843c2014-09-25 12:27:56 +0530683 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
684 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700685 {
686 /*New country doesn't support DFS */
687 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
688 }
689 else
690 {
691 /*New country Supports DFS as well resetting value back from .ini*/
692 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
693 }
694
695}
696
Rajeev79dbe4c2013-10-05 11:03:42 +0530697#ifdef FEATURE_WLAN_BATCH_SCAN
698
699/**---------------------------------------------------------------------------
700
701 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
702 input string
703
704 This function extracts assigned integer from string in below format:
705 "STRING=10" : extracts integer 10 from this string
706
707 \param - pInPtr Pointer to input string
708 \param - base Base for string to int conversion(10 for decimal 16 for hex)
709 \param - pOutPtr Pointer to variable in which extracted integer needs to be
710 assigned
711 \param - pLastArg to tell whether it is last arguement in input string or
712 not
713
714 \return - NULL for failure cases
715 pointer to next arguement in input string for success cases
716 --------------------------------------------------------------------------*/
717static tANI_U8 *
718hdd_extract_assigned_int_from_str
719(
720 tANI_U8 *pInPtr,
721 tANI_U8 base,
722 tANI_U32 *pOutPtr,
723 tANI_U8 *pLastArg
724)
725{
726 int tempInt;
727 int v = 0;
728 char buf[32];
729 int val = 0;
730 *pLastArg = FALSE;
731
732 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
733 if (NULL == pInPtr)
734 {
735 return NULL;
736 }
737
738 pInPtr++;
739
740 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
741
742 val = sscanf(pInPtr, "%32s ", buf);
743 if (val < 0 && val > strlen(pInPtr))
744 {
745 return NULL;
746 }
747 pInPtr += val;
748 v = kstrtos32(buf, base, &tempInt);
749 if (v < 0)
750 {
751 return NULL;
752 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800753 if (tempInt < 0)
754 {
755 tempInt = 0;
756 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530757 *pOutPtr = tempInt;
758
759 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
760 if (NULL == pInPtr)
761 {
762 *pLastArg = TRUE;
763 return NULL;
764 }
765 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
766
767 return pInPtr;
768}
769
770/**---------------------------------------------------------------------------
771
772 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
773 input string
774
775 This function extracts assigned character from string in below format:
776 "STRING=A" : extracts char 'A' from this string
777
778 \param - pInPtr Pointer to input string
779 \param - pOutPtr Pointer to variable in which extracted char needs to be
780 assigned
781 \param - pLastArg to tell whether it is last arguement in input string or
782 not
783
784 \return - NULL for failure cases
785 pointer to next arguement in input string for success cases
786 --------------------------------------------------------------------------*/
787static tANI_U8 *
788hdd_extract_assigned_char_from_str
789(
790 tANI_U8 *pInPtr,
791 tANI_U8 *pOutPtr,
792 tANI_U8 *pLastArg
793)
794{
795 *pLastArg = FALSE;
796
797 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
798 if (NULL == pInPtr)
799 {
800 return NULL;
801 }
802
803 pInPtr++;
804
805 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
806
807 *pOutPtr = *pInPtr;
808
809 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
810 if (NULL == pInPtr)
811 {
812 *pLastArg = TRUE;
813 return NULL;
814 }
815 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
816
817 return pInPtr;
818}
819
820
821/**---------------------------------------------------------------------------
822
823 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
824
825 This function parses set batch scan command in below format:
826 WLS_BATCHING_SET <space> followed by below arguements
827 "SCANFREQ=XX" : Optional defaults to 30 sec
828 "MSCAN=XX" : Required number of scans to attempt to batch
829 "BESTN=XX" : Best Network (RSSI) defaults to 16
830 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
831 A. implies only 5 GHz , B. implies only 2.4GHz
832 "RTT=X" : optional defaults to 0
833 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
834 error
835
836 For example input commands:
837 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
838 translated into set batch scan with following parameters:
839 a) Frequence 60 seconds
840 b) Batch 10 scans together
841 c) Best RSSI to be 20
842 d) 5GHz band only
843 e) RTT is equal to 0
844
845 \param - pValue Pointer to input channel list
846 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
847
848 \return - 0 for success non-zero for failure
849
850 --------------------------------------------------------------------------*/
851static int
852hdd_parse_set_batchscan_command
853(
854 tANI_U8 *pValue,
855 tSirSetBatchScanReq *pHddSetBatchScanReq
856)
857{
858 tANI_U8 *inPtr = pValue;
859 tANI_U8 val = 0;
860 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800861 tANI_U32 nScanFreq;
862 tANI_U32 nMscan;
863 tANI_U32 nBestN;
864 tANI_U8 ucRfBand;
865 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800866 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530867
868 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800869 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
870 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
871 nRtt = 0;
872 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530873
874 /*go to space after WLS_BATCHING_SET command*/
875 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
876 /*no argument after the command*/
877 if (NULL == inPtr)
878 {
879 return -EINVAL;
880 }
881
882 /*no space after the command*/
883 else if (SPACE_ASCII_VALUE != *inPtr)
884 {
885 return -EINVAL;
886 }
887
888 /*removing empty spaces*/
889 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
890
891 /*no argument followed by spaces*/
892 if ('\0' == *inPtr)
893 {
894 return -EINVAL;
895 }
896
897 /*check and parse SCANFREQ*/
898 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
899 {
900 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800901 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800902
Rajeev Kumarc933d982013-11-18 20:04:20 -0800903 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800904 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800905 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800906 }
907
Rajeev79dbe4c2013-10-05 11:03:42 +0530908 if ( (NULL == inPtr) || (TRUE == lastArg))
909 {
910 return -EINVAL;
911 }
912 }
913
914 /*check and parse MSCAN*/
915 if ((strncmp(inPtr, "MSCAN", 5) == 0))
916 {
917 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800918 &nMscan, &lastArg);
919
920 if (0 == nMscan)
921 {
922 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
923 "invalid MSCAN=%d", nMscan);
924 return -EINVAL;
925 }
926
Rajeev79dbe4c2013-10-05 11:03:42 +0530927 if (TRUE == lastArg)
928 {
929 goto done;
930 }
931 else if (NULL == inPtr)
932 {
933 return -EINVAL;
934 }
935 }
936 else
937 {
938 return -EINVAL;
939 }
940
941 /*check and parse BESTN*/
942 if ((strncmp(inPtr, "BESTN", 5) == 0))
943 {
944 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800945 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800946
Rajeev Kumarc933d982013-11-18 20:04:20 -0800947 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800948 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800949 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800950 }
951
Rajeev79dbe4c2013-10-05 11:03:42 +0530952 if (TRUE == lastArg)
953 {
954 goto done;
955 }
956 else if (NULL == inPtr)
957 {
958 return -EINVAL;
959 }
960 }
961
962 /*check and parse CHANNEL*/
963 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
964 {
965 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800966
Rajeev79dbe4c2013-10-05 11:03:42 +0530967 if (('A' == val) || ('a' == val))
968 {
c_hpothuebf89732014-02-25 13:00:24 +0530969 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530970 }
971 else if (('B' == val) || ('b' == val))
972 {
c_hpothuebf89732014-02-25 13:00:24 +0530973 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530974 }
975 else
976 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800977 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
978 }
979
980 if (TRUE == lastArg)
981 {
982 goto done;
983 }
984 else if (NULL == inPtr)
985 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530986 return -EINVAL;
987 }
988 }
989
990 /*check and parse RTT*/
991 if ((strncmp(inPtr, "RTT", 3) == 0))
992 {
993 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800994 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530995 if (TRUE == lastArg)
996 {
997 goto done;
998 }
999 if (NULL == inPtr)
1000 {
1001 return -EINVAL;
1002 }
1003 }
1004
1005
1006done:
1007
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001008 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1009 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1010 pHddSetBatchScanReq->bestNetwork = nBestN;
1011 pHddSetBatchScanReq->rfBand = ucRfBand;
1012 pHddSetBatchScanReq->rtt = nRtt;
1013
Rajeev79dbe4c2013-10-05 11:03:42 +05301014 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1015 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1016 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1017 pHddSetBatchScanReq->scanFrequency,
1018 pHddSetBatchScanReq->numberOfScansToBatch,
1019 pHddSetBatchScanReq->bestNetwork,
1020 pHddSetBatchScanReq->rfBand,
1021 pHddSetBatchScanReq->rtt);
1022
1023 return 0;
1024}/*End of hdd_parse_set_batchscan_command*/
1025
1026/**---------------------------------------------------------------------------
1027
1028 \brief hdd_set_batch_scan_req_callback () - This function is called after
1029 receiving set batch scan response from FW and it saves set batch scan
1030 response data FW to HDD context and sets the completion event on
1031 which hdd_ioctl is waiting
1032
1033 \param - callbackContext Pointer to HDD adapter
1034 \param - pRsp Pointer to set batch scan response data received from FW
1035
1036 \return - nothing
1037
1038 --------------------------------------------------------------------------*/
1039static void hdd_set_batch_scan_req_callback
1040(
1041 void *callbackContext,
1042 tSirSetBatchScanRsp *pRsp
1043)
1044{
1045 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1046 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1047
1048 /*sanity check*/
1049 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1050 {
1051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1052 "%s: Invalid pAdapter magic", __func__);
1053 VOS_ASSERT(0);
1054 return;
1055 }
1056 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1057
1058 /*save set batch scan response*/
1059 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1060
1061 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1062 "Received set batch scan rsp from FW with nScansToBatch=%d",
1063 pHddSetBatchScanRsp->nScansToBatch);
1064
1065 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1066 complete(&pAdapter->hdd_set_batch_scan_req_var);
1067
1068 return;
1069}/*End of hdd_set_batch_scan_req_callback*/
1070
1071
1072/**---------------------------------------------------------------------------
1073
1074 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1075 info in hdd batch scan response queue
1076
1077 \param - pAdapter Pointer to hdd adapter
1078 \param - pAPMetaInfo Pointer to access point meta info
1079 \param - scanId scan ID of batch scan response
1080 \param - isLastAp tells whether AP is last AP in batch scan response or not
1081
1082 \return - nothing
1083
1084 --------------------------------------------------------------------------*/
1085static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1086 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1087{
1088 tHddBatchScanRsp *pHead;
1089 tHddBatchScanRsp *pNode;
1090 tHddBatchScanRsp *pPrev;
1091 tHddBatchScanRsp *pTemp;
1092 tANI_U8 ssidLen;
1093
1094 /*head of hdd batch scan response queue*/
1095 pHead = pAdapter->pBatchScanRsp;
1096
1097 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1098 if (NULL == pNode)
1099 {
1100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1101 "%s: Could not allocate memory", __func__);
1102 VOS_ASSERT(0);
1103 return;
1104 }
1105
1106 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1107 sizeof(pNode->ApInfo.bssid));
1108 ssidLen = strlen(pApMetaInfo->ssid);
1109 if (SIR_MAX_SSID_SIZE < ssidLen)
1110 {
1111 /*invalid scan result*/
1112 vos_mem_free(pNode);
1113 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1114 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1115 return;
1116 }
1117 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1118 /*null terminate ssid*/
1119 pNode->ApInfo.ssid[ssidLen] = '\0';
1120 pNode->ApInfo.ch = pApMetaInfo->ch;
1121 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1122 pNode->ApInfo.age = pApMetaInfo->timestamp;
1123 pNode->ApInfo.batchId = scanId;
1124 pNode->ApInfo.isLastAp = isLastAp;
1125
1126 pNode->pNext = NULL;
1127 if (NULL == pHead)
1128 {
1129 pAdapter->pBatchScanRsp = pNode;
1130 }
1131 else
1132 {
1133 pTemp = pHead;
1134 while (NULL != pTemp)
1135 {
1136 pPrev = pTemp;
1137 pTemp = pTemp->pNext;
1138 }
1139 pPrev->pNext = pNode;
1140 }
1141
1142 return;
1143}/*End of hdd_populate_batch_scan_rsp_queue*/
1144
1145/**---------------------------------------------------------------------------
1146
1147 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1148 receiving batch scan response indication from FW. It saves get batch scan
1149 response data in HDD batch scan response queue. This callback sets the
1150 completion event on which hdd_ioctl is waiting only after getting complete
1151 batch scan response data from FW
1152
1153 \param - callbackContext Pointer to HDD adapter
1154 \param - pRsp Pointer to get batch scan response data received from FW
1155
1156 \return - nothing
1157
1158 --------------------------------------------------------------------------*/
1159static void hdd_batch_scan_result_ind_callback
1160(
1161 void *callbackContext,
1162 void *pRsp
1163)
1164{
1165 v_BOOL_t isLastAp;
1166 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001167 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301168 tANI_U32 numberScanList;
1169 tANI_U32 nextScanListOffset;
1170 tANI_U32 nextApMetaInfoOffset;
1171 hdd_adapter_t* pAdapter;
1172 tpSirBatchScanList pScanList;
1173 tpSirBatchScanNetworkInfo pApMetaInfo;
1174 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1175 tSirSetBatchScanReq *pReq;
1176
1177 pAdapter = (hdd_adapter_t *)callbackContext;
1178 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001179 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301180 {
1181 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1182 "%s: Invalid pAdapter magic", __func__);
1183 VOS_ASSERT(0);
1184 return;
1185 }
1186
1187 /*initialize locals*/
1188 pReq = &pAdapter->hddSetBatchScanReq;
1189 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1190 isLastAp = FALSE;
1191 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001192 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301193 numberScanList = 0;
1194 nextScanListOffset = 0;
1195 nextApMetaInfoOffset = 0;
1196 pScanList = NULL;
1197 pApMetaInfo = NULL;
1198
1199 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1200 {
1201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1202 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1203 isLastAp = TRUE;
1204 goto done;
1205 }
1206
1207 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1209 "Batch scan rsp: numberScalList %d", numberScanList);
1210
1211 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1212 {
1213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1214 "%s: numberScanList %d", __func__, numberScanList);
1215 isLastAp = TRUE;
1216 goto done;
1217 }
1218
1219 while (numberScanList)
1220 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001221 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301222 nextScanListOffset);
1223 if (NULL == pScanList)
1224 {
1225 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1226 "%s: pScanList is %p", __func__, pScanList);
1227 isLastAp = TRUE;
1228 goto done;
1229 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001230 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001232 "Batch scan rsp: numApMetaInfo %d scanId %d",
1233 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301234
1235 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1236 {
1237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1238 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1239 isLastAp = TRUE;
1240 goto done;
1241 }
1242
Rajeev Kumarce651e42013-10-21 18:57:15 -07001243 /*Initialize next AP meta info offset for next scan list*/
1244 nextApMetaInfoOffset = 0;
1245
Rajeev79dbe4c2013-10-05 11:03:42 +05301246 while (numApMetaInfo)
1247 {
1248 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1249 nextApMetaInfoOffset);
1250 if (NULL == pApMetaInfo)
1251 {
1252 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1253 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1254 isLastAp = TRUE;
1255 goto done;
1256 }
1257 /*calculate AP age*/
1258 pApMetaInfo->timestamp =
1259 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1260
1261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001262 "%s: bssId "MAC_ADDRESS_STR
1263 " ch %d rssi %d timestamp %d", __func__,
1264 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1265 pApMetaInfo->ch, pApMetaInfo->rssi,
1266 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301267
1268 /*mark last AP in batch scan response*/
1269 if ((TRUE == pBatchScanRsp->isLastResult) &&
1270 (1 == numberScanList) && (1 == numApMetaInfo))
1271 {
1272 isLastAp = TRUE;
1273 }
1274
1275 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1276 /*store batch scan repsonse in hdd queue*/
1277 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1278 pScanList->scanId, isLastAp);
1279 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1280
1281 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1282 numApMetaInfo--;
1283 }
1284
Rajeev Kumarce651e42013-10-21 18:57:15 -07001285 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1286 + (sizeof(tSirBatchScanNetworkInfo)
1287 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301288 numberScanList--;
1289 }
1290
1291done:
1292
1293 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1294 requested from hdd_ioctl*/
1295 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1296 (TRUE == isLastAp))
1297 {
1298 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1299 complete(&pAdapter->hdd_get_batch_scan_req_var);
1300 }
1301
1302 return;
1303}/*End of hdd_batch_scan_result_ind_callback*/
1304
1305/**---------------------------------------------------------------------------
1306
1307 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1308 response as per batch scan FR request format by putting proper markers
1309
1310 \param - pDest pointer to destination buffer
1311 \param - cur_len current length
1312 \param - tot_len total remaining size which can be written to user space
1313 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1314 \param - pAdapter Pointer to HDD adapter
1315
1316 \return - ret no of characters written
1317
1318 --------------------------------------------------------------------------*/
1319static tANI_U32
1320hdd_format_batch_scan_rsp
1321(
1322 tANI_U8 *pDest,
1323 tANI_U32 cur_len,
1324 tANI_U32 tot_len,
1325 tHddBatchScanRsp *pApMetaInfo,
1326 hdd_adapter_t* pAdapter
1327)
1328{
1329 tANI_U32 ret = 0;
1330 tANI_U32 rem_len = 0;
1331 tANI_U8 temp_len = 0;
1332 tANI_U8 temp_total_len = 0;
1333 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1334 tANI_U8 *pTemp = temp;
1335
1336 /*Batch scan reponse needs to be returned to user space in
1337 following format:
1338 "scancount=X\n" where X is the number of scans in current batch
1339 batch
1340 "trunc\n" optional present if current scan truncated
1341 "bssid=XX:XX:XX:XX:XX:XX\n"
1342 "ssid=XXXX\n"
1343 "freq=X\n" frequency in Mhz
1344 "level=XX\n"
1345 "age=X\n" ms
1346 "dist=X\n" cm (-1 if not available)
1347 "errror=X\n" (-1if not available)
1348 "====\n" (end of ap marker)
1349 "####\n" (end of scan marker)
1350 "----\n" (end of results)*/
1351 /*send scan result in above format to user space based on
1352 available length*/
1353 /*The GET response may have more data than the driver can return in its
1354 buffer. In that case the buffer should be filled to the nearest complete
1355 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1356 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1357 The final buffer should end with "----\n"*/
1358
1359 /*sanity*/
1360 if (cur_len > tot_len)
1361 {
1362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1363 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1364 return 0;
1365 }
1366 else
1367 {
1368 rem_len = (tot_len - cur_len);
1369 }
1370
1371 /*end scan marker*/
1372 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1373 {
1374 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1375 pTemp += temp_len;
1376 temp_total_len += temp_len;
1377 }
1378
1379 /*bssid*/
1380 temp_len = snprintf(pTemp, sizeof(temp),
1381 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1382 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1383 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1384 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1385 pTemp += temp_len;
1386 temp_total_len += temp_len;
1387
1388 /*ssid*/
1389 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1390 pApMetaInfo->ApInfo.ssid);
1391 pTemp += temp_len;
1392 temp_total_len += temp_len;
1393
1394 /*freq*/
1395 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001396 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301397 pTemp += temp_len;
1398 temp_total_len += temp_len;
1399
1400 /*level*/
1401 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1402 pApMetaInfo->ApInfo.rssi);
1403 pTemp += temp_len;
1404 temp_total_len += temp_len;
1405
1406 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001407 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301408 pApMetaInfo->ApInfo.age);
1409 pTemp += temp_len;
1410 temp_total_len += temp_len;
1411
1412 /*dist*/
1413 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1414 pTemp += temp_len;
1415 temp_total_len += temp_len;
1416
1417 /*error*/
1418 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1419 pTemp += temp_len;
1420 temp_total_len += temp_len;
1421
1422 /*end AP marker*/
1423 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1424 pTemp += temp_len;
1425 temp_total_len += temp_len;
1426
1427 /*last AP in batch scan response*/
1428 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1429 {
1430 /*end scan marker*/
1431 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1432 pTemp += temp_len;
1433 temp_total_len += temp_len;
1434
1435 /*end batch scan result marker*/
1436 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1437 pTemp += temp_len;
1438 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001439
Rajeev79dbe4c2013-10-05 11:03:42 +05301440 }
1441
1442 if (temp_total_len < rem_len)
1443 {
1444 ret = temp_total_len + 1;
1445 strlcpy(pDest, temp, ret);
1446 pAdapter->isTruncated = FALSE;
1447 }
1448 else
1449 {
1450 pAdapter->isTruncated = TRUE;
1451 if (rem_len >= strlen("%%%%"))
1452 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001453 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301454 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001455 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301456 {
1457 ret = 0;
1458 }
1459 }
1460
1461 return ret;
1462
1463}/*End of hdd_format_batch_scan_rsp*/
1464
1465/**---------------------------------------------------------------------------
1466
1467 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1468 buffer starting with head of hdd batch scan response queue
1469
1470 \param - pAdapter Pointer to HDD adapter
1471 \param - pDest Pointer to user data buffer
1472 \param - cur_len current offset in user buffer
1473 \param - rem_len remaining no of bytes in user buffer
1474
1475 \return - number of bytes written in user buffer
1476
1477 --------------------------------------------------------------------------*/
1478
1479tANI_U32 hdd_populate_user_batch_scan_rsp
1480(
1481 hdd_adapter_t* pAdapter,
1482 tANI_U8 *pDest,
1483 tANI_U32 cur_len,
1484 tANI_U32 rem_len
1485)
1486{
1487 tHddBatchScanRsp *pHead;
1488 tHddBatchScanRsp *pPrev;
1489 tANI_U32 len;
1490
Rajeev79dbe4c2013-10-05 11:03:42 +05301491 pAdapter->isTruncated = FALSE;
1492
1493 /*head of hdd batch scan response queue*/
1494 pHead = pAdapter->pBatchScanRsp;
1495 while (pHead)
1496 {
1497 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1498 pAdapter);
1499 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001500 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301501 cur_len += len;
1502 if(TRUE == pAdapter->isTruncated)
1503 {
1504 /*result is truncated return rest of scan rsp in next req*/
1505 cur_len = rem_len;
1506 break;
1507 }
1508 pPrev = pHead;
1509 pHead = pHead->pNext;
1510 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001511 if (TRUE == pPrev->ApInfo.isLastAp)
1512 {
1513 pAdapter->prev_batch_id = 0;
1514 }
1515 else
1516 {
1517 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1518 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301519 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001520 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301521 }
1522
1523 return cur_len;
1524}/*End of hdd_populate_user_batch_scan_rsp*/
1525
1526/**---------------------------------------------------------------------------
1527
1528 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1529 scan response data from HDD queue to user space
1530 It does following in detail:
1531 a) if HDD has enough data in its queue then it 1st copies data to user
1532 space and then send get batch scan indication message to FW. In this
1533 case it does not wait on any event and batch scan response data will
1534 be populated in HDD response queue in MC thread context after receiving
1535 indication from FW
1536 b) else send get batch scan indication message to FW and wait on an event
1537 which will be set once HDD receives complete batch scan response from
1538 FW and then this function returns batch scan response to user space
1539
1540 \param - pAdapter Pointer to HDD adapter
1541 \param - pPrivData Pointer to priv_data
1542
1543 \return - 0 for success -EFAULT for failure
1544
1545 --------------------------------------------------------------------------*/
1546
1547int hdd_return_batch_scan_rsp_to_user
1548(
1549 hdd_adapter_t* pAdapter,
1550 hdd_priv_data_t *pPrivData,
1551 tANI_U8 *command
1552)
1553{
1554 tANI_U8 *pDest;
1555 tANI_U32 count = 0;
1556 tANI_U32 len = 0;
1557 tANI_U32 cur_len = 0;
1558 tANI_U32 rem_len = 0;
1559 eHalStatus halStatus;
1560 unsigned long rc;
1561 tSirTriggerBatchScanResultInd *pReq;
1562
1563 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1564 pReq->param = 0;/*batch scan client*/
1565 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1566 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1567
1568 cur_len = pPrivData->used_len;
1569 if (pPrivData->total_len > pPrivData->used_len)
1570 {
1571 rem_len = pPrivData->total_len - pPrivData->used_len;
1572 }
1573 else
1574 {
1575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1576 "%s: Invalid user data buffer total_len %d used_len %d",
1577 __func__, pPrivData->total_len, pPrivData->used_len);
1578 return -EFAULT;
1579 }
1580
1581 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1582 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1583 cur_len, rem_len);
1584 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1585
1586 /*enough scan result available in cache to return to user space or
1587 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001588 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301589 {
1590 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1591 halStatus = sme_TriggerBatchScanResultInd(
1592 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1593 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1594 pAdapter);
1595 if ( eHAL_STATUS_SUCCESS == halStatus )
1596 {
1597 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1598 {
1599 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1600 rc = wait_for_completion_timeout(
1601 &pAdapter->hdd_get_batch_scan_req_var,
1602 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1603 if (0 == rc)
1604 {
1605 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1606 "%s: Timeout waiting to fetch batch scan rsp from fw",
1607 __func__);
1608 return -EFAULT;
1609 }
1610 }
1611
1612 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001613 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301614 pDest += len;
1615 cur_len += len;
1616
1617 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1618 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1619 cur_len, rem_len);
1620 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1621
1622 count = 0;
1623 len = (len - pPrivData->used_len);
1624 pDest = (command + pPrivData->used_len);
1625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001626 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301627 while(count < len)
1628 {
1629 printk("%c", *(pDest + count));
1630 count++;
1631 }
1632 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1633 "%s: copy %d data to user buffer", __func__, len);
1634 if (copy_to_user(pPrivData->buf, pDest, len))
1635 {
1636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1637 "%s: failed to copy data to user buffer", __func__);
1638 return -EFAULT;
1639 }
1640 }
1641 else
1642 {
1643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1644 "sme_GetBatchScanScan returned failure halStatus %d",
1645 halStatus);
1646 return -EINVAL;
1647 }
1648 }
1649 else
1650 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301651 count = 0;
1652 len = (len - pPrivData->used_len);
1653 pDest = (command + pPrivData->used_len);
1654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001655 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301656 while(count < len)
1657 {
1658 printk("%c", *(pDest + count));
1659 count++;
1660 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1662 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301663 if (copy_to_user(pPrivData->buf, pDest, len))
1664 {
1665 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1666 "%s: failed to copy data to user buffer", __func__);
1667 return -EFAULT;
1668 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301669 }
1670
1671 return 0;
1672} /*End of hdd_return_batch_scan_rsp_to_user*/
1673
Rajeev Kumar8b373292014-01-08 20:36:55 -08001674
1675/**---------------------------------------------------------------------------
1676
1677 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1678 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1679 WLS_BATCHING VERSION
1680 WLS_BATCHING SET
1681 WLS_BATCHING GET
1682 WLS_BATCHING STOP
1683
1684 \param - pAdapter Pointer to HDD adapter
1685 \param - pPrivdata Pointer to priv_data
1686 \param - command Pointer to command
1687
1688 \return - 0 for success -EFAULT for failure
1689
1690 --------------------------------------------------------------------------*/
1691
1692int hdd_handle_batch_scan_ioctl
1693(
1694 hdd_adapter_t *pAdapter,
1695 hdd_priv_data_t *pPrivdata,
1696 tANI_U8 *command
1697)
1698{
1699 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001700 hdd_context_t *pHddCtx;
1701
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301702 ENTER();
1703
Yue Mae36e3552014-03-05 17:06:20 -08001704 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1705 ret = wlan_hdd_validate_context(pHddCtx);
1706 if (ret)
1707 {
Yue Mae36e3552014-03-05 17:06:20 -08001708 goto exit;
1709 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001710
1711 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1712 {
1713 char extra[32];
1714 tANI_U8 len = 0;
1715 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1716
1717 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1718 {
1719 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1720 "%s: Batch scan feature is not supported by FW", __func__);
1721 ret = -EINVAL;
1722 goto exit;
1723 }
1724
1725 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1726 version);
1727 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1728 {
1729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1730 "%s: failed to copy data to user buffer", __func__);
1731 ret = -EFAULT;
1732 goto exit;
1733 }
1734 ret = HDD_BATCH_SCAN_VERSION;
1735 }
1736 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1737 {
1738 int status;
1739 tANI_U8 *value = (command + 16);
1740 eHalStatus halStatus;
1741 unsigned long rc;
1742 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1743 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1744
1745 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1746 {
1747 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1748 "%s: Batch scan feature is not supported by FW", __func__);
1749 ret = -EINVAL;
1750 goto exit;
1751 }
1752
1753 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1754 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1755 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1756 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1757 {
1758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301759 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001760 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301761 hdd_device_modetoString(pAdapter->device_mode),
1762 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001763 ret = -EINVAL;
1764 goto exit;
1765 }
1766
1767 status = hdd_parse_set_batchscan_command(value, pReq);
1768 if (status)
1769 {
1770 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1771 "Invalid WLS_BATCHING SET command");
1772 ret = -EINVAL;
1773 goto exit;
1774 }
1775
1776
1777 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1778 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1779 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1780 pAdapter);
1781
1782 if ( eHAL_STATUS_SUCCESS == halStatus )
1783 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301784 char extra[32];
1785 tANI_U8 len = 0;
1786 tANI_U8 mScan = 0;
1787
Rajeev Kumar8b373292014-01-08 20:36:55 -08001788 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1789 "sme_SetBatchScanReq returned success halStatus %d",
1790 halStatus);
1791 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1792 {
1793 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1794 rc = wait_for_completion_timeout(
1795 &pAdapter->hdd_set_batch_scan_req_var,
1796 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1797 if (0 == rc)
1798 {
1799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1800 "%s: Timeout waiting for set batch scan to complete",
1801 __func__);
1802 ret = -EINVAL;
1803 goto exit;
1804 }
1805 }
1806 if ( !pRsp->nScansToBatch )
1807 {
1808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1809 "%s: Received set batch scan failure response from FW",
1810 __func__);
1811 ret = -EINVAL;
1812 goto exit;
1813 }
1814 /*As per the Batch Scan Framework API we should return the MIN of
1815 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301816 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001817
1818 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1819
1820 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1821 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301822 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1823 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1824 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1825 {
1826 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1827 "%s: failed to copy MSCAN value to user buffer", __func__);
1828 ret = -EFAULT;
1829 goto exit;
1830 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001831 }
1832 else
1833 {
1834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1835 "sme_SetBatchScanReq returned failure halStatus %d",
1836 halStatus);
1837 ret = -EINVAL;
1838 goto exit;
1839 }
1840 }
1841 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1842 {
1843 eHalStatus halStatus;
1844 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1845 pInd->param = 0;
1846
1847 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1848 {
1849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1850 "%s: Batch scan feature is not supported by FW", __func__);
1851 ret = -EINVAL;
1852 goto exit;
1853 }
1854
1855 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1856 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001858 "Batch scan is not yet enabled batch scan state %d",
1859 pAdapter->batchScanState);
1860 ret = -EINVAL;
1861 goto exit;
1862 }
1863
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001864 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1865 hdd_deinit_batch_scan(pAdapter);
1866 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1867
Rajeev Kumar8b373292014-01-08 20:36:55 -08001868 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1869
1870 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1871 pAdapter->sessionId);
1872 if ( eHAL_STATUS_SUCCESS == halStatus )
1873 {
1874 ret = 0;
1875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1876 "sme_StopBatchScanInd returned success halStatus %d",
1877 halStatus);
1878 }
1879 else
1880 {
1881 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1882 "sme_StopBatchScanInd returned failure halStatus %d",
1883 halStatus);
1884 ret = -EINVAL;
1885 goto exit;
1886 }
1887 }
1888 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1889 {
1890 tANI_U32 remain_len;
1891
1892 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1893 {
1894 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1895 "%s: Batch scan feature is not supported by FW", __func__);
1896 ret = -EINVAL;
1897 goto exit;
1898 }
1899
1900 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1901 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001903 "Batch scan is not yet enabled could not return results"
1904 "Batch Scan state %d",
1905 pAdapter->batchScanState);
1906 ret = -EINVAL;
1907 goto exit;
1908 }
1909
1910 pPrivdata->used_len = 16;
1911 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1912 if (remain_len < pPrivdata->total_len)
1913 {
1914 /*Clear previous batch scan response data if any*/
1915 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1916 }
1917 else
1918 {
1919 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1920 "Invalid total length from user space can't fetch batch"
1921 " scan response total_len %d used_len %d remain len %d",
1922 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1923 ret = -EINVAL;
1924 goto exit;
1925 }
1926 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1927 }
1928
1929exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301930 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08001931 return ret;
1932}
1933
1934
Rajeev79dbe4c2013-10-05 11:03:42 +05301935#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1936
c_hpothu92367912014-05-01 15:18:17 +05301937static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1938{
c_hpothu39eb1e32014-06-26 16:31:50 +05301939 bcnMissRateContext_t *pCBCtx;
1940
1941 if (NULL == data)
1942 {
1943 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1944 return;
1945 }
c_hpothu92367912014-05-01 15:18:17 +05301946
1947 /* there is a race condition that exists between this callback
1948 function and the caller since the caller could time out either
1949 before or while this code is executing. we use a spinlock to
1950 serialize these actions */
1951 spin_lock(&hdd_context_lock);
1952
c_hpothu39eb1e32014-06-26 16:31:50 +05301953 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301954 gbcnMissRate = -1;
1955
c_hpothu39eb1e32014-06-26 16:31:50 +05301956 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301957 {
1958 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301959 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301960 spin_unlock(&hdd_context_lock);
1961 return ;
1962 }
1963
1964 if (VOS_STATUS_SUCCESS == status)
1965 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301966 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301967 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301968 else
1969 {
1970 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
1971 }
1972
c_hpothu92367912014-05-01 15:18:17 +05301973 complete(&(pCBCtx->completion));
1974 spin_unlock(&hdd_context_lock);
1975
1976 return;
1977}
1978
Abhishek Singh08aa7762014-12-16 13:59:03 +05301979void hdd_FWStatisCB( VOS_STATUS status,
1980 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05301981{
1982 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301983 hdd_adapter_t *pAdapter;
1984
1985 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
1986
Abhishek Singh08aa7762014-12-16 13:59:03 +05301987 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05301988 {
1989 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1990 return;
1991 }
1992 /* there is a race condition that exists between this callback
1993 function and the caller since the caller could time out either
1994 before or while this code is executing. we use a spinlock to
1995 serialize these actions */
1996 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05301997 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301998 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
1999 {
2000 hddLog(VOS_TRACE_LEVEL_ERROR,
2001 FL("invalid context magic: %08x"), fwStatsCtx->magic);
2002 spin_unlock(&hdd_context_lock);
2003 return;
2004 }
2005 pAdapter = fwStatsCtx->pAdapter;
2006 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
2007 {
2008 hddLog(VOS_TRACE_LEVEL_ERROR,
2009 FL("pAdapter returned is NULL or invalid"));
2010 spin_unlock(&hdd_context_lock);
2011 return;
2012 }
2013 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05302014 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05302015 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302016 switch( fwStatsResult->type )
2017 {
2018 case FW_UBSP_STATS:
2019 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302020 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302021 hddLog(VOS_TRACE_LEVEL_INFO,
2022 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302023 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2024 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302025 }
2026 break;
2027 default:
2028 {
2029 hddLog(VOS_TRACE_LEVEL_ERROR,
2030 FL(" No handling for stats type %d"),fwStatsResult->type);
2031 }
2032 }
2033 }
2034 complete(&(fwStatsCtx->completion));
2035 spin_unlock(&hdd_context_lock);
2036 return;
2037}
2038
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302039static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2040{
2041 int ret = 0;
2042
2043 if (!pCfg || !command || !extra || !len)
2044 {
2045 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2046 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2047 ret = -EINVAL;
2048 return ret;
2049 }
2050
2051 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2052 {
2053 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2054 (int)pCfg->nActiveMaxChnTime);
2055 return ret;
2056 }
2057 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2058 {
2059 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2060 (int)pCfg->nActiveMinChnTime);
2061 return ret;
2062 }
2063 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2064 {
2065 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2066 (int)pCfg->nPassiveMaxChnTime);
2067 return ret;
2068 }
2069 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2070 {
2071 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2072 (int)pCfg->nPassiveMinChnTime);
2073 return ret;
2074 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302075 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2076 {
2077 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2078 (int)pCfg->nActiveMaxChnTime);
2079 return ret;
2080 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302081 else
2082 {
2083 ret = -EINVAL;
2084 }
2085
2086 return ret;
2087}
2088
2089static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2090{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302091 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302092 hdd_config_t *pCfg;
2093 tANI_U8 *value = command;
2094 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302095 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302096
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302097 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2098 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302099 {
2100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2101 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2102 ret = -EINVAL;
2103 return ret;
2104 }
2105
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302106 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2107 sme_GetConfigParam(hHal, &smeConfig);
2108
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302109 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2110 {
2111 value = value + 24;
2112 temp = kstrtou32(value, 10, &val);
2113 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2114 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2115 {
2116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2117 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2118 ret = -EFAULT;
2119 return ret;
2120 }
2121 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302122 smeConfig.csrConfig.nActiveMaxChnTime = val;
2123 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302124 }
2125 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2126 {
2127 value = value + 24;
2128 temp = kstrtou32(value, 10, &val);
2129 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2130 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2131 {
2132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2133 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2134 ret = -EFAULT;
2135 return ret;
2136 }
2137 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302138 smeConfig.csrConfig.nActiveMinChnTime = val;
2139 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302140 }
2141 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2142 {
2143 value = value + 25;
2144 temp = kstrtou32(value, 10, &val);
2145 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2146 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2147 {
2148 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2149 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2150 ret = -EFAULT;
2151 return ret;
2152 }
2153 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302154 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2155 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302156 }
2157 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2158 {
2159 value = value + 25;
2160 temp = kstrtou32(value, 10, &val);
2161 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2162 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2163 {
2164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2165 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2166 ret = -EFAULT;
2167 return ret;
2168 }
2169 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302170 smeConfig.csrConfig.nPassiveMinChnTime = val;
2171 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302172 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302173 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2174 {
2175 value = value + 13;
2176 temp = kstrtou32(value, 10, &val);
2177 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2178 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2179 {
2180 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2181 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2182 ret = -EFAULT;
2183 return ret;
2184 }
2185 pCfg->nActiveMaxChnTime = val;
2186 smeConfig.csrConfig.nActiveMaxChnTime = val;
2187 sme_UpdateConfig(hHal, &smeConfig);
2188 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302189 else
2190 {
2191 ret = -EINVAL;
2192 }
2193
2194 return ret;
2195}
2196
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002197static int hdd_driver_command(hdd_adapter_t *pAdapter,
2198 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002199{
Jeff Johnson295189b2012-06-20 16:38:30 -07002200 hdd_priv_data_t priv_data;
2201 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302202 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2203 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002204 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302205 int status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302206
2207 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002208 /*
2209 * Note that valid pointers are provided by caller
2210 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002211
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002212 /* copy to local struct to avoid numerous changes to legacy code */
2213 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002214
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002215 if (priv_data.total_len <= 0 ||
2216 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002217 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002218 hddLog(VOS_TRACE_LEVEL_WARN,
2219 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2220 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002221 ret = -EINVAL;
2222 goto exit;
2223 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302224 status = wlan_hdd_validate_context(pHddCtx);
2225 if (0 != status)
2226 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302227 ret = -EINVAL;
2228 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302229 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002230 /* Allocate +1 for '\0' */
2231 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002232 if (!command)
2233 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002234 hddLog(VOS_TRACE_LEVEL_ERROR,
2235 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002236 ret = -ENOMEM;
2237 goto exit;
2238 }
2239
2240 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2241 {
2242 ret = -EFAULT;
2243 goto exit;
2244 }
2245
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002246 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002247 command[priv_data.total_len] = '\0';
2248
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002249 /* at one time the following block of code was conditional. braces
2250 * have been retained to avoid re-indenting the legacy code
2251 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002252 {
2253 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2254
2255 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002256 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002257
2258 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2259 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302260 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2261 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2262 pAdapter->sessionId, (unsigned)
2263 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2264 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2265 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2266 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002267 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2268 sizeof(tSirMacAddr)))
2269 {
2270 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002271 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002272 ret = -EFAULT;
2273 }
2274 }
Amar Singhal0974e402013-02-12 14:27:46 -08002275 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002276 {
Amar Singhal0974e402013-02-12 14:27:46 -08002277 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002278
Jeff Johnson295189b2012-06-20 16:38:30 -07002279 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002280
2281 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002282 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002284 "%s: SetBandCommand Info comm %s UL %d, TL %d", __func__, command, priv_data.used_len, priv_data.total_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07002285 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002286 ret = hdd_setBand_helper(pAdapter->dev, ptr);
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05302287 if(ret < 0)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302288 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002289 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002290 }
Kiet Lamf040f472013-11-20 21:15:23 +05302291 else if(strncmp(command, "SETWMMPS", 8) == 0)
2292 {
2293 tANI_U8 *ptr = command;
2294 ret = hdd_wmmps_helper(pAdapter, ptr);
2295 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05302296
2297 else if(strncmp(command, "TDLSSCAN", 8) == 0)
2298 {
2299 tANI_U8 *ptr = command;
2300 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
2301 }
2302
Jeff Johnson32d95a32012-09-10 13:15:23 -07002303 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2304 {
2305 char *country_code;
2306
2307 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002308
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002309 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002310 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002311#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302312 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002313#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002314 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2315 (void *)(tSmeChangeCountryCallback)
2316 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302317 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002318 if (eHAL_STATUS_SUCCESS == ret)
2319 {
2320 ret = wait_for_completion_interruptible_timeout(
2321 &pAdapter->change_country_code,
2322 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2323 if (0 >= ret)
2324 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002325 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302326 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002327 }
2328 }
2329 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002330 {
2331 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002332 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002333 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002334 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002335
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002336 }
2337 /*
2338 command should be a string having format
2339 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2340 */
Amar Singhal0974e402013-02-12 14:27:46 -08002341 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002342 {
Amar Singhal0974e402013-02-12 14:27:46 -08002343 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002344
2345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002346 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002347
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002348 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002349 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002350 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2351 {
2352 int suspend = 0;
2353 tANI_U8 *ptr = (tANI_U8*)command + 15;
2354
2355 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302356 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2357 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2358 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002359 hdd_set_wlan_suspend_mode(suspend);
2360 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002361#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2362 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2363 {
2364 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002365 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002366 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2367 eHalStatus status = eHAL_STATUS_SUCCESS;
2368
2369 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2370 value = value + 15;
2371
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002372 /* Convert the value from ascii to integer */
2373 ret = kstrtos8(value, 10, &rssi);
2374 if (ret < 0)
2375 {
2376 /* If the input value is greater than max value of datatype, then also
2377 kstrtou8 fails */
2378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2379 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002380 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002381 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2382 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2383 ret = -EINVAL;
2384 goto exit;
2385 }
2386
Srinivas Girigowdade697412013-02-14 16:31:48 -08002387 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002388
Srinivas Girigowdade697412013-02-14 16:31:48 -08002389 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2390 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2391 {
2392 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2393 "Neighbor lookup threshold value %d is out of range"
2394 " (Min: %d Max: %d)", lookUpThreshold,
2395 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2396 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2397 ret = -EINVAL;
2398 goto exit;
2399 }
2400
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302401 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2402 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2403 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2405 "%s: Received Command to Set Roam trigger"
2406 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2407
2408 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2409 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2410 if (eHAL_STATUS_SUCCESS != status)
2411 {
2412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2413 "%s: Failed to set roam trigger, try again", __func__);
2414 ret = -EPERM;
2415 goto exit;
2416 }
2417
2418 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302419 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002420 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2421 }
2422 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2423 {
2424 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2425 int rssi = (-1) * lookUpThreshold;
2426 char extra[32];
2427 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302428 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2429 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2430 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002431 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002432 if (copy_to_user(priv_data.buf, &extra, len + 1))
2433 {
2434 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2435 "%s: failed to copy data to user buffer", __func__);
2436 ret = -EFAULT;
2437 goto exit;
2438 }
2439 }
2440 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2441 {
2442 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002443 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002444 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002445
Srinivas Girigowdade697412013-02-14 16:31:48 -08002446 /* input refresh period is in terms of seconds */
2447 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2448 value = value + 18;
2449 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002450 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002451 if (ret < 0)
2452 {
2453 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002454 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002456 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002457 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002458 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2459 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002460 ret = -EINVAL;
2461 goto exit;
2462 }
2463
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002464 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2465 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002466 {
2467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002468 "Roam scan period value %d is out of range"
2469 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002470 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2471 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002472 ret = -EINVAL;
2473 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302474 }
2475 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2476 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2477 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002478 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002479
2480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2481 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002482 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002483
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002484 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2485 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002486 }
2487 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2488 {
2489 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2490 char extra[32];
2491 tANI_U8 len = 0;
2492
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302493 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2494 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2495 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002496 len = scnprintf(extra, sizeof(extra), "%s %d",
2497 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002498 /* Returned value is in units of seconds */
2499 if (copy_to_user(priv_data.buf, &extra, len + 1))
2500 {
2501 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2502 "%s: failed to copy data to user buffer", __func__);
2503 ret = -EFAULT;
2504 goto exit;
2505 }
2506 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002507 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2508 {
2509 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002510 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002511 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002512
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002513 /* input refresh period is in terms of seconds */
2514 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2515 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002516
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002517 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002518 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002519 if (ret < 0)
2520 {
2521 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002522 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002523 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002524 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002525 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002526 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2527 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2528 ret = -EINVAL;
2529 goto exit;
2530 }
2531
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002532 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2533 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2534 {
2535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2536 "Neighbor scan results refresh period value %d is out of range"
2537 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2538 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2539 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2540 ret = -EINVAL;
2541 goto exit;
2542 }
2543 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2544
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2546 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002547 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002548
2549 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2550 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2551 }
2552 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2553 {
2554 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2555 char extra[32];
2556 tANI_U8 len = 0;
2557
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002558 len = scnprintf(extra, sizeof(extra), "%s %d",
2559 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002560 /* Returned value is in units of seconds */
2561 if (copy_to_user(priv_data.buf, &extra, len + 1))
2562 {
2563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2564 "%s: failed to copy data to user buffer", __func__);
2565 ret = -EFAULT;
2566 goto exit;
2567 }
2568 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002569#ifdef FEATURE_WLAN_LFR
2570 /* SETROAMMODE */
2571 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2572 {
2573 tANI_U8 *value = command;
2574 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2575
2576 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2577 value = value + SIZE_OF_SETROAMMODE + 1;
2578
2579 /* Convert the value from ascii to integer */
2580 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2581 if (ret < 0)
2582 {
2583 /* If the input value is greater than max value of datatype, then also
2584 kstrtou8 fails */
2585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2586 "%s: kstrtou8 failed range [%d - %d]", __func__,
2587 CFG_LFR_FEATURE_ENABLED_MIN,
2588 CFG_LFR_FEATURE_ENABLED_MAX);
2589 ret = -EINVAL;
2590 goto exit;
2591 }
2592 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2593 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2594 {
2595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2596 "Roam Mode value %d is out of range"
2597 " (Min: %d Max: %d)", roamMode,
2598 CFG_LFR_FEATURE_ENABLED_MIN,
2599 CFG_LFR_FEATURE_ENABLED_MAX);
2600 ret = -EINVAL;
2601 goto exit;
2602 }
2603
2604 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2605 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2606 /*
2607 * Note that
2608 * SETROAMMODE 0 is to enable LFR while
2609 * SETROAMMODE 1 is to disable LFR, but
2610 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2611 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2612 */
2613 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2614 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2615 else
2616 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2617
2618 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2619 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2620 }
2621 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302622 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002623 {
2624 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2625 char extra[32];
2626 tANI_U8 len = 0;
2627
2628 /*
2629 * roamMode value shall be inverted because the sementics is different.
2630 */
2631 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2632 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2633 else
2634 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2635
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002636 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002637 if (copy_to_user(priv_data.buf, &extra, len + 1))
2638 {
2639 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2640 "%s: failed to copy data to user buffer", __func__);
2641 ret = -EFAULT;
2642 goto exit;
2643 }
2644 }
2645#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002646#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002647#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002648 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2649 {
2650 tANI_U8 *value = command;
2651 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2652
2653 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2654 value = value + 13;
2655 /* Convert the value from ascii to integer */
2656 ret = kstrtou8(value, 10, &roamRssiDiff);
2657 if (ret < 0)
2658 {
2659 /* If the input value is greater than max value of datatype, then also
2660 kstrtou8 fails */
2661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2662 "%s: kstrtou8 failed range [%d - %d]", __func__,
2663 CFG_ROAM_RSSI_DIFF_MIN,
2664 CFG_ROAM_RSSI_DIFF_MAX);
2665 ret = -EINVAL;
2666 goto exit;
2667 }
2668
2669 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2670 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2671 {
2672 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2673 "Roam rssi diff value %d is out of range"
2674 " (Min: %d Max: %d)", roamRssiDiff,
2675 CFG_ROAM_RSSI_DIFF_MIN,
2676 CFG_ROAM_RSSI_DIFF_MAX);
2677 ret = -EINVAL;
2678 goto exit;
2679 }
2680
2681 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2682 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2683
2684 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2685 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2686 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302687 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002688 {
2689 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2690 char extra[32];
2691 tANI_U8 len = 0;
2692
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302693 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2694 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2695 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002696 len = scnprintf(extra, sizeof(extra), "%s %d",
2697 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002698 if (copy_to_user(priv_data.buf, &extra, len + 1))
2699 {
2700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2701 "%s: failed to copy data to user buffer", __func__);
2702 ret = -EFAULT;
2703 goto exit;
2704 }
2705 }
2706#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002707#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002708 else if (strncmp(command, "GETBAND", 7) == 0)
2709 {
2710 int band = -1;
2711 char extra[32];
2712 tANI_U8 len = 0;
2713 hdd_getBand_helper(pHddCtx, &band);
2714
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302715 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2716 TRACE_CODE_HDD_GETBAND_IOCTL,
2717 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002718 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002719 if (copy_to_user(priv_data.buf, &extra, len + 1))
2720 {
2721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2722 "%s: failed to copy data to user buffer", __func__);
2723 ret = -EFAULT;
2724 goto exit;
2725 }
2726 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002727 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2728 {
2729 tANI_U8 *value = command;
2730 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2731 tANI_U8 numChannels = 0;
2732 eHalStatus status = eHAL_STATUS_SUCCESS;
2733
2734 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2735 if (eHAL_STATUS_SUCCESS != status)
2736 {
2737 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2738 "%s: Failed to parse channel list information", __func__);
2739 ret = -EINVAL;
2740 goto exit;
2741 }
2742
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302743 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2744 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2745 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002746 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2747 {
2748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2749 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2750 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2751 ret = -EINVAL;
2752 goto exit;
2753 }
2754 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2755 numChannels);
2756 if (eHAL_STATUS_SUCCESS != status)
2757 {
2758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2759 "%s: Failed to update channel list information", __func__);
2760 ret = -EINVAL;
2761 goto exit;
2762 }
2763 }
2764 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2765 {
2766 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2767 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002768 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002769 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002770 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002771
2772 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2773 ChannelList, &numChannels ))
2774 {
2775 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2776 "%s: failed to get roam scan channel list", __func__);
2777 ret = -EFAULT;
2778 goto exit;
2779 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302780 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2781 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2782 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002783 /* output channel list is of the format
2784 [Number of roam scan channels][Channel1][Channel2]... */
2785 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002786 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002787 for (j = 0; (j < numChannels); j++)
2788 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002789 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2790 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002791 }
2792
2793 if (copy_to_user(priv_data.buf, &extra, len + 1))
2794 {
2795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2796 "%s: failed to copy data to user buffer", __func__);
2797 ret = -EFAULT;
2798 goto exit;
2799 }
2800 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002801 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2802 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002803 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002804 char extra[32];
2805 tANI_U8 len = 0;
2806
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002807 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002808 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002809 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002810 hdd_is_okc_mode_enabled(pHddCtx) &&
2811 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2812 {
2813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002814 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002815 " hence this operation is not permitted!", __func__);
2816 ret = -EPERM;
2817 goto exit;
2818 }
2819
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002820 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002821 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002822 if (copy_to_user(priv_data.buf, &extra, len + 1))
2823 {
2824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2825 "%s: failed to copy data to user buffer", __func__);
2826 ret = -EFAULT;
2827 goto exit;
2828 }
2829 }
2830 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2831 {
2832 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2833 char extra[32];
2834 tANI_U8 len = 0;
2835
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002836 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002837 then this operation is not permitted (return FAILURE) */
2838 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002839 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002840 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2841 {
2842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002843 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002844 " hence this operation is not permitted!", __func__);
2845 ret = -EPERM;
2846 goto exit;
2847 }
2848
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002849 len = scnprintf(extra, sizeof(extra), "%s %d",
2850 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002851 if (copy_to_user(priv_data.buf, &extra, len + 1))
2852 {
2853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2854 "%s: failed to copy data to user buffer", __func__);
2855 ret = -EFAULT;
2856 goto exit;
2857 }
2858 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002859 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002860 {
2861 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2862 char extra[32];
2863 tANI_U8 len = 0;
2864
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002865 len = scnprintf(extra, sizeof(extra), "%s %d",
2866 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002867 if (copy_to_user(priv_data.buf, &extra, len + 1))
2868 {
2869 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2870 "%s: failed to copy data to user buffer", __func__);
2871 ret = -EFAULT;
2872 goto exit;
2873 }
2874 }
2875 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2876 {
2877 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2878 char extra[32];
2879 tANI_U8 len = 0;
2880
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002881 len = scnprintf(extra, sizeof(extra), "%s %d",
2882 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002883 if (copy_to_user(priv_data.buf, &extra, len + 1))
2884 {
2885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2886 "%s: failed to copy data to user buffer", __func__);
2887 ret = -EFAULT;
2888 goto exit;
2889 }
2890 }
2891 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2892 {
2893 tANI_U8 *value = command;
2894 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2895
2896 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2897 value = value + 26;
2898 /* Convert the value from ascii to integer */
2899 ret = kstrtou8(value, 10, &minTime);
2900 if (ret < 0)
2901 {
2902 /* If the input value is greater than max value of datatype, then also
2903 kstrtou8 fails */
2904 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2905 "%s: kstrtou8 failed range [%d - %d]", __func__,
2906 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2907 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2908 ret = -EINVAL;
2909 goto exit;
2910 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002911 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2912 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2913 {
2914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2915 "scan min channel time value %d is out of range"
2916 " (Min: %d Max: %d)", minTime,
2917 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2918 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2919 ret = -EINVAL;
2920 goto exit;
2921 }
2922
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302923 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2924 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2925 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2927 "%s: Received Command to change channel min time = %d", __func__, minTime);
2928
2929 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2930 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2931 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002932 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2933 {
2934 tANI_U8 *value = command;
2935 tANI_U8 channel = 0;
2936 tANI_U8 dwellTime = 0;
2937 tANI_U8 bufLen = 0;
2938 tANI_U8 *buf = NULL;
2939 tSirMacAddr targetApBssid;
2940 eHalStatus status = eHAL_STATUS_SUCCESS;
2941 struct ieee80211_channel chan;
2942 tANI_U8 finalLen = 0;
2943 tANI_U8 *finalBuf = NULL;
2944 tANI_U8 temp = 0;
2945 u64 cookie;
2946 hdd_station_ctx_t *pHddStaCtx = NULL;
2947 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2948
2949 /* if not associated, no need to send action frame */
2950 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2951 {
2952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2953 ret = -EINVAL;
2954 goto exit;
2955 }
2956
2957 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2958 &dwellTime, &buf, &bufLen);
2959 if (eHAL_STATUS_SUCCESS != status)
2960 {
2961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2962 "%s: Failed to parse send action frame data", __func__);
2963 ret = -EINVAL;
2964 goto exit;
2965 }
2966
2967 /* if the target bssid is different from currently associated AP,
2968 then no need to send action frame */
2969 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2970 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2971 {
2972 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2973 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002974 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002975 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002976 goto exit;
2977 }
2978
2979 /* if the channel number is different from operating channel then
2980 no need to send action frame */
2981 if (channel != pHddStaCtx->conn_info.operationChannel)
2982 {
2983 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2984 "%s: channel(%d) is different from operating channel(%d)",
2985 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2986 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002987 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002988 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002989 goto exit;
2990 }
2991 chan.center_freq = sme_ChnToFreq(channel);
2992
2993 finalLen = bufLen + 24;
2994 finalBuf = vos_mem_malloc(finalLen);
2995 if (NULL == finalBuf)
2996 {
2997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2998 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002999 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003000 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003001 goto exit;
3002 }
3003 vos_mem_zero(finalBuf, finalLen);
3004
3005 /* Fill subtype */
3006 temp = SIR_MAC_MGMT_ACTION << 4;
3007 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3008
3009 /* Fill type */
3010 temp = SIR_MAC_MGMT_FRAME;
3011 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3012
3013 /* Fill destination address (bssid of the AP) */
3014 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3015
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003016 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003017 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3018
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003019 /* Fill BSSID (AP mac address) */
3020 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003021
3022 /* Fill received buffer from 24th address */
3023 vos_mem_copy(finalBuf + 24, buf, bufLen);
3024
Jeff Johnson11c33152013-04-16 17:52:40 -07003025 /* done with the parsed buffer */
3026 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003027 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003028
DARAM SUDHA39eede62014-02-12 11:16:40 +05303029 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003030#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3031 &(pAdapter->wdev),
3032#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003033 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003034#endif
3035 &chan, 0,
3036#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3037 NL80211_CHAN_HT20, 1,
3038#endif
3039 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003040 1, &cookie );
3041 vos_mem_free(finalBuf);
3042 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003043 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3044 {
3045 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3046 char extra[32];
3047 tANI_U8 len = 0;
3048
3049 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003050 len = scnprintf(extra, sizeof(extra), "%s %d",
3051 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303052 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3053 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3054 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003055 if (copy_to_user(priv_data.buf, &extra, len + 1))
3056 {
3057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3058 "%s: failed to copy data to user buffer", __func__);
3059 ret = -EFAULT;
3060 goto exit;
3061 }
3062 }
3063 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3064 {
3065 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003066 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003067
3068 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3069 value = value + 19;
3070 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003071 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003072 if (ret < 0)
3073 {
3074 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003075 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003076 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003077 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003078 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3079 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3080 ret = -EINVAL;
3081 goto exit;
3082 }
3083
3084 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3085 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3086 {
3087 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3088 "lfr mode value %d is out of range"
3089 " (Min: %d Max: %d)", maxTime,
3090 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3091 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3092 ret = -EINVAL;
3093 goto exit;
3094 }
3095
3096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3097 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3098
3099 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3100 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3101 }
3102 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3103 {
3104 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3105 char extra[32];
3106 tANI_U8 len = 0;
3107
3108 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003109 len = scnprintf(extra, sizeof(extra), "%s %d",
3110 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003111 if (copy_to_user(priv_data.buf, &extra, len + 1))
3112 {
3113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3114 "%s: failed to copy data to user buffer", __func__);
3115 ret = -EFAULT;
3116 goto exit;
3117 }
3118 }
3119 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3120 {
3121 tANI_U8 *value = command;
3122 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3123
3124 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3125 value = value + 16;
3126 /* Convert the value from ascii to integer */
3127 ret = kstrtou16(value, 10, &val);
3128 if (ret < 0)
3129 {
3130 /* If the input value is greater than max value of datatype, then also
3131 kstrtou16 fails */
3132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3133 "%s: kstrtou16 failed range [%d - %d]", __func__,
3134 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3135 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3136 ret = -EINVAL;
3137 goto exit;
3138 }
3139
3140 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3141 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3142 {
3143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3144 "scan home time value %d is out of range"
3145 " (Min: %d Max: %d)", val,
3146 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3147 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3148 ret = -EINVAL;
3149 goto exit;
3150 }
3151
3152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3153 "%s: Received Command to change scan home time = %d", __func__, val);
3154
3155 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3156 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3157 }
3158 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3159 {
3160 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3161 char extra[32];
3162 tANI_U8 len = 0;
3163
3164 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003165 len = scnprintf(extra, sizeof(extra), "%s %d",
3166 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003167 if (copy_to_user(priv_data.buf, &extra, len + 1))
3168 {
3169 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3170 "%s: failed to copy data to user buffer", __func__);
3171 ret = -EFAULT;
3172 goto exit;
3173 }
3174 }
3175 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3176 {
3177 tANI_U8 *value = command;
3178 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3179
3180 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3181 value = value + 17;
3182 /* Convert the value from ascii to integer */
3183 ret = kstrtou8(value, 10, &val);
3184 if (ret < 0)
3185 {
3186 /* If the input value is greater than max value of datatype, then also
3187 kstrtou8 fails */
3188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3189 "%s: kstrtou8 failed range [%d - %d]", __func__,
3190 CFG_ROAM_INTRA_BAND_MIN,
3191 CFG_ROAM_INTRA_BAND_MAX);
3192 ret = -EINVAL;
3193 goto exit;
3194 }
3195
3196 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3197 (val > CFG_ROAM_INTRA_BAND_MAX))
3198 {
3199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3200 "intra band mode value %d is out of range"
3201 " (Min: %d Max: %d)", val,
3202 CFG_ROAM_INTRA_BAND_MIN,
3203 CFG_ROAM_INTRA_BAND_MAX);
3204 ret = -EINVAL;
3205 goto exit;
3206 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3208 "%s: Received Command to change intra band = %d", __func__, val);
3209
3210 pHddCtx->cfg_ini->nRoamIntraBand = val;
3211 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3212 }
3213 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3214 {
3215 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3216 char extra[32];
3217 tANI_U8 len = 0;
3218
3219 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003220 len = scnprintf(extra, sizeof(extra), "%s %d",
3221 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003222 if (copy_to_user(priv_data.buf, &extra, len + 1))
3223 {
3224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3225 "%s: failed to copy data to user buffer", __func__);
3226 ret = -EFAULT;
3227 goto exit;
3228 }
3229 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003230 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3231 {
3232 tANI_U8 *value = command;
3233 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3234
3235 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3236 value = value + 15;
3237 /* Convert the value from ascii to integer */
3238 ret = kstrtou8(value, 10, &nProbes);
3239 if (ret < 0)
3240 {
3241 /* If the input value is greater than max value of datatype, then also
3242 kstrtou8 fails */
3243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3244 "%s: kstrtou8 failed range [%d - %d]", __func__,
3245 CFG_ROAM_SCAN_N_PROBES_MIN,
3246 CFG_ROAM_SCAN_N_PROBES_MAX);
3247 ret = -EINVAL;
3248 goto exit;
3249 }
3250
3251 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3252 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3253 {
3254 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3255 "NProbes value %d is out of range"
3256 " (Min: %d Max: %d)", nProbes,
3257 CFG_ROAM_SCAN_N_PROBES_MIN,
3258 CFG_ROAM_SCAN_N_PROBES_MAX);
3259 ret = -EINVAL;
3260 goto exit;
3261 }
3262
3263 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3264 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3265
3266 pHddCtx->cfg_ini->nProbes = nProbes;
3267 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3268 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303269 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003270 {
3271 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3272 char extra[32];
3273 tANI_U8 len = 0;
3274
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003275 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003276 if (copy_to_user(priv_data.buf, &extra, len + 1))
3277 {
3278 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3279 "%s: failed to copy data to user buffer", __func__);
3280 ret = -EFAULT;
3281 goto exit;
3282 }
3283 }
3284 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3285 {
3286 tANI_U8 *value = command;
3287 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3288
3289 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3290 /* input value is in units of msec */
3291 value = value + 20;
3292 /* Convert the value from ascii to integer */
3293 ret = kstrtou16(value, 10, &homeAwayTime);
3294 if (ret < 0)
3295 {
3296 /* If the input value is greater than max value of datatype, then also
3297 kstrtou8 fails */
3298 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3299 "%s: kstrtou8 failed range [%d - %d]", __func__,
3300 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3301 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3302 ret = -EINVAL;
3303 goto exit;
3304 }
3305
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003306 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3307 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3308 {
3309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3310 "homeAwayTime value %d is out of range"
3311 " (Min: %d Max: %d)", homeAwayTime,
3312 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3313 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3314 ret = -EINVAL;
3315 goto exit;
3316 }
3317
3318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3319 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003320 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3321 {
3322 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3323 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3324 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003325 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303326 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003327 {
3328 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3329 char extra[32];
3330 tANI_U8 len = 0;
3331
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003332 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003333 if (copy_to_user(priv_data.buf, &extra, len + 1))
3334 {
3335 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3336 "%s: failed to copy data to user buffer", __func__);
3337 ret = -EFAULT;
3338 goto exit;
3339 }
3340 }
3341 else if (strncmp(command, "REASSOC", 7) == 0)
3342 {
3343 tANI_U8 *value = command;
3344 tANI_U8 channel = 0;
3345 tSirMacAddr targetApBssid;
3346 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003347#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3348 tCsrHandoffRequest handoffInfo;
3349#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003350 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003351 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3352
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003353 /* if not associated, no need to proceed with reassoc */
3354 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3355 {
3356 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3357 ret = -EINVAL;
3358 goto exit;
3359 }
3360
3361 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3362 if (eHAL_STATUS_SUCCESS != status)
3363 {
3364 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3365 "%s: Failed to parse reassoc command data", __func__);
3366 ret = -EINVAL;
3367 goto exit;
3368 }
3369
3370 /* if the target bssid is same as currently associated AP,
3371 then no need to proceed with reassoc */
3372 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3373 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3374 {
3375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3376 ret = -EINVAL;
3377 goto exit;
3378 }
3379
3380 /* Check channel number is a valid channel number */
3381 if(VOS_STATUS_SUCCESS !=
3382 wlan_hdd_validate_operation_channel(pAdapter, channel))
3383 {
3384 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003385 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003386 return -EINVAL;
3387 }
3388
3389 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003390#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3391 handoffInfo.channel = channel;
3392 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3393 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3394#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003395 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003396 else if (strncmp(command, "SETWESMODE", 10) == 0)
3397 {
3398 tANI_U8 *value = command;
3399 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3400
3401 /* Move pointer to ahead of SETWESMODE<delimiter> */
3402 value = value + 11;
3403 /* Convert the value from ascii to integer */
3404 ret = kstrtou8(value, 10, &wesMode);
3405 if (ret < 0)
3406 {
3407 /* If the input value is greater than max value of datatype, then also
3408 kstrtou8 fails */
3409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3410 "%s: kstrtou8 failed range [%d - %d]", __func__,
3411 CFG_ENABLE_WES_MODE_NAME_MIN,
3412 CFG_ENABLE_WES_MODE_NAME_MAX);
3413 ret = -EINVAL;
3414 goto exit;
3415 }
3416
3417 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3418 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3419 {
3420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3421 "WES Mode value %d is out of range"
3422 " (Min: %d Max: %d)", wesMode,
3423 CFG_ENABLE_WES_MODE_NAME_MIN,
3424 CFG_ENABLE_WES_MODE_NAME_MAX);
3425 ret = -EINVAL;
3426 goto exit;
3427 }
3428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3429 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3430
3431 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3432 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3433 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303434 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003435 {
3436 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3437 char extra[32];
3438 tANI_U8 len = 0;
3439
Arif Hussain826d9412013-11-12 16:44:54 -08003440 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003441 if (copy_to_user(priv_data.buf, &extra, len + 1))
3442 {
3443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3444 "%s: failed to copy data to user buffer", __func__);
3445 ret = -EFAULT;
3446 goto exit;
3447 }
3448 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003449#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003450#ifdef FEATURE_WLAN_LFR
3451 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3452 {
3453 tANI_U8 *value = command;
3454 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3455
3456 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3457 value = value + 12;
3458 /* Convert the value from ascii to integer */
3459 ret = kstrtou8(value, 10, &lfrMode);
3460 if (ret < 0)
3461 {
3462 /* If the input value is greater than max value of datatype, then also
3463 kstrtou8 fails */
3464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3465 "%s: kstrtou8 failed range [%d - %d]", __func__,
3466 CFG_LFR_FEATURE_ENABLED_MIN,
3467 CFG_LFR_FEATURE_ENABLED_MAX);
3468 ret = -EINVAL;
3469 goto exit;
3470 }
3471
3472 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3473 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3474 {
3475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3476 "lfr mode value %d is out of range"
3477 " (Min: %d Max: %d)", lfrMode,
3478 CFG_LFR_FEATURE_ENABLED_MIN,
3479 CFG_LFR_FEATURE_ENABLED_MAX);
3480 ret = -EINVAL;
3481 goto exit;
3482 }
3483
3484 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3485 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3486
3487 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3488 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3489 }
3490#endif
3491#ifdef WLAN_FEATURE_VOWIFI_11R
3492 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3493 {
3494 tANI_U8 *value = command;
3495 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3496
3497 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3498 value = value + 18;
3499 /* Convert the value from ascii to integer */
3500 ret = kstrtou8(value, 10, &ft);
3501 if (ret < 0)
3502 {
3503 /* If the input value is greater than max value of datatype, then also
3504 kstrtou8 fails */
3505 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3506 "%s: kstrtou8 failed range [%d - %d]", __func__,
3507 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3508 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3509 ret = -EINVAL;
3510 goto exit;
3511 }
3512
3513 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3514 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3515 {
3516 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3517 "ft mode value %d is out of range"
3518 " (Min: %d Max: %d)", ft,
3519 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3520 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3521 ret = -EINVAL;
3522 goto exit;
3523 }
3524
3525 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3526 "%s: Received Command to change ft mode = %d", __func__, ft);
3527
3528 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3529 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3530 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303531 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
3532 {
3533 tANI_U8 *value = command;
3534 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303535
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303536 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
3537 value = value + 15;
3538 /* Convert the value from ascii to integer */
3539 ret = kstrtou8(value, 10, &dfsScanMode);
3540 if (ret < 0)
3541 {
3542 /* If the input value is greater than max value of
3543 datatype, then also kstrtou8 fails
3544 */
3545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3546 "%s: kstrtou8 failed range [%d - %d]", __func__,
3547 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3548 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3549 ret = -EINVAL;
3550 goto exit;
3551 }
3552
3553 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
3554 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
3555 {
3556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3557 "dfsScanMode value %d is out of range"
3558 " (Min: %d Max: %d)", dfsScanMode,
3559 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3560 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3561 ret = -EINVAL;
3562 goto exit;
3563 }
3564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3565 "%s: Received Command to Set DFS Scan Mode = %d",
3566 __func__, dfsScanMode);
3567
3568 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
3569 }
3570 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
3571 {
3572 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
3573 char extra[32];
3574 tANI_U8 len = 0;
3575
3576 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
3577 if (copy_to_user(priv_data.buf, &extra, len + 1))
3578 {
3579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3580 "%s: failed to copy data to user buffer", __func__);
3581 ret = -EFAULT;
3582 goto exit;
3583 }
3584 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303585 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3586 {
3587 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303588 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303589 tSirMacAddr targetApBssid;
3590 tANI_U8 trigger = 0;
3591 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303592 tHalHandle hHal;
3593 v_U32_t roamId = 0;
3594 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303595 hdd_station_ctx_t *pHddStaCtx = NULL;
3596 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303597 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303598
3599 /* if not associated, no need to proceed with reassoc */
3600 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3601 {
3602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3603 ret = -EINVAL;
3604 goto exit;
3605 }
3606
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303607 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303608 if (eHAL_STATUS_SUCCESS != status)
3609 {
3610 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3611 "%s: Failed to parse reassoc command data", __func__);
3612 ret = -EINVAL;
3613 goto exit;
3614 }
3615
3616 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303617 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303618 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3619 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3620 {
3621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3622 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3623 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303624 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3625 &modProfileFields);
3626 sme_RoamReassoc(hHal, pAdapter->sessionId,
3627 NULL, modProfileFields, &roamId, 1);
3628 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303629 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303630
3631 /* Check channel number is a valid channel number */
3632 if(VOS_STATUS_SUCCESS !=
3633 wlan_hdd_validate_operation_channel(pAdapter, channel))
3634 {
3635 hddLog(VOS_TRACE_LEVEL_ERROR,
3636 "%s: Invalid Channel [%d]", __func__, channel);
3637 return -EINVAL;
3638 }
3639
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303640 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303641
3642 /* Proceed with scan/roam */
3643 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3644 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303645 (tSmeFastRoamTrigger)(trigger),
3646 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303647 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003648#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003649#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003650 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3651 {
3652 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003653 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003654
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003655 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003656 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003657 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003658 hdd_is_okc_mode_enabled(pHddCtx) &&
3659 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3660 {
3661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003662 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003663 " hence this operation is not permitted!", __func__);
3664 ret = -EPERM;
3665 goto exit;
3666 }
3667
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003668 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3669 value = value + 11;
3670 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003671 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003672 if (ret < 0)
3673 {
3674 /* If the input value is greater than max value of datatype, then also
3675 kstrtou8 fails */
3676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3677 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003678 CFG_ESE_FEATURE_ENABLED_MIN,
3679 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003680 ret = -EINVAL;
3681 goto exit;
3682 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003683 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3684 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003685 {
3686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003687 "Ese mode value %d is out of range"
3688 " (Min: %d Max: %d)", eseMode,
3689 CFG_ESE_FEATURE_ENABLED_MIN,
3690 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003691 ret = -EINVAL;
3692 goto exit;
3693 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003694 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003695 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003696
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003697 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3698 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003699 }
3700#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003701 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3702 {
3703 tANI_U8 *value = command;
3704 tANI_BOOLEAN roamScanControl = 0;
3705
3706 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3707 value = value + 19;
3708 /* Convert the value from ascii to integer */
3709 ret = kstrtou8(value, 10, &roamScanControl);
3710 if (ret < 0)
3711 {
3712 /* If the input value is greater than max value of datatype, then also
3713 kstrtou8 fails */
3714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3715 "%s: kstrtou8 failed ", __func__);
3716 ret = -EINVAL;
3717 goto exit;
3718 }
3719
3720 if (0 != roamScanControl)
3721 {
3722 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3723 "roam scan control invalid value = %d",
3724 roamScanControl);
3725 ret = -EINVAL;
3726 goto exit;
3727 }
3728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3729 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3730
3731 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3732 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003733#ifdef FEATURE_WLAN_OKC
3734 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3735 {
3736 tANI_U8 *value = command;
3737 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3738
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003739 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003740 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003741 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003742 hdd_is_okc_mode_enabled(pHddCtx) &&
3743 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3744 {
3745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003746 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003747 " hence this operation is not permitted!", __func__);
3748 ret = -EPERM;
3749 goto exit;
3750 }
3751
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003752 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3753 value = value + 11;
3754 /* Convert the value from ascii to integer */
3755 ret = kstrtou8(value, 10, &okcMode);
3756 if (ret < 0)
3757 {
3758 /* If the input value is greater than max value of datatype, then also
3759 kstrtou8 fails */
3760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3761 "%s: kstrtou8 failed range [%d - %d]", __func__,
3762 CFG_OKC_FEATURE_ENABLED_MIN,
3763 CFG_OKC_FEATURE_ENABLED_MAX);
3764 ret = -EINVAL;
3765 goto exit;
3766 }
3767
3768 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3769 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3770 {
3771 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3772 "Okc mode value %d is out of range"
3773 " (Min: %d Max: %d)", okcMode,
3774 CFG_OKC_FEATURE_ENABLED_MIN,
3775 CFG_OKC_FEATURE_ENABLED_MAX);
3776 ret = -EINVAL;
3777 goto exit;
3778 }
3779
3780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3781 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3782
3783 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3784 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003785#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303786 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003787 {
3788 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3789 char extra[32];
3790 tANI_U8 len = 0;
3791
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003792 len = scnprintf(extra, sizeof(extra), "%s %d",
3793 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003794 if (copy_to_user(priv_data.buf, &extra, len + 1))
3795 {
3796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3797 "%s: failed to copy data to user buffer", __func__);
3798 ret = -EFAULT;
3799 goto exit;
3800 }
3801 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303802#ifdef WLAN_FEATURE_PACKET_FILTERING
3803 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3804 {
3805 tANI_U8 filterType = 0;
3806 tANI_U8 *value = command;
3807
3808 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3809 value = value + 22;
3810
3811 /* Convert the value from ascii to integer */
3812 ret = kstrtou8(value, 10, &filterType);
3813 if (ret < 0)
3814 {
3815 /* If the input value is greater than max value of datatype,
3816 * then also kstrtou8 fails
3817 */
3818 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3819 "%s: kstrtou8 failed range ", __func__);
3820 ret = -EINVAL;
3821 goto exit;
3822 }
3823
3824 if (filterType != 0 && filterType != 1)
3825 {
3826 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3827 "%s: Accepted Values are 0 and 1 ", __func__);
3828 ret = -EINVAL;
3829 goto exit;
3830 }
3831 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3832 pAdapter->sessionId);
3833 }
3834#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303835 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3836 {
Kiet Lamad161252014-07-22 11:23:32 -07003837 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303838 int ret;
3839
Kiet Lamad161252014-07-22 11:23:32 -07003840 dhcpPhase = command + 11;
3841 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303842 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003844 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303845
3846 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003847
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303848 ret = wlan_hdd_scan_abort(pAdapter);
3849 if (ret < 0)
3850 {
3851 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3852 FL("failed to abort existing scan %d"), ret);
3853 }
3854
Kiet Lamad161252014-07-22 11:23:32 -07003855 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3856 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303857 }
Kiet Lamad161252014-07-22 11:23:32 -07003858 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303859 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003861 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303862
3863 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003864
3865 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3866 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303867 }
3868 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003869 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3870 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303871 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3872 FL("making default scan to ACTIVE"));
3873 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003874 }
3875 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3876 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3878 FL("making default scan to PASSIVE"));
3879 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003880 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303881 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3882 {
3883 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3884 char extra[32];
3885 tANI_U8 len = 0;
3886
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303887 memset(extra, 0, sizeof(extra));
3888 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3889 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303890 {
3891 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3892 "%s: failed to copy data to user buffer", __func__);
3893 ret = -EFAULT;
3894 goto exit;
3895 }
3896 ret = len;
3897 }
3898 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3899 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303900 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303901 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003902 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3903 {
3904 tANI_U8 filterType = 0;
3905 tANI_U8 *value;
3906 value = command + 9;
3907
3908 /* Convert the value from ascii to integer */
3909 ret = kstrtou8(value, 10, &filterType);
3910 if (ret < 0)
3911 {
3912 /* If the input value is greater than max value of datatype,
3913 * then also kstrtou8 fails
3914 */
3915 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3916 "%s: kstrtou8 failed range ", __func__);
3917 ret = -EINVAL;
3918 goto exit;
3919 }
3920 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3921 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3922 {
3923 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3924 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3925 " 2-Sink ", __func__);
3926 ret = -EINVAL;
3927 goto exit;
3928 }
3929 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3930 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303931 pScanInfo = &pHddCtx->scan_info;
3932 if (filterType && pScanInfo != NULL &&
3933 pHddCtx->scan_info.mScanPending)
3934 {
3935 /*Miracast Session started. Abort Scan */
3936 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3937 "%s, Aborting Scan For Miracast",__func__);
3938 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3939 eCSR_SCAN_ABORT_DEFAULT);
3940 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003941 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303942 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003943 }
Leo Chang614d2072013-08-22 14:59:44 -07003944 else if (strncmp(command, "SETMCRATE", 9) == 0)
3945 {
Leo Chang614d2072013-08-22 14:59:44 -07003946 tANI_U8 *value = command;
3947 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003948 tSirRateUpdateInd *rateUpdate;
3949 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003950
3951 /* Only valid for SAP mode */
3952 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3953 {
3954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3955 "%s: SAP mode is not running", __func__);
3956 ret = -EFAULT;
3957 goto exit;
3958 }
3959
3960 /* Move pointer to ahead of SETMCRATE<delimiter> */
3961 /* input value is in units of hundred kbps */
3962 value = value + 10;
3963 /* Convert the value from ascii to integer, decimal base */
3964 ret = kstrtouint(value, 10, &targetRate);
3965
Leo Chang1f98cbd2013-10-17 15:03:52 -07003966 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3967 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003968 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003969 hddLog(VOS_TRACE_LEVEL_ERROR,
3970 "%s: SETMCRATE indication alloc fail", __func__);
3971 ret = -EFAULT;
3972 goto exit;
3973 }
3974 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3975
3976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3977 "MC Target rate %d", targetRate);
3978 /* Ignore unicast */
3979 rateUpdate->ucastDataRate = -1;
3980 rateUpdate->mcastDataRate24GHz = targetRate;
3981 rateUpdate->mcastDataRate5GHz = targetRate;
3982 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3983 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3984 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3985 if (eHAL_STATUS_SUCCESS != status)
3986 {
3987 hddLog(VOS_TRACE_LEVEL_ERROR,
3988 "%s: SET_MC_RATE failed", __func__);
3989 vos_mem_free(rateUpdate);
3990 ret = -EFAULT;
3991 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003992 }
3993 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303994#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003995 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303996 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003997 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303998 }
3999#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004000#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004001 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
4002 {
4003 tANI_U8 *value = command;
4004 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4005 tANI_U8 numChannels = 0;
4006 eHalStatus status = eHAL_STATUS_SUCCESS;
4007
4008 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4009 if (eHAL_STATUS_SUCCESS != status)
4010 {
4011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4012 "%s: Failed to parse channel list information", __func__);
4013 ret = -EINVAL;
4014 goto exit;
4015 }
4016
4017 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4018 {
4019 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4020 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4021 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4022 ret = -EINVAL;
4023 goto exit;
4024 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004025 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004026 ChannelList,
4027 numChannels);
4028 if (eHAL_STATUS_SUCCESS != status)
4029 {
4030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4031 "%s: Failed to update channel list information", __func__);
4032 ret = -EINVAL;
4033 goto exit;
4034 }
4035 }
4036 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
4037 {
4038 tANI_U8 *value = command;
4039 char extra[128] = {0};
4040 int len = 0;
4041 tANI_U8 tid = 0;
4042 hdd_station_ctx_t *pHddStaCtx = NULL;
4043 tAniTrafStrmMetrics tsmMetrics;
4044 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4045
4046 /* if not associated, return error */
4047 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4048 {
4049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
4050 ret = -EINVAL;
4051 goto exit;
4052 }
4053
4054 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
4055 value = value + 12;
4056 /* Convert the value from ascii to integer */
4057 ret = kstrtou8(value, 10, &tid);
4058 if (ret < 0)
4059 {
4060 /* If the input value is greater than max value of datatype, then also
4061 kstrtou8 fails */
4062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4063 "%s: kstrtou8 failed range [%d - %d]", __func__,
4064 TID_MIN_VALUE,
4065 TID_MAX_VALUE);
4066 ret = -EINVAL;
4067 goto exit;
4068 }
4069
4070 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4071 {
4072 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4073 "tid value %d is out of range"
4074 " (Min: %d Max: %d)", tid,
4075 TID_MIN_VALUE,
4076 TID_MAX_VALUE);
4077 ret = -EINVAL;
4078 goto exit;
4079 }
4080
4081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4082 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4083
4084 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4085 {
4086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4087 "%s: failed to get tsm stats", __func__);
4088 ret = -EFAULT;
4089 goto exit;
4090 }
4091
4092 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4093 "UplinkPktQueueDly(%d)\n"
4094 "UplinkPktQueueDlyHist[0](%d)\n"
4095 "UplinkPktQueueDlyHist[1](%d)\n"
4096 "UplinkPktQueueDlyHist[2](%d)\n"
4097 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304098 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004099 "UplinkPktLoss(%d)\n"
4100 "UplinkPktCount(%d)\n"
4101 "RoamingCount(%d)\n"
4102 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4103 tsmMetrics.UplinkPktQueueDlyHist[0],
4104 tsmMetrics.UplinkPktQueueDlyHist[1],
4105 tsmMetrics.UplinkPktQueueDlyHist[2],
4106 tsmMetrics.UplinkPktQueueDlyHist[3],
4107 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4108 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4109
4110 /* Output TSM stats is of the format
4111 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4112 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004113 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004114 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4115 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4116 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4117 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4118 tsmMetrics.RoamingDly);
4119
4120 if (copy_to_user(priv_data.buf, &extra, len + 1))
4121 {
4122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4123 "%s: failed to copy data to user buffer", __func__);
4124 ret = -EFAULT;
4125 goto exit;
4126 }
4127 }
4128 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4129 {
4130 tANI_U8 *value = command;
4131 tANI_U8 *cckmIe = NULL;
4132 tANI_U8 cckmIeLen = 0;
4133 eHalStatus status = eHAL_STATUS_SUCCESS;
4134
4135 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4136 if (eHAL_STATUS_SUCCESS != status)
4137 {
4138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4139 "%s: Failed to parse cckm ie data", __func__);
4140 ret = -EINVAL;
4141 goto exit;
4142 }
4143
4144 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4145 {
4146 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4147 "%s: CCKM Ie input length is more than max[%d]", __func__,
4148 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004149 vos_mem_free(cckmIe);
4150 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004151 ret = -EINVAL;
4152 goto exit;
4153 }
4154 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004155 vos_mem_free(cckmIe);
4156 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004157 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004158 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4159 {
4160 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004161 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004162 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004163
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004164 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004165 if (eHAL_STATUS_SUCCESS != status)
4166 {
4167 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004168 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004169 ret = -EINVAL;
4170 goto exit;
4171 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004172 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4173 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4174 hdd_indicateEseBcnReportNoResults (pAdapter,
4175 eseBcnReq.bcnReq[0].measurementToken,
4176 0x02, //BIT(1) set for measurement done
4177 0); // no BSS
4178 goto exit;
4179 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004180
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004181 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4182 if (eHAL_STATUS_SUCCESS != status)
4183 {
4184 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4185 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4186 ret = -EINVAL;
4187 goto exit;
4188 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004189 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004190#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304191 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4192 {
4193 eHalStatus status;
4194 char buf[32], len;
4195 long waitRet;
4196 bcnMissRateContext_t getBcnMissRateCtx;
4197
4198 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4199
4200 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4201 {
4202 hddLog(VOS_TRACE_LEVEL_WARN,
4203 FL("GETBCNMISSRATE: STA is not in connected state"));
4204 ret = -1;
4205 goto exit;
4206 }
4207
4208 init_completion(&(getBcnMissRateCtx.completion));
4209 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4210
4211 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4212 pAdapter->sessionId,
4213 (void *)getBcnMissRateCB,
4214 (void *)(&getBcnMissRateCtx));
4215 if( eHAL_STATUS_SUCCESS != status)
4216 {
4217 hddLog(VOS_TRACE_LEVEL_INFO,
4218 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4219 ret = -EINVAL;
4220 goto exit;
4221 }
4222
4223 waitRet = wait_for_completion_interruptible_timeout
4224 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4225 if(waitRet <= 0)
4226 {
4227 hddLog(VOS_TRACE_LEVEL_ERROR,
4228 FL("failed to wait on bcnMissRateComp %d"), ret);
4229
4230 //Make magic number to zero so that callback is not called.
4231 spin_lock(&hdd_context_lock);
4232 getBcnMissRateCtx.magic = 0x0;
4233 spin_unlock(&hdd_context_lock);
4234 ret = -EINVAL;
4235 goto exit;
4236 }
4237
4238 hddLog(VOS_TRACE_LEVEL_INFO,
4239 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4240
4241 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4242 if (copy_to_user(priv_data.buf, &buf, len + 1))
4243 {
4244 hddLog(VOS_TRACE_LEVEL_ERROR,
4245 "%s: failed to copy data to user buffer", __func__);
4246 ret = -EFAULT;
4247 goto exit;
4248 }
4249 ret = len;
4250 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304251#ifdef FEATURE_WLAN_TDLS
4252 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4253 tANI_U8 *value = command;
4254 int set_value;
4255 /* Move pointer to ahead of TDLSOFFCH*/
4256 value += 26;
4257 sscanf(value, "%d", &set_value);
4258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4259 "%s: Tdls offchannel offset:%d",
4260 __func__, set_value);
4261 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4262 if (ret < 0)
4263 {
4264 ret = -EINVAL;
4265 goto exit;
4266 }
4267
4268 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4269 tANI_U8 *value = command;
4270 int set_value;
4271 /* Move pointer to ahead of tdlsoffchnmode*/
4272 value += 18;
4273 sscanf(value, "%d", &set_value);
4274 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4275 "%s: Tdls offchannel mode:%d",
4276 __func__, set_value);
4277 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4278 if (ret < 0)
4279 {
4280 ret = -EINVAL;
4281 goto exit;
4282 }
4283 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4284 tANI_U8 *value = command;
4285 int set_value;
4286 /* Move pointer to ahead of TDLSOFFCH*/
4287 value += 14;
4288 sscanf(value, "%d", &set_value);
4289 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4290 "%s: Tdls offchannel num: %d",
4291 __func__, set_value);
4292 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4293 if (ret < 0)
4294 {
4295 ret = -EINVAL;
4296 goto exit;
4297 }
4298 }
4299#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304300 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4301 {
4302 eHalStatus status;
4303 char *buf = NULL;
4304 char len;
4305 long waitRet;
4306 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304307 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304308 tANI_U8 *ptr = command;
4309 int stats = *(ptr + 11) - '0';
4310
4311 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4312 if (!IS_FEATURE_FW_STATS_ENABLE)
4313 {
4314 hddLog(VOS_TRACE_LEVEL_INFO,
4315 FL("Get Firmware stats feature not supported"));
4316 ret = -EINVAL;
4317 goto exit;
4318 }
4319
4320 if (FW_STATS_MAX <= stats || 0 >= stats)
4321 {
4322 hddLog(VOS_TRACE_LEVEL_INFO,
4323 FL(" stats %d not supported"),stats);
4324 ret = -EINVAL;
4325 goto exit;
4326 }
4327
4328 init_completion(&(fwStatsCtx.completion));
4329 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4330 fwStatsCtx.pAdapter = pAdapter;
4331 fwStatsRsp->type = 0;
4332 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304333 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304334 if (eHAL_STATUS_SUCCESS != status)
4335 {
4336 hddLog(VOS_TRACE_LEVEL_ERROR,
4337 FL(" fail to post WDA cmd status = %d"), status);
4338 ret = -EINVAL;
4339 goto exit;
4340 }
4341 waitRet = wait_for_completion_timeout
4342 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4343 if (waitRet <= 0)
4344 {
4345 hddLog(VOS_TRACE_LEVEL_ERROR,
4346 FL("failed to wait on GwtFwstats"));
4347 //Make magic number to zero so that callback is not executed.
4348 spin_lock(&hdd_context_lock);
4349 fwStatsCtx.magic = 0x0;
4350 spin_unlock(&hdd_context_lock);
4351 ret = -EINVAL;
4352 goto exit;
4353 }
4354 if (fwStatsRsp->type)
4355 {
4356 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4357 if (!buf)
4358 {
4359 hddLog(VOS_TRACE_LEVEL_ERROR,
4360 FL(" failed to allocate memory"));
4361 ret = -ENOMEM;
4362 goto exit;
4363 }
4364 switch( fwStatsRsp->type )
4365 {
4366 case FW_UBSP_STATS:
4367 {
4368 len = snprintf(buf, FW_STATE_RSP_LEN,
4369 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304370 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4371 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304372 }
4373 break;
4374 default:
4375 {
4376 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4377 ret = -EFAULT;
4378 kfree(buf);
4379 goto exit;
4380 }
4381 }
4382 if (copy_to_user(priv_data.buf, buf, len + 1))
4383 {
4384 hddLog(VOS_TRACE_LEVEL_ERROR,
4385 FL(" failed to copy data to user buffer"));
4386 ret = -EFAULT;
4387 kfree(buf);
4388 goto exit;
4389 }
4390 ret = len;
4391 kfree(buf);
4392 }
4393 else
4394 {
4395 hddLog(VOS_TRACE_LEVEL_ERROR,
4396 FL("failed to fetch the stats"));
4397 ret = -EFAULT;
4398 goto exit;
4399 }
4400
4401 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004402 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304403 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4404 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4405 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304406 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4407 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004408 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004409 }
4410exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304411 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004412 if (command)
4413 {
4414 kfree(command);
4415 }
4416 return ret;
4417}
4418
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004419#ifdef CONFIG_COMPAT
4420static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4421{
4422 struct {
4423 compat_uptr_t buf;
4424 int used_len;
4425 int total_len;
4426 } compat_priv_data;
4427 hdd_priv_data_t priv_data;
4428 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004429
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004430 /*
4431 * Note that pAdapter and ifr have already been verified by caller,
4432 * and HDD context has also been validated
4433 */
4434 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4435 sizeof(compat_priv_data))) {
4436 ret = -EFAULT;
4437 goto exit;
4438 }
4439 priv_data.buf = compat_ptr(compat_priv_data.buf);
4440 priv_data.used_len = compat_priv_data.used_len;
4441 priv_data.total_len = compat_priv_data.total_len;
4442 ret = hdd_driver_command(pAdapter, &priv_data);
4443 exit:
4444 return ret;
4445}
4446#else /* CONFIG_COMPAT */
4447static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4448{
4449 /* will never be invoked */
4450 return 0;
4451}
4452#endif /* CONFIG_COMPAT */
4453
4454static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4455{
4456 hdd_priv_data_t priv_data;
4457 int ret = 0;
4458
4459 /*
4460 * Note that pAdapter and ifr have already been verified by caller,
4461 * and HDD context has also been validated
4462 */
4463 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4464 ret = -EFAULT;
4465 } else {
4466 ret = hdd_driver_command(pAdapter, &priv_data);
4467 }
4468 return ret;
4469}
4470
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304471int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004472{
4473 hdd_adapter_t *pAdapter;
4474 hdd_context_t *pHddCtx;
4475 int ret;
4476
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304477 ENTER();
4478
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004479 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4480 if (NULL == pAdapter) {
4481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4482 "%s: HDD adapter context is Null", __func__);
4483 ret = -ENODEV;
4484 goto exit;
4485 }
4486 if (dev != pAdapter->dev) {
4487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4488 "%s: HDD adapter/dev inconsistency", __func__);
4489 ret = -ENODEV;
4490 goto exit;
4491 }
4492
4493 if ((!ifr) || (!ifr->ifr_data)) {
4494 ret = -EINVAL;
4495 goto exit;
4496 }
4497
4498 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4499 ret = wlan_hdd_validate_context(pHddCtx);
4500 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004501 ret = -EBUSY;
4502 goto exit;
4503 }
4504
4505 switch (cmd) {
4506 case (SIOCDEVPRIVATE + 1):
4507 if (is_compat_task())
4508 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4509 else
4510 ret = hdd_driver_ioctl(pAdapter, ifr);
4511 break;
4512 default:
4513 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4514 __func__, cmd);
4515 ret = -EINVAL;
4516 break;
4517 }
4518 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304519 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004520 return ret;
4521}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004522
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304523int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4524{
4525 int ret;
4526
4527 vos_ssr_protect(__func__);
4528 ret = __hdd_ioctl(dev, ifr, cmd);
4529 vos_ssr_unprotect(__func__);
4530
4531 return ret;
4532}
4533
Katya Nigame7b69a82015-04-28 15:24:06 +05304534int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4535{
4536 return 0;
4537}
4538
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004539#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004540/**---------------------------------------------------------------------------
4541
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004542 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004543
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004544 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004545 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4546 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4547 <space>Scan Mode N<space>Meas Duration N
4548 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4549 then take N.
4550 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4551 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4552 This function does not take care of removing duplicate channels from the list
4553
4554 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004555 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004556
4557 \return - 0 for success non-zero for failure
4558
4559 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004560static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4561 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004562{
4563 tANI_U8 *inPtr = pValue;
4564 int tempInt = 0;
4565 int j = 0, i = 0, v = 0;
4566 char buf[32];
4567
4568 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4569 /*no argument after the command*/
4570 if (NULL == inPtr)
4571 {
4572 return -EINVAL;
4573 }
4574 /*no space after the command*/
4575 else if (SPACE_ASCII_VALUE != *inPtr)
4576 {
4577 return -EINVAL;
4578 }
4579
4580 /*removing empty spaces*/
4581 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4582
4583 /*no argument followed by spaces*/
4584 if ('\0' == *inPtr) return -EINVAL;
4585
4586 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004587 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004588 if (1 != v) return -EINVAL;
4589
4590 v = kstrtos32(buf, 10, &tempInt);
4591 if ( v < 0) return -EINVAL;
4592
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004593 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004594
4595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004596 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004597
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004598 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004599 {
4600 for (i = 0; i < 4; i++)
4601 {
4602 /*inPtr pointing to the beginning of first space after number of ie fields*/
4603 inPtr = strpbrk( inPtr, " " );
4604 /*no ie data after the number of ie fields argument*/
4605 if (NULL == inPtr) return -EINVAL;
4606
4607 /*removing empty space*/
4608 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4609
4610 /*no ie data after the number of ie fields argument and spaces*/
4611 if ( '\0' == *inPtr ) return -EINVAL;
4612
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004613 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004614 if (1 != v) return -EINVAL;
4615
4616 v = kstrtos32(buf, 10, &tempInt);
4617 if (v < 0) return -EINVAL;
4618
4619 switch (i)
4620 {
4621 case 0: /* Measurement token */
4622 if (tempInt <= 0)
4623 {
4624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4625 "Invalid Measurement Token(%d)", tempInt);
4626 return -EINVAL;
4627 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004628 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004629 break;
4630
4631 case 1: /* Channel number */
4632 if ((tempInt <= 0) ||
4633 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4634 {
4635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4636 "Invalid Channel Number(%d)", tempInt);
4637 return -EINVAL;
4638 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004639 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004640 break;
4641
4642 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004643 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004644 {
4645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4646 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4647 return -EINVAL;
4648 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004649 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004650 break;
4651
4652 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004653 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4654 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004655 {
4656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4657 "Invalid Measurement Duration(%d)", tempInt);
4658 return -EINVAL;
4659 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004660 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004661 break;
4662 }
4663 }
4664 }
4665
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004666 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004667 {
4668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304669 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004670 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004671 pEseBcnReq->bcnReq[j].measurementToken,
4672 pEseBcnReq->bcnReq[j].channel,
4673 pEseBcnReq->bcnReq[j].scanMode,
4674 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004675 }
4676
4677 return VOS_STATUS_SUCCESS;
4678}
4679
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004680static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4681{
4682 struct statsContext *pStatsContext = NULL;
4683 hdd_adapter_t *pAdapter = NULL;
4684
4685 if (NULL == pContext)
4686 {
4687 hddLog(VOS_TRACE_LEVEL_ERROR,
4688 "%s: Bad param, pContext [%p]",
4689 __func__, pContext);
4690 return;
4691 }
4692
Jeff Johnson72a40512013-12-19 10:14:15 -08004693 /* there is a race condition that exists between this callback
4694 function and the caller since the caller could time out either
4695 before or while this code is executing. we use a spinlock to
4696 serialize these actions */
4697 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004698
4699 pStatsContext = pContext;
4700 pAdapter = pStatsContext->pAdapter;
4701 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4702 {
4703 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004704 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004705 hddLog(VOS_TRACE_LEVEL_WARN,
4706 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4707 __func__, pAdapter, pStatsContext->magic);
4708 return;
4709 }
4710
Jeff Johnson72a40512013-12-19 10:14:15 -08004711 /* context is valid so caller is still waiting */
4712
4713 /* paranoia: invalidate the magic */
4714 pStatsContext->magic = 0;
4715
4716 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004717 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4718 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4719 tsmMetrics.UplinkPktQueueDlyHist,
4720 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4721 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4722 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4723 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4724 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4725 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4726 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4727
Jeff Johnson72a40512013-12-19 10:14:15 -08004728 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004729 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004730
4731 /* serialization is complete */
4732 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004733}
4734
4735
4736
4737static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4738 tAniTrafStrmMetrics* pTsmMetrics)
4739{
4740 hdd_station_ctx_t *pHddStaCtx = NULL;
4741 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004742 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004743 long lrc;
4744 struct statsContext context;
4745 hdd_context_t *pHddCtx = NULL;
4746
4747 if (NULL == pAdapter)
4748 {
4749 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4750 return VOS_STATUS_E_FAULT;
4751 }
4752
4753 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4754 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4755
4756 /* we are connected prepare our callback context */
4757 init_completion(&context.completion);
4758 context.pAdapter = pAdapter;
4759 context.magic = STATS_CONTEXT_MAGIC;
4760
4761 /* query tsm stats */
4762 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4763 pHddStaCtx->conn_info.staId[ 0 ],
4764 pHddStaCtx->conn_info.bssId,
4765 &context, pHddCtx->pvosContext, tid);
4766
4767 if (eHAL_STATUS_SUCCESS != hstatus)
4768 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004769 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4770 __func__);
4771 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004772 }
4773 else
4774 {
4775 /* request was sent -- wait for the response */
4776 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4777 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004778 if (lrc <= 0)
4779 {
4780 hddLog(VOS_TRACE_LEVEL_ERROR,
4781 "%s: SME %s while retrieving statistics",
4782 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004783 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004784 }
4785 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004786
Jeff Johnson72a40512013-12-19 10:14:15 -08004787 /* either we never sent a request, we sent a request and received a
4788 response or we sent a request and timed out. if we never sent a
4789 request or if we sent a request and got a response, we want to
4790 clear the magic out of paranoia. if we timed out there is a
4791 race condition such that the callback function could be
4792 executing at the same time we are. of primary concern is if the
4793 callback function had already verified the "magic" but had not
4794 yet set the completion variable when a timeout occurred. we
4795 serialize these activities by invalidating the magic while
4796 holding a shared spinlock which will cause us to block if the
4797 callback is currently executing */
4798 spin_lock(&hdd_context_lock);
4799 context.magic = 0;
4800 spin_unlock(&hdd_context_lock);
4801
4802 if (VOS_STATUS_SUCCESS == vstatus)
4803 {
4804 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4805 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4806 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4807 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4808 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4809 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4810 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4811 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4812 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4813 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4814 }
4815 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004816}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004817#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004818
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004819#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004820void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4821{
4822 eCsrBand band = -1;
4823 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4824 switch (band)
4825 {
4826 case eCSR_BAND_ALL:
4827 *pBand = WLAN_HDD_UI_BAND_AUTO;
4828 break;
4829
4830 case eCSR_BAND_24:
4831 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4832 break;
4833
4834 case eCSR_BAND_5G:
4835 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4836 break;
4837
4838 default:
4839 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4840 *pBand = -1;
4841 break;
4842 }
4843}
4844
4845/**---------------------------------------------------------------------------
4846
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004847 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4848
4849 This function parses the send action frame data passed in the format
4850 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4851
Srinivas Girigowda56076852013-08-20 14:00:50 -07004852 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004853 \param - pTargetApBssid Pointer to target Ap bssid
4854 \param - pChannel Pointer to the Target AP channel
4855 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4856 \param - pBuf Pointer to data
4857 \param - pBufLen Pointer to data length
4858
4859 \return - 0 for success non-zero for failure
4860
4861 --------------------------------------------------------------------------*/
4862VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4863 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4864{
4865 tANI_U8 *inPtr = pValue;
4866 tANI_U8 *dataEnd;
4867 int tempInt;
4868 int j = 0;
4869 int i = 0;
4870 int v = 0;
4871 tANI_U8 tempBuf[32];
4872 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004873 /* 12 hexa decimal digits, 5 ':' and '\0' */
4874 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004875
4876 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4877 /*no argument after the command*/
4878 if (NULL == inPtr)
4879 {
4880 return -EINVAL;
4881 }
4882
4883 /*no space after the command*/
4884 else if (SPACE_ASCII_VALUE != *inPtr)
4885 {
4886 return -EINVAL;
4887 }
4888
4889 /*removing empty spaces*/
4890 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4891
4892 /*no argument followed by spaces*/
4893 if ('\0' == *inPtr)
4894 {
4895 return -EINVAL;
4896 }
4897
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004898 v = sscanf(inPtr, "%17s", macAddress);
4899 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004900 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4902 "Invalid MAC address or All hex inputs are not read (%d)", v);
4903 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004904 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004905
4906 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4907 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4908 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4909 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4910 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4911 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004912
4913 /* point to the next argument */
4914 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4915 /*no argument after the command*/
4916 if (NULL == inPtr) return -EINVAL;
4917
4918 /*removing empty spaces*/
4919 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4920
4921 /*no argument followed by spaces*/
4922 if ('\0' == *inPtr)
4923 {
4924 return -EINVAL;
4925 }
4926
4927 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004928 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004929 if (1 != v) return -EINVAL;
4930
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004931 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304932 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304933 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004934
4935 *pChannel = tempInt;
4936
4937 /* point to the next argument */
4938 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4939 /*no argument after the command*/
4940 if (NULL == inPtr) return -EINVAL;
4941 /*removing empty spaces*/
4942 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4943
4944 /*no argument followed by spaces*/
4945 if ('\0' == *inPtr)
4946 {
4947 return -EINVAL;
4948 }
4949
4950 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004951 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004952 if (1 != v) return -EINVAL;
4953
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004954 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004955 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004956
4957 *pDwellTime = tempInt;
4958
4959 /* point to the next argument */
4960 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4961 /*no argument after the command*/
4962 if (NULL == inPtr) return -EINVAL;
4963 /*removing empty spaces*/
4964 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4965
4966 /*no argument followed by spaces*/
4967 if ('\0' == *inPtr)
4968 {
4969 return -EINVAL;
4970 }
4971
4972 /* find the length of data */
4973 dataEnd = inPtr;
4974 while(('\0' != *dataEnd) )
4975 {
4976 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004977 }
Kiet Lambe150c22013-11-21 16:30:32 +05304978 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004979 if ( *pBufLen <= 0) return -EINVAL;
4980
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004981 /* Allocate the number of bytes based on the number of input characters
4982 whether it is even or odd.
4983 if the number of input characters are even, then we need N/2 byte.
4984 if the number of input characters are odd, then we need do (N+1)/2 to
4985 compensate rounding off.
4986 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4987 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4988 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004989 if (NULL == *pBuf)
4990 {
4991 hddLog(VOS_TRACE_LEVEL_FATAL,
4992 "%s: vos_mem_alloc failed ", __func__);
4993 return -EINVAL;
4994 }
4995
4996 /* the buffer received from the upper layer is character buffer,
4997 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4998 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4999 and f0 in 3rd location */
5000 for (i = 0, j = 0; j < *pBufLen; j += 2)
5001 {
Kiet Lambe150c22013-11-21 16:30:32 +05305002 if( j+1 == *pBufLen)
5003 {
5004 tempByte = hdd_parse_hex(inPtr[j]);
5005 }
5006 else
5007 {
5008 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5009 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005010 (*pBuf)[i++] = tempByte;
5011 }
5012 *pBufLen = i;
5013 return VOS_STATUS_SUCCESS;
5014}
5015
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005016/**---------------------------------------------------------------------------
5017
Srinivas Girigowdade697412013-02-14 16:31:48 -08005018 \brief hdd_parse_channellist() - HDD Parse channel list
5019
5020 This function parses the channel list passed in the format
5021 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005022 if the Number of channels (N) does not match with the actual number of channels passed
5023 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
5024 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
5025 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
5026 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08005027
5028 \param - pValue Pointer to input channel list
5029 \param - ChannelList Pointer to local output array to record channel list
5030 \param - pNumChannels Pointer to number of roam scan channels
5031
5032 \return - 0 for success non-zero for failure
5033
5034 --------------------------------------------------------------------------*/
5035VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
5036{
5037 tANI_U8 *inPtr = pValue;
5038 int tempInt;
5039 int j = 0;
5040 int v = 0;
5041 char buf[32];
5042
5043 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5044 /*no argument after the command*/
5045 if (NULL == inPtr)
5046 {
5047 return -EINVAL;
5048 }
5049
5050 /*no space after the command*/
5051 else if (SPACE_ASCII_VALUE != *inPtr)
5052 {
5053 return -EINVAL;
5054 }
5055
5056 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005057 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005058
5059 /*no argument followed by spaces*/
5060 if ('\0' == *inPtr)
5061 {
5062 return -EINVAL;
5063 }
5064
5065 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005066 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005067 if (1 != v) return -EINVAL;
5068
Srinivas Girigowdade697412013-02-14 16:31:48 -08005069 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005070 if ((v < 0) ||
5071 (tempInt <= 0) ||
5072 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
5073 {
5074 return -EINVAL;
5075 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005076
5077 *pNumChannels = tempInt;
5078
5079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5080 "Number of channels are: %d", *pNumChannels);
5081
5082 for (j = 0; j < (*pNumChannels); j++)
5083 {
5084 /*inPtr pointing to the beginning of first space after number of channels*/
5085 inPtr = strpbrk( inPtr, " " );
5086 /*no channel list after the number of channels argument*/
5087 if (NULL == inPtr)
5088 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005089 if (0 != j)
5090 {
5091 *pNumChannels = j;
5092 return VOS_STATUS_SUCCESS;
5093 }
5094 else
5095 {
5096 return -EINVAL;
5097 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005098 }
5099
5100 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005101 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005102
5103 /*no channel list after the number of channels argument and spaces*/
5104 if ( '\0' == *inPtr )
5105 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005106 if (0 != j)
5107 {
5108 *pNumChannels = j;
5109 return VOS_STATUS_SUCCESS;
5110 }
5111 else
5112 {
5113 return -EINVAL;
5114 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005115 }
5116
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005117 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005118 if (1 != v) return -EINVAL;
5119
Srinivas Girigowdade697412013-02-14 16:31:48 -08005120 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005121 if ((v < 0) ||
5122 (tempInt <= 0) ||
5123 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5124 {
5125 return -EINVAL;
5126 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005127 pChannelList[j] = tempInt;
5128
5129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5130 "Channel %d added to preferred channel list",
5131 pChannelList[j] );
5132 }
5133
Srinivas Girigowdade697412013-02-14 16:31:48 -08005134 return VOS_STATUS_SUCCESS;
5135}
5136
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005137
5138/**---------------------------------------------------------------------------
5139
5140 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5141
5142 This function parses the reasoc command data passed in the format
5143 REASSOC<space><bssid><space><channel>
5144
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005145 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005146 \param - pTargetApBssid Pointer to target Ap bssid
5147 \param - pChannel Pointer to the Target AP channel
5148
5149 \return - 0 for success non-zero for failure
5150
5151 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005152VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5153 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005154{
5155 tANI_U8 *inPtr = pValue;
5156 int tempInt;
5157 int v = 0;
5158 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005159 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005160 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005161
5162 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5163 /*no argument after the command*/
5164 if (NULL == inPtr)
5165 {
5166 return -EINVAL;
5167 }
5168
5169 /*no space after the command*/
5170 else if (SPACE_ASCII_VALUE != *inPtr)
5171 {
5172 return -EINVAL;
5173 }
5174
5175 /*removing empty spaces*/
5176 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5177
5178 /*no argument followed by spaces*/
5179 if ('\0' == *inPtr)
5180 {
5181 return -EINVAL;
5182 }
5183
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005184 v = sscanf(inPtr, "%17s", macAddress);
5185 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005186 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5188 "Invalid MAC address or All hex inputs are not read (%d)", v);
5189 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005190 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005191
5192 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5193 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5194 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5195 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5196 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5197 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005198
5199 /* point to the next argument */
5200 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5201 /*no argument after the command*/
5202 if (NULL == inPtr) return -EINVAL;
5203
5204 /*removing empty spaces*/
5205 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5206
5207 /*no argument followed by spaces*/
5208 if ('\0' == *inPtr)
5209 {
5210 return -EINVAL;
5211 }
5212
5213 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005214 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005215 if (1 != v) return -EINVAL;
5216
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005217 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005218 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305219 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005220 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5221 {
5222 return -EINVAL;
5223 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005224
5225 *pChannel = tempInt;
5226 return VOS_STATUS_SUCCESS;
5227}
5228
5229#endif
5230
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005231#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005232/**---------------------------------------------------------------------------
5233
5234 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5235
5236 This function parses the SETCCKM IE command
5237 SETCCKMIE<space><ie data>
5238
5239 \param - pValue Pointer to input data
5240 \param - pCckmIe Pointer to output cckm Ie
5241 \param - pCckmIeLen Pointer to output cckm ie length
5242
5243 \return - 0 for success non-zero for failure
5244
5245 --------------------------------------------------------------------------*/
5246VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5247 tANI_U8 *pCckmIeLen)
5248{
5249 tANI_U8 *inPtr = pValue;
5250 tANI_U8 *dataEnd;
5251 int j = 0;
5252 int i = 0;
5253 tANI_U8 tempByte = 0;
5254
5255 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5256 /*no argument after the command*/
5257 if (NULL == inPtr)
5258 {
5259 return -EINVAL;
5260 }
5261
5262 /*no space after the command*/
5263 else if (SPACE_ASCII_VALUE != *inPtr)
5264 {
5265 return -EINVAL;
5266 }
5267
5268 /*removing empty spaces*/
5269 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5270
5271 /*no argument followed by spaces*/
5272 if ('\0' == *inPtr)
5273 {
5274 return -EINVAL;
5275 }
5276
5277 /* find the length of data */
5278 dataEnd = inPtr;
5279 while(('\0' != *dataEnd) )
5280 {
5281 dataEnd++;
5282 ++(*pCckmIeLen);
5283 }
5284 if ( *pCckmIeLen <= 0) return -EINVAL;
5285
5286 /* Allocate the number of bytes based on the number of input characters
5287 whether it is even or odd.
5288 if the number of input characters are even, then we need N/2 byte.
5289 if the number of input characters are odd, then we need do (N+1)/2 to
5290 compensate rounding off.
5291 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5292 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5293 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5294 if (NULL == *pCckmIe)
5295 {
5296 hddLog(VOS_TRACE_LEVEL_FATAL,
5297 "%s: vos_mem_alloc failed ", __func__);
5298 return -EINVAL;
5299 }
5300 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5301 /* the buffer received from the upper layer is character buffer,
5302 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5303 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5304 and f0 in 3rd location */
5305 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5306 {
5307 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5308 (*pCckmIe)[i++] = tempByte;
5309 }
5310 *pCckmIeLen = i;
5311
5312 return VOS_STATUS_SUCCESS;
5313}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005314#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005315
Jeff Johnson295189b2012-06-20 16:38:30 -07005316/**---------------------------------------------------------------------------
5317
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005318 \brief hdd_is_valid_mac_address() - Validate MAC address
5319
5320 This function validates whether the given MAC address is valid or not
5321 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5322 where X is the hexa decimal digit character and separated by ':'
5323 This algorithm works even if MAC address is not separated by ':'
5324
5325 This code checks given input string mac contains exactly 12 hexadecimal digits.
5326 and a separator colon : appears in the input string only after
5327 an even number of hex digits.
5328
5329 \param - pMacAddr pointer to the input MAC address
5330 \return - 1 for valid and 0 for invalid
5331
5332 --------------------------------------------------------------------------*/
5333
5334v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5335{
5336 int xdigit = 0;
5337 int separator = 0;
5338 while (*pMacAddr)
5339 {
5340 if (isxdigit(*pMacAddr))
5341 {
5342 xdigit++;
5343 }
5344 else if (':' == *pMacAddr)
5345 {
5346 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5347 break;
5348
5349 ++separator;
5350 }
5351 else
5352 {
5353 separator = -1;
5354 /* Invalid MAC found */
5355 return 0;
5356 }
5357 ++pMacAddr;
5358 }
5359 return (xdigit == 12 && (separator == 5 || separator == 0));
5360}
5361
5362/**---------------------------------------------------------------------------
5363
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305364 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005365
5366 \param - dev Pointer to net_device structure
5367
5368 \return - 0 for success non-zero for failure
5369
5370 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305371int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005372{
5373 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5374 hdd_context_t *pHddCtx;
5375 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5376 VOS_STATUS status;
5377 v_BOOL_t in_standby = TRUE;
5378
5379 if (NULL == pAdapter)
5380 {
5381 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305382 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005383 return -ENODEV;
5384 }
5385
5386 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305387 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5388 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005389 if (NULL == pHddCtx)
5390 {
5391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005392 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005393 return -ENODEV;
5394 }
5395
5396 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5397 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5398 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005399 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5400 {
5401 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305402 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005403 in_standby = FALSE;
5404 break;
5405 }
5406 else
5407 {
5408 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5409 pAdapterNode = pNext;
5410 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005411 }
5412
5413 if (TRUE == in_standby)
5414 {
5415 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5416 {
5417 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5418 "wlan out of power save", __func__);
5419 return -EINVAL;
5420 }
5421 }
5422
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005423 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005424 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5425 {
5426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005427 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005428 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305429 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005430 netif_tx_start_all_queues(dev);
5431 }
5432
5433 return 0;
5434}
5435
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305436/**---------------------------------------------------------------------------
5437
5438 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5439
5440 This is called in response to ifconfig up
5441
5442 \param - dev Pointer to net_device structure
5443
5444 \return - 0 for success non-zero for failure
5445
5446 --------------------------------------------------------------------------*/
5447int hdd_open(struct net_device *dev)
5448{
5449 int ret;
5450
5451 vos_ssr_protect(__func__);
5452 ret = __hdd_open(dev);
5453 vos_ssr_unprotect(__func__);
5454
5455 return ret;
5456}
5457
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305458int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005459{
5460 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5461
5462 if(pAdapter == NULL) {
5463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005464 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005465 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005466 }
5467
Jeff Johnson295189b2012-06-20 16:38:30 -07005468 return 0;
5469}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305470
5471int hdd_mon_open (struct net_device *dev)
5472{
5473 int ret;
5474
5475 vos_ssr_protect(__func__);
5476 ret = __hdd_mon_open(dev);
5477 vos_ssr_unprotect(__func__);
5478
5479 return ret;
5480}
5481
Katya Nigame7b69a82015-04-28 15:24:06 +05305482int hdd_mon_stop(struct net_device *dev)
5483{
5484 return 0;
5485}
5486
Jeff Johnson295189b2012-06-20 16:38:30 -07005487/**---------------------------------------------------------------------------
5488
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305489 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005490
5491 \param - dev Pointer to net_device structure
5492
5493 \return - 0 for success non-zero for failure
5494
5495 --------------------------------------------------------------------------*/
5496
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305497int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005498{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305499 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005500 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5501 hdd_context_t *pHddCtx;
5502 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5503 VOS_STATUS status;
5504 v_BOOL_t enter_standby = TRUE;
5505
5506 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005507 if (NULL == pAdapter)
5508 {
5509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305510 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005511 return -ENODEV;
5512 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305513 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305514 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305515
5516 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5517 ret = wlan_hdd_validate_context(pHddCtx);
5518 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005519 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305520 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005521 }
5522
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305523 /* Nothing to be done if the interface is not opened */
5524 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5525 {
5526 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5527 "%s: NETDEV Interface is not OPENED", __func__);
5528 return -ENODEV;
5529 }
5530
5531 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005532 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005533 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305534
5535 /* Disable TX on the interface, after this hard_start_xmit() will not
5536 * be called on that interface
5537 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305538 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005539 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305540
5541 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005542 netif_carrier_off(pAdapter->dev);
5543
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305544 /* The interface is marked as down for outside world (aka kernel)
5545 * But the driver is pretty much alive inside. The driver needs to
5546 * tear down the existing connection on the netdev (session)
5547 * cleanup the data pipes and wait until the control plane is stabilized
5548 * for this interface. The call also needs to wait until the above
5549 * mentioned actions are completed before returning to the caller.
5550 * Notice that the hdd_stop_adapter is requested not to close the session
5551 * That is intentional to be able to scan if it is a STA/P2P interface
5552 */
5553 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305554#ifdef FEATURE_WLAN_TDLS
5555 mutex_lock(&pHddCtx->tdls_lock);
5556#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305557 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305558 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305559#ifdef FEATURE_WLAN_TDLS
5560 mutex_unlock(&pHddCtx->tdls_lock);
5561#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005562 /* SoftAP ifaces should never go in power save mode
5563 making sure same here. */
5564 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5565 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005566 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005567 )
5568 {
5569 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5571 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005572 EXIT();
5573 return 0;
5574 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305575 /* Find if any iface is up. If any iface is up then can't put device to
5576 * sleep/power save mode
5577 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005578 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5579 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5580 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005581 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5582 {
5583 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305584 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005585 enter_standby = FALSE;
5586 break;
5587 }
5588 else
5589 {
5590 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5591 pAdapterNode = pNext;
5592 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005593 }
5594
5595 if (TRUE == enter_standby)
5596 {
5597 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5598 "entering standby", __func__);
5599 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5600 {
5601 /*log and return success*/
5602 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5603 "wlan in power save", __func__);
5604 }
5605 }
5606
5607 EXIT();
5608 return 0;
5609}
5610
5611/**---------------------------------------------------------------------------
5612
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305613 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005614
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305615 This is called in response to ifconfig down
5616
5617 \param - dev Pointer to net_device structure
5618
5619 \return - 0 for success non-zero for failure
5620-----------------------------------------------------------------------------*/
5621int hdd_stop (struct net_device *dev)
5622{
5623 int ret;
5624
5625 vos_ssr_protect(__func__);
5626 ret = __hdd_stop(dev);
5627 vos_ssr_unprotect(__func__);
5628
5629 return ret;
5630}
5631
5632/**---------------------------------------------------------------------------
5633
5634 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005635
5636 \param - dev Pointer to net_device structure
5637
5638 \return - void
5639
5640 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305641static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005642{
5643 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305644 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005645 ENTER();
5646
5647 do
5648 {
5649 if (NULL == pAdapter)
5650 {
5651 hddLog(VOS_TRACE_LEVEL_FATAL,
5652 "%s: NULL pAdapter", __func__);
5653 break;
5654 }
5655
5656 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5657 {
5658 hddLog(VOS_TRACE_LEVEL_FATAL,
5659 "%s: Invalid magic", __func__);
5660 break;
5661 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305662 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5663 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005664 {
5665 hddLog(VOS_TRACE_LEVEL_FATAL,
5666 "%s: NULL pHddCtx", __func__);
5667 break;
5668 }
5669
5670 if (dev != pAdapter->dev)
5671 {
5672 hddLog(VOS_TRACE_LEVEL_FATAL,
5673 "%s: Invalid device reference", __func__);
5674 /* we haven't validated all cases so let this go for now */
5675 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305676#ifdef FEATURE_WLAN_TDLS
5677 mutex_lock(&pHddCtx->tdls_lock);
5678#endif
c_hpothu002231a2015-02-05 14:58:51 +05305679 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305680#ifdef FEATURE_WLAN_TDLS
5681 mutex_unlock(&pHddCtx->tdls_lock);
5682#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005683
5684 /* after uninit our adapter structure will no longer be valid */
5685 pAdapter->dev = NULL;
5686 pAdapter->magic = 0;
5687 } while (0);
5688
5689 EXIT();
5690}
5691
5692/**---------------------------------------------------------------------------
5693
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305694 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5695
5696 This is called during the netdev unregister to uninitialize all data
5697associated with the device
5698
5699 \param - dev Pointer to net_device structure
5700
5701 \return - void
5702
5703 --------------------------------------------------------------------------*/
5704static void hdd_uninit (struct net_device *dev)
5705{
5706 vos_ssr_protect(__func__);
5707 __hdd_uninit(dev);
5708 vos_ssr_unprotect(__func__);
5709}
5710
5711/**---------------------------------------------------------------------------
5712
Jeff Johnson295189b2012-06-20 16:38:30 -07005713 \brief hdd_release_firmware() -
5714
5715 This function calls the release firmware API to free the firmware buffer.
5716
5717 \param - pFileName Pointer to the File Name.
5718 pCtx - Pointer to the adapter .
5719
5720
5721 \return - 0 for success, non zero for failure
5722
5723 --------------------------------------------------------------------------*/
5724
5725VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5726{
5727 VOS_STATUS status = VOS_STATUS_SUCCESS;
5728 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5729 ENTER();
5730
5731
5732 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5733
5734 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5735
5736 if(pHddCtx->fw) {
5737 release_firmware(pHddCtx->fw);
5738 pHddCtx->fw = NULL;
5739 }
5740 else
5741 status = VOS_STATUS_E_FAILURE;
5742 }
5743 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5744 if(pHddCtx->nv) {
5745 release_firmware(pHddCtx->nv);
5746 pHddCtx->nv = NULL;
5747 }
5748 else
5749 status = VOS_STATUS_E_FAILURE;
5750
5751 }
5752
5753 EXIT();
5754 return status;
5755}
5756
5757/**---------------------------------------------------------------------------
5758
5759 \brief hdd_request_firmware() -
5760
5761 This function reads the firmware file using the request firmware
5762 API and returns the the firmware data and the firmware file size.
5763
5764 \param - pfileName - Pointer to the file name.
5765 - pCtx - Pointer to the adapter .
5766 - ppfw_data - Pointer to the pointer of the firmware data.
5767 - pSize - Pointer to the file size.
5768
5769 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5770
5771 --------------------------------------------------------------------------*/
5772
5773
5774VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5775{
5776 int status;
5777 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5778 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5779 ENTER();
5780
5781 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5782
5783 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5784
5785 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5786 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5787 __func__, pfileName);
5788 retval = VOS_STATUS_E_FAILURE;
5789 }
5790
5791 else {
5792 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5793 *pSize = pHddCtx->fw->size;
5794 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5795 __func__, *pSize);
5796 }
5797 }
5798 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5799
5800 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5801
5802 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5803 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5804 __func__, pfileName);
5805 retval = VOS_STATUS_E_FAILURE;
5806 }
5807
5808 else {
5809 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5810 *pSize = pHddCtx->nv->size;
5811 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5812 __func__, *pSize);
5813 }
5814 }
5815
5816 EXIT();
5817 return retval;
5818}
5819/**---------------------------------------------------------------------------
5820 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5821
5822 This is the function invoked by SME to inform the result of a full power
5823 request issued by HDD
5824
5825 \param - callbackcontext - Pointer to cookie
5826 status - result of request
5827
5828 \return - None
5829
5830--------------------------------------------------------------------------*/
5831void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5832{
5833 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5834
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005835 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005836 if(&pHddCtx->full_pwr_comp_var)
5837 {
5838 complete(&pHddCtx->full_pwr_comp_var);
5839 }
5840}
5841
5842/**---------------------------------------------------------------------------
5843
5844 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5845
5846 This is the function invoked by SME to inform the result of BMPS
5847 request issued by HDD
5848
5849 \param - callbackcontext - Pointer to cookie
5850 status - result of request
5851
5852 \return - None
5853
5854--------------------------------------------------------------------------*/
5855void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5856{
5857
5858 struct completion *completion_var = (struct completion*) callbackContext;
5859
Arif Hussain6d2a3322013-11-17 19:50:10 -08005860 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005861 if(completion_var != NULL)
5862 {
5863 complete(completion_var);
5864 }
5865}
5866
5867/**---------------------------------------------------------------------------
5868
5869 \brief hdd_get_cfg_file_size() -
5870
5871 This function reads the configuration file using the request firmware
5872 API and returns the configuration file size.
5873
5874 \param - pCtx - Pointer to the adapter .
5875 - pFileName - Pointer to the file name.
5876 - pBufSize - Pointer to the buffer size.
5877
5878 \return - 0 for success, non zero for failure
5879
5880 --------------------------------------------------------------------------*/
5881
5882VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5883{
5884 int status;
5885 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5886
5887 ENTER();
5888
5889 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5890
5891 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5892 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5893 status = VOS_STATUS_E_FAILURE;
5894 }
5895 else {
5896 *pBufSize = pHddCtx->fw->size;
5897 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5898 release_firmware(pHddCtx->fw);
5899 pHddCtx->fw = NULL;
5900 }
5901
5902 EXIT();
5903 return VOS_STATUS_SUCCESS;
5904}
5905
5906/**---------------------------------------------------------------------------
5907
5908 \brief hdd_read_cfg_file() -
5909
5910 This function reads the configuration file using the request firmware
5911 API and returns the cfg data and the buffer size of the configuration file.
5912
5913 \param - pCtx - Pointer to the adapter .
5914 - pFileName - Pointer to the file name.
5915 - pBuffer - Pointer to the data buffer.
5916 - pBufSize - Pointer to the buffer size.
5917
5918 \return - 0 for success, non zero for failure
5919
5920 --------------------------------------------------------------------------*/
5921
5922VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5923 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5924{
5925 int status;
5926 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5927
5928 ENTER();
5929
5930 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5931
5932 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5933 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5934 return VOS_STATUS_E_FAILURE;
5935 }
5936 else {
5937 if(*pBufSize != pHddCtx->fw->size) {
5938 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5939 "file size", __func__);
5940 release_firmware(pHddCtx->fw);
5941 pHddCtx->fw = NULL;
5942 return VOS_STATUS_E_FAILURE;
5943 }
5944 else {
5945 if(pBuffer) {
5946 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5947 }
5948 release_firmware(pHddCtx->fw);
5949 pHddCtx->fw = NULL;
5950 }
5951 }
5952
5953 EXIT();
5954
5955 return VOS_STATUS_SUCCESS;
5956}
5957
5958/**---------------------------------------------------------------------------
5959
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305960 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07005961
5962 This function sets the user specified mac address using
5963 the command ifconfig wlanX hw ether <mac adress>.
5964
5965 \param - dev - Pointer to the net device.
5966 - addr - Pointer to the sockaddr.
5967 \return - 0 for success, non zero for failure
5968
5969 --------------------------------------------------------------------------*/
5970
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305971static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07005972{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305973 hdd_adapter_t *pAdapter;
5974 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005975 struct sockaddr *psta_mac_addr = addr;
5976 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305977 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005978
5979 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305980 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5981 if (NULL == pAdapter)
5982 {
5983 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5984 "%s: Adapter is NULL",__func__);
5985 return -EINVAL;
5986 }
5987 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5988 ret = wlan_hdd_validate_context(pHddCtx);
5989 if (0 != ret)
5990 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305991 return ret;
5992 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005993
5994 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07005995 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5996
5997 EXIT();
5998 return halStatus;
5999}
6000
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306001/**---------------------------------------------------------------------------
6002
6003 \brief hdd_set_mac_address() -
6004
6005 Wrapper function to protect __hdd_set_mac_address() function from ssr
6006
6007 \param - dev - Pointer to the net device.
6008 - addr - Pointer to the sockaddr.
6009 \return - 0 for success, non zero for failure
6010
6011 --------------------------------------------------------------------------*/
6012static int hdd_set_mac_address(struct net_device *dev, void *addr)
6013{
6014 int ret;
6015
6016 vos_ssr_protect(__func__);
6017 ret = __hdd_set_mac_address(dev, addr);
6018 vos_ssr_unprotect(__func__);
6019
6020 return ret;
6021}
6022
Jeff Johnson295189b2012-06-20 16:38:30 -07006023tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
6024{
6025 int i;
6026 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6027 {
Abhishek Singheb183782014-02-06 13:37:21 +05306028 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006029 break;
6030 }
6031
6032 if( VOS_MAX_CONCURRENCY_PERSONA == i)
6033 return NULL;
6034
6035 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
6036 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
6037}
6038
6039void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
6040{
6041 int i;
6042 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6043 {
6044 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
6045 {
6046 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
6047 break;
6048 }
6049 }
6050 return;
6051}
6052
6053#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6054 static struct net_device_ops wlan_drv_ops = {
6055 .ndo_open = hdd_open,
6056 .ndo_stop = hdd_stop,
6057 .ndo_uninit = hdd_uninit,
6058 .ndo_start_xmit = hdd_hard_start_xmit,
6059 .ndo_tx_timeout = hdd_tx_timeout,
6060 .ndo_get_stats = hdd_stats,
6061 .ndo_do_ioctl = hdd_ioctl,
6062 .ndo_set_mac_address = hdd_set_mac_address,
6063 .ndo_select_queue = hdd_select_queue,
6064#ifdef WLAN_FEATURE_PACKET_FILTERING
6065#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
6066 .ndo_set_rx_mode = hdd_set_multicast_list,
6067#else
6068 .ndo_set_multicast_list = hdd_set_multicast_list,
6069#endif //LINUX_VERSION_CODE
6070#endif
6071 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006072 static struct net_device_ops wlan_mon_drv_ops = {
6073 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05306074 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07006075 .ndo_uninit = hdd_uninit,
6076 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6077 .ndo_tx_timeout = hdd_tx_timeout,
6078 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05306079 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07006080 .ndo_set_mac_address = hdd_set_mac_address,
6081 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306082
Jeff Johnson295189b2012-06-20 16:38:30 -07006083#endif
6084
6085void hdd_set_station_ops( struct net_device *pWlanDev )
6086{
6087#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006088 pWlanDev->netdev_ops = &wlan_drv_ops;
6089#else
6090 pWlanDev->open = hdd_open;
6091 pWlanDev->stop = hdd_stop;
6092 pWlanDev->uninit = hdd_uninit;
6093 pWlanDev->hard_start_xmit = NULL;
6094 pWlanDev->tx_timeout = hdd_tx_timeout;
6095 pWlanDev->get_stats = hdd_stats;
6096 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006097 pWlanDev->set_mac_address = hdd_set_mac_address;
6098#endif
6099}
6100
Katya Nigam1fd24402015-02-16 14:52:19 +05306101void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
6102{
6103 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6104 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
6105 #else
6106 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
6107 #endif
6108}
6109
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006110static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006111{
6112 struct net_device *pWlanDev = NULL;
6113 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006114 /*
6115 * cfg80211 initialization and registration....
6116 */
6117 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
6118
Jeff Johnson295189b2012-06-20 16:38:30 -07006119 if(pWlanDev != NULL)
6120 {
6121
6122 //Save the pointer to the net_device in the HDD adapter
6123 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6124
Jeff Johnson295189b2012-06-20 16:38:30 -07006125 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6126
6127 pAdapter->dev = pWlanDev;
6128 pAdapter->pHddCtx = pHddCtx;
6129 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306130 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006131
6132 init_completion(&pAdapter->session_open_comp_var);
6133 init_completion(&pAdapter->session_close_comp_var);
6134 init_completion(&pAdapter->disconnect_comp_var);
6135 init_completion(&pAdapter->linkup_event_var);
6136 init_completion(&pAdapter->cancel_rem_on_chan_var);
6137 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306138 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006139#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6140 init_completion(&pAdapter->offchannel_tx_event);
6141#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006142 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006143#ifdef FEATURE_WLAN_TDLS
6144 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006145 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006146 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306147 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006148#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006149 init_completion(&pHddCtx->mc_sus_event_var);
6150 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306151 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006152 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006153 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006154
Rajeev79dbe4c2013-10-05 11:03:42 +05306155#ifdef FEATURE_WLAN_BATCH_SCAN
6156 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6157 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6158 pAdapter->pBatchScanRsp = NULL;
6159 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006160 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006161 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306162 mutex_init(&pAdapter->hdd_batch_scan_lock);
6163#endif
6164
Jeff Johnson295189b2012-06-20 16:38:30 -07006165 pAdapter->isLinkUpSvcNeeded = FALSE;
6166 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6167 //Init the net_device structure
6168 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6169
6170 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6171 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6172 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6173 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6174
6175 hdd_set_station_ops( pAdapter->dev );
6176
6177 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006178 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6179 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6180 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006181 /* set pWlanDev's parent to underlying device */
6182 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006183
6184 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006185 }
6186
6187 return pAdapter;
6188}
6189
6190VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6191{
6192 struct net_device *pWlanDev = pAdapter->dev;
6193 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6194 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6195 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6196
6197 if( rtnl_lock_held )
6198 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006199 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006200 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6201 {
6202 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6203 return VOS_STATUS_E_FAILURE;
6204 }
6205 }
6206 if (register_netdevice(pWlanDev))
6207 {
6208 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6209 return VOS_STATUS_E_FAILURE;
6210 }
6211 }
6212 else
6213 {
6214 if(register_netdev(pWlanDev))
6215 {
6216 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6217 return VOS_STATUS_E_FAILURE;
6218 }
6219 }
6220 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6221
6222 return VOS_STATUS_SUCCESS;
6223}
6224
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006225static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006226{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006227 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006228
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006229 if (NULL == pAdapter)
6230 {
6231 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6232 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006233 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006234
6235 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6236 {
6237 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6238 return eHAL_STATUS_NOT_INITIALIZED;
6239 }
6240
6241 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6242
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006243#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006244 /* need to make sure all of our scheduled work has completed.
6245 * This callback is called from MC thread context, so it is safe to
6246 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006247 *
6248 * Even though this is called from MC thread context, if there is a faulty
6249 * work item in the system, that can hang this call forever. So flushing
6250 * this global work queue is not safe; and now we make sure that
6251 * individual work queues are stopped correctly. But the cancel work queue
6252 * is a GPL only API, so the proprietary version of the driver would still
6253 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006254 */
6255 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006256#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006257
6258 /* We can be blocked while waiting for scheduled work to be
6259 * flushed, and the adapter structure can potentially be freed, in
6260 * which case the magic will have been reset. So make sure the
6261 * magic is still good, and hence the adapter structure is still
6262 * valid, before signaling completion */
6263 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6264 {
6265 complete(&pAdapter->session_close_comp_var);
6266 }
6267
Jeff Johnson295189b2012-06-20 16:38:30 -07006268 return eHAL_STATUS_SUCCESS;
6269}
6270
6271VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6272{
6273 struct net_device *pWlanDev = pAdapter->dev;
6274 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6275 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6276 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6277 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306278 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006279
6280 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006281 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006282 //Open a SME session for future operation
6283 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006284 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006285 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6286 {
6287 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006288 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006289 halStatus, halStatus );
6290 status = VOS_STATUS_E_FAILURE;
6291 goto error_sme_open;
6292 }
6293
6294 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306295 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006296 &pAdapter->session_open_comp_var,
6297 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306298 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006299 {
6300 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306301 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006302 status = VOS_STATUS_E_FAILURE;
6303 goto error_sme_open;
6304 }
6305
6306 // Register wireless extensions
6307 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6308 {
6309 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006310 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006311 halStatus, halStatus );
6312 status = VOS_STATUS_E_FAILURE;
6313 goto error_register_wext;
6314 }
Katya Nigam1fd24402015-02-16 14:52:19 +05306315
Jeff Johnson295189b2012-06-20 16:38:30 -07006316 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05306317 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6318 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6319 #else
6320 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6321 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006322
6323 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306324 hddLog(VOS_TRACE_LEVEL_INFO,
6325 "%s: Set HDD connState to eConnectionState_NotConnected",
6326 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006327 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6328
6329 //Set the default operation channel
6330 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6331
6332 /* Make the default Auth Type as OPEN*/
6333 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6334
6335 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6336 {
6337 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006338 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006339 status, status );
6340 goto error_init_txrx;
6341 }
6342
6343 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6344
6345 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6346 {
6347 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006348 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006349 status, status );
6350 goto error_wmm_init;
6351 }
6352
6353 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6354
6355 return VOS_STATUS_SUCCESS;
6356
6357error_wmm_init:
6358 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6359 hdd_deinit_tx_rx(pAdapter);
6360error_init_txrx:
6361 hdd_UnregisterWext(pWlanDev);
6362error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006363 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006364 {
6365 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006366 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006367 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006368 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006369 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306370 unsigned long rc;
6371
Jeff Johnson295189b2012-06-20 16:38:30 -07006372 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306373 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006374 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006375 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306376 if (rc <= 0)
6377 hddLog(VOS_TRACE_LEVEL_ERROR,
6378 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006379 }
6380}
6381error_sme_open:
6382 return status;
6383}
6384
Jeff Johnson295189b2012-06-20 16:38:30 -07006385void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6386{
6387 hdd_cfg80211_state_t *cfgState;
6388
6389 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6390
6391 if( NULL != cfgState->buf )
6392 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306393 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006394 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6395 rc = wait_for_completion_interruptible_timeout(
6396 &pAdapter->tx_action_cnf_event,
6397 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306398 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006399 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306401 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6402 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006403 }
6404 }
6405 return;
6406}
Jeff Johnson295189b2012-06-20 16:38:30 -07006407
c_hpothu002231a2015-02-05 14:58:51 +05306408void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006409{
6410 ENTER();
6411 switch ( pAdapter->device_mode )
6412 {
Katya Nigam1fd24402015-02-16 14:52:19 +05306413 case WLAN_HDD_IBSS:
6414 {
6415 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6416 {
6417 hdd_ibss_deinit_tx_rx( pAdapter );
6418 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6419 }
6420 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006421 case WLAN_HDD_INFRA_STATION:
6422 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006423 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006424 {
6425 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6426 {
6427 hdd_deinit_tx_rx( pAdapter );
6428 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6429 }
6430
6431 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6432 {
6433 hdd_wmm_adapter_close( pAdapter );
6434 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6435 }
6436
Jeff Johnson295189b2012-06-20 16:38:30 -07006437 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006438 break;
6439 }
6440
6441 case WLAN_HDD_SOFTAP:
6442 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306444
6445 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6446 {
6447 hdd_wmm_adapter_close( pAdapter );
6448 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6449 }
6450
Jeff Johnson295189b2012-06-20 16:38:30 -07006451 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006452
c_hpothu002231a2015-02-05 14:58:51 +05306453 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006454 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006455 break;
6456 }
6457
6458 case WLAN_HDD_MONITOR:
6459 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006460 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6461 {
6462 hdd_deinit_tx_rx( pAdapter );
6463 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6464 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006465 break;
6466 }
6467
6468
6469 default:
6470 break;
6471 }
6472
6473 EXIT();
6474}
6475
6476void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6477{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006478 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306479
6480 ENTER();
6481 if (NULL == pAdapter)
6482 {
6483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6484 "%s: HDD adapter is Null", __func__);
6485 return;
6486 }
6487
6488 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006489
Rajeev79dbe4c2013-10-05 11:03:42 +05306490#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306491 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6492 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006493 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306494 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6495 )
6496 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006497 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306498 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006499 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6500 {
6501 hdd_deinit_batch_scan(pAdapter);
6502 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306503 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006504 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306505#endif
6506
Jeff Johnson295189b2012-06-20 16:38:30 -07006507 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6508 if( rtnl_held )
6509 {
6510 unregister_netdevice(pWlanDev);
6511 }
6512 else
6513 {
6514 unregister_netdev(pWlanDev);
6515 }
6516 // note that the pAdapter is no longer valid at this point
6517 // since the memory has been reclaimed
6518 }
6519
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306520 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006521}
6522
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006523void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6524{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306525 VOS_STATUS status;
6526 hdd_adapter_t *pAdapter = NULL;
6527 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006528
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306529 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006530
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306531 /*loop through all adapters.*/
6532 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006533 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306534 pAdapter = pAdapterNode->pAdapter;
6535 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6536 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006537
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306538 { // we skip this registration for modes other than STA and P2P client modes.
6539 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6540 pAdapterNode = pNext;
6541 continue;
6542 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006543
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306544 //Apply Dynamic DTIM For P2P
6545 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6546 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6547 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6548 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6549 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6550 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6551 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6552 (eConnectionState_Associated ==
6553 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6554 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6555 {
6556 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006557
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306558 powerRequest.uIgnoreDTIM = 1;
6559 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6560
6561 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6562 {
6563 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6564 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6565 }
6566 else
6567 {
6568 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6569 }
6570
6571 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6572 * specified during Enter/Exit BMPS when LCD off*/
6573 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6574 NULL, eANI_BOOLEAN_FALSE);
6575 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6576 NULL, eANI_BOOLEAN_FALSE);
6577
6578 /* switch to the DTIM specified in cfg.ini */
6579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6580 "Switch to DTIM %d", powerRequest.uListenInterval);
6581 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6582 break;
6583
6584 }
6585
6586 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6587 pAdapterNode = pNext;
6588 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006589}
6590
6591void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6592{
6593 /*Switch back to DTIM 1*/
6594 tSirSetPowerParamsReq powerRequest = { 0 };
6595
6596 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6597 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006598 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006599
6600 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6601 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6602 NULL, eANI_BOOLEAN_FALSE);
6603 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6604 NULL, eANI_BOOLEAN_FALSE);
6605
6606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6607 "Switch to DTIM%d",powerRequest.uListenInterval);
6608 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6609
6610}
6611
Jeff Johnson295189b2012-06-20 16:38:30 -07006612VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6613{
6614 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306615 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6616 {
6617 hddLog( LOGE, FL("Wlan Unload in progress"));
6618 return VOS_STATUS_E_PERM;
6619 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006620 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6621 {
6622 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6623 }
6624
6625 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6626 {
6627 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6628 }
6629
6630 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6631 {
6632 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6633 }
6634
6635 return status;
6636}
6637
6638VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6639{
6640 hdd_adapter_t *pAdapter = NULL;
6641 eHalStatus halStatus;
6642 VOS_STATUS status = VOS_STATUS_E_INVAL;
6643 v_BOOL_t disableBmps = FALSE;
6644 v_BOOL_t disableImps = FALSE;
6645
6646 switch(session_type)
6647 {
6648 case WLAN_HDD_INFRA_STATION:
6649 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006650 case WLAN_HDD_P2P_CLIENT:
6651 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006652 //Exit BMPS -> Is Sta/P2P Client is already connected
6653 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6654 if((NULL != pAdapter)&&
6655 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6656 {
6657 disableBmps = TRUE;
6658 }
6659
6660 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6661 if((NULL != pAdapter)&&
6662 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6663 {
6664 disableBmps = TRUE;
6665 }
6666
6667 //Exit both Bmps and Imps incase of Go/SAP Mode
6668 if((WLAN_HDD_SOFTAP == session_type) ||
6669 (WLAN_HDD_P2P_GO == session_type))
6670 {
6671 disableBmps = TRUE;
6672 disableImps = TRUE;
6673 }
6674
6675 if(TRUE == disableImps)
6676 {
6677 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6678 {
6679 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6680 }
6681 }
6682
6683 if(TRUE == disableBmps)
6684 {
6685 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6686 {
6687 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6688
6689 if(eHAL_STATUS_SUCCESS != halStatus)
6690 {
6691 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006692 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006693 VOS_ASSERT(0);
6694 return status;
6695 }
6696 }
6697
6698 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6699 {
6700 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6701
6702 if(eHAL_STATUS_SUCCESS != halStatus)
6703 {
6704 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006705 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006706 VOS_ASSERT(0);
6707 return status;
6708 }
6709 }
6710 }
6711
6712 if((TRUE == disableBmps) ||
6713 (TRUE == disableImps))
6714 {
6715 /* Now, get the chip into Full Power now */
6716 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6717 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6718 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6719
6720 if(halStatus != eHAL_STATUS_SUCCESS)
6721 {
6722 if(halStatus == eHAL_STATUS_PMC_PENDING)
6723 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306724 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006725 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306726 ret = wait_for_completion_interruptible_timeout(
6727 &pHddCtx->full_pwr_comp_var,
6728 msecs_to_jiffies(1000));
6729 if (ret <= 0)
6730 {
6731 hddLog(VOS_TRACE_LEVEL_ERROR,
6732 "%s: wait on full_pwr_comp_var failed %ld",
6733 __func__, ret);
6734 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006735 }
6736 else
6737 {
6738 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006739 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006740 VOS_ASSERT(0);
6741 return status;
6742 }
6743 }
6744
6745 status = VOS_STATUS_SUCCESS;
6746 }
6747
6748 break;
6749 }
6750 return status;
6751}
Katya Nigame7b69a82015-04-28 15:24:06 +05306752void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
6753 {
6754 hdd_mon_ctx_t *pMonCtx = NULL;
6755 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
6756
6757 pMonCtx->state = 0;
6758 pMonCtx->ChannelNo = 1;
6759 pMonCtx->ChannelBW = 20;
6760 pMonCtx->crcCheckEnabled = 0;
6761 pMonCtx->typeSubtypeBitmap = 0xFFFFFFFFFFFF;
6762 pMonCtx->is80211to803ConReq = 0;
6763 pMonCtx->numOfMacFilters = 0;
6764 }
6765
Jeff Johnson295189b2012-06-20 16:38:30 -07006766
6767hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006768 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006769 tANI_U8 rtnl_held )
6770{
6771 hdd_adapter_t *pAdapter = NULL;
6772 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6773 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6774 VOS_STATUS exitbmpsStatus;
6775
Arif Hussain6d2a3322013-11-17 19:50:10 -08006776 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006777
Nirav Shah436658f2014-02-28 17:05:45 +05306778 if(macAddr == NULL)
6779 {
6780 /* Not received valid macAddr */
6781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6782 "%s:Unable to add virtual intf: Not able to get"
6783 "valid mac address",__func__);
6784 return NULL;
6785 }
6786
Jeff Johnson295189b2012-06-20 16:38:30 -07006787 //Disable BMPS incase of Concurrency
6788 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6789
6790 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6791 {
6792 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306793 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006794 VOS_ASSERT(0);
6795 return NULL;
6796 }
6797
6798 switch(session_type)
6799 {
6800 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006801 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006802 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006803 {
6804 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6805
6806 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306807 {
6808 hddLog(VOS_TRACE_LEVEL_FATAL,
6809 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006810 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306811 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006812
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306813#ifdef FEATURE_WLAN_TDLS
6814 /* A Mutex Lock is introduced while changing/initializing the mode to
6815 * protect the concurrent access for the Adapters by TDLS module.
6816 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306817 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306818#endif
6819
Jeff Johnsone7245742012-09-05 17:12:55 -07006820 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6821 NL80211_IFTYPE_P2P_CLIENT:
6822 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006823
Jeff Johnson295189b2012-06-20 16:38:30 -07006824 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306825#ifdef FEATURE_WLAN_TDLS
6826 mutex_unlock(&pHddCtx->tdls_lock);
6827#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306828
6829 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006830 if( VOS_STATUS_SUCCESS != status )
6831 goto err_free_netdev;
6832
6833 status = hdd_register_interface( pAdapter, rtnl_held );
6834 if( VOS_STATUS_SUCCESS != status )
6835 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306836#ifdef FEATURE_WLAN_TDLS
6837 mutex_lock(&pHddCtx->tdls_lock);
6838#endif
c_hpothu002231a2015-02-05 14:58:51 +05306839 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306840#ifdef FEATURE_WLAN_TDLS
6841 mutex_unlock(&pHddCtx->tdls_lock);
6842#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006843 goto err_free_netdev;
6844 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306845
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306846 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306847 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306848
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306849#ifdef WLAN_NS_OFFLOAD
6850 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306851 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306852#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006853 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306854 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006855 netif_tx_disable(pAdapter->dev);
6856 //netif_tx_disable(pWlanDev);
6857 netif_carrier_off(pAdapter->dev);
6858
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306859 if (WLAN_HDD_P2P_CLIENT == session_type ||
6860 WLAN_HDD_P2P_DEVICE == session_type)
6861 {
6862 /* Initialize the work queue to defer the
6863 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306864 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306865 hdd_p2p_roc_work_queue);
6866 }
6867
Jeff Johnson295189b2012-06-20 16:38:30 -07006868 break;
6869 }
6870
Jeff Johnson295189b2012-06-20 16:38:30 -07006871 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006872 case WLAN_HDD_SOFTAP:
6873 {
6874 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6875 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306876 {
6877 hddLog(VOS_TRACE_LEVEL_FATAL,
6878 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006879 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306880 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006881
Jeff Johnson295189b2012-06-20 16:38:30 -07006882 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6883 NL80211_IFTYPE_AP:
6884 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006885 pAdapter->device_mode = session_type;
6886
6887 status = hdd_init_ap_mode(pAdapter);
6888 if( VOS_STATUS_SUCCESS != status )
6889 goto err_free_netdev;
6890
6891 status = hdd_register_hostapd( pAdapter, rtnl_held );
6892 if( VOS_STATUS_SUCCESS != status )
6893 {
c_hpothu002231a2015-02-05 14:58:51 +05306894 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006895 goto err_free_netdev;
6896 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306897 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006898 netif_tx_disable(pAdapter->dev);
6899 netif_carrier_off(pAdapter->dev);
6900
6901 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306902
6903 if (WLAN_HDD_P2P_GO == session_type)
6904 {
6905 /* Initialize the work queue to
6906 * defer the back to back RoC request */
6907 INIT_DELAYED_WORK(&pAdapter->roc_work,
6908 hdd_p2p_roc_work_queue);
6909 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006910 break;
6911 }
6912 case WLAN_HDD_MONITOR:
6913 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006914 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6915 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306916 {
6917 hddLog(VOS_TRACE_LEVEL_FATAL,
6918 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006919 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306920 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006921
Katya Nigame7b69a82015-04-28 15:24:06 +05306922 // Register wireless extensions
6923 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
6924 {
6925 hddLog(VOS_TRACE_LEVEL_FATAL,
6926 "hdd_register_wext() failed with status code %08d [x%08x]",
6927 status, status );
6928 status = VOS_STATUS_E_FAILURE;
6929 }
6930
Jeff Johnson295189b2012-06-20 16:38:30 -07006931 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6932 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006933#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6934 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6935#else
6936 pAdapter->dev->open = hdd_mon_open;
6937 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05306938 pAdapter->dev->stop = hdd_mon_stop;
6939 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006940#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05306941 status = hdd_register_interface( pAdapter, rtnl_held );
6942 hdd_init_mon_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006943 hdd_init_tx_rx( pAdapter );
6944 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05306945 //Stop the Interface TX queue.
6946 netif_tx_disable(pAdapter->dev);
6947 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006948 }
6949 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006950 case WLAN_HDD_FTM:
6951 {
6952 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6953
6954 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306955 {
6956 hddLog(VOS_TRACE_LEVEL_FATAL,
6957 FL("failed to allocate adapter for session %d"), session_type);
6958 return NULL;
6959 }
6960
Jeff Johnson295189b2012-06-20 16:38:30 -07006961 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6962 * message while loading driver in FTM mode. */
6963 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6964 pAdapter->device_mode = session_type;
6965 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306966
6967 hdd_init_tx_rx( pAdapter );
6968
6969 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306970 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306971 netif_tx_disable(pAdapter->dev);
6972 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006973 }
6974 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006975 default:
6976 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306977 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6978 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006979 VOS_ASSERT(0);
6980 return NULL;
6981 }
6982 }
6983
Jeff Johnson295189b2012-06-20 16:38:30 -07006984 if( VOS_STATUS_SUCCESS == status )
6985 {
6986 //Add it to the hdd's session list.
6987 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6988 if( NULL == pHddAdapterNode )
6989 {
6990 status = VOS_STATUS_E_NOMEM;
6991 }
6992 else
6993 {
6994 pHddAdapterNode->pAdapter = pAdapter;
6995 status = hdd_add_adapter_back ( pHddCtx,
6996 pHddAdapterNode );
6997 }
6998 }
6999
7000 if( VOS_STATUS_SUCCESS != status )
7001 {
7002 if( NULL != pAdapter )
7003 {
7004 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
7005 pAdapter = NULL;
7006 }
7007 if( NULL != pHddAdapterNode )
7008 {
7009 vos_mem_free( pHddAdapterNode );
7010 }
7011
7012 goto resume_bmps;
7013 }
7014
7015 if(VOS_STATUS_SUCCESS == status)
7016 {
7017 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
7018
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07007019 //Initialize the WoWL service
7020 if(!hdd_init_wowl(pAdapter))
7021 {
7022 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
7023 goto err_free_netdev;
7024 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007025 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007026 return pAdapter;
7027
7028err_free_netdev:
7029 free_netdev(pAdapter->dev);
7030 wlan_hdd_release_intf_addr( pHddCtx,
7031 pAdapter->macAddressCurrent.bytes );
7032
7033resume_bmps:
7034 //If bmps disabled enable it
7035 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
7036 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307037 if (pHddCtx->hdd_wlan_suspended)
7038 {
7039 hdd_set_pwrparams(pHddCtx);
7040 }
7041 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007042 }
7043 return NULL;
7044}
7045
7046VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7047 tANI_U8 rtnl_held )
7048{
7049 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
7050 VOS_STATUS status;
7051
7052 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
7053 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307054 {
7055 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
7056 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007057 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307058 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007059
7060 while ( pCurrent->pAdapter != pAdapter )
7061 {
7062 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
7063 if( VOS_STATUS_SUCCESS != status )
7064 break;
7065
7066 pCurrent = pNext;
7067 }
7068 pAdapterNode = pCurrent;
7069 if( VOS_STATUS_SUCCESS == status )
7070 {
7071 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7072 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307073
7074#ifdef FEATURE_WLAN_TDLS
7075
7076 /* A Mutex Lock is introduced while changing/initializing the mode to
7077 * protect the concurrent access for the Adapters by TDLS module.
7078 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307079 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307080#endif
7081
Jeff Johnson295189b2012-06-20 16:38:30 -07007082 hdd_remove_adapter( pHddCtx, pAdapterNode );
7083 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007084 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007085
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307086#ifdef FEATURE_WLAN_TDLS
7087 mutex_unlock(&pHddCtx->tdls_lock);
7088#endif
7089
Jeff Johnson295189b2012-06-20 16:38:30 -07007090
7091 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307092 if ((!vos_concurrent_open_sessions_running()) &&
7093 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7094 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007095 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307096 if (pHddCtx->hdd_wlan_suspended)
7097 {
7098 hdd_set_pwrparams(pHddCtx);
7099 }
7100 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007101 }
7102
7103 return VOS_STATUS_SUCCESS;
7104 }
7105
7106 return VOS_STATUS_E_FAILURE;
7107}
7108
7109VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7110{
7111 hdd_adapter_list_node_t *pHddAdapterNode;
7112 VOS_STATUS status;
7113
7114 ENTER();
7115
7116 do
7117 {
7118 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7119 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7120 {
7121 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7122 vos_mem_free( pHddAdapterNode );
7123 }
7124 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7125
7126 EXIT();
7127
7128 return VOS_STATUS_SUCCESS;
7129}
7130
7131void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7132{
7133 v_U8_t addIE[1] = {0};
7134
7135 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7136 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7137 eANI_BOOLEAN_FALSE) )
7138 {
7139 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007140 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007141 }
7142
7143 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7144 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7145 eANI_BOOLEAN_FALSE) )
7146 {
7147 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007148 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007149 }
7150
7151 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7152 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7153 eANI_BOOLEAN_FALSE) )
7154 {
7155 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007156 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007157 }
7158}
7159
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307160VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7161 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007162{
7163 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7164 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307165 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007166 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307167 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307168 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007169
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307170 if (pHddCtx->isLogpInProgress) {
7171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7172 "%s:LOGP in Progress. Ignore!!!",__func__);
7173 return VOS_STATUS_E_FAILURE;
7174 }
7175
Jeff Johnson295189b2012-06-20 16:38:30 -07007176 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307177
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307178 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007179 switch(pAdapter->device_mode)
7180 {
7181 case WLAN_HDD_INFRA_STATION:
7182 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007183 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307184 {
7185 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7186 if( hdd_connIsConnected(pstation) ||
7187 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007188 {
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307189#ifdef FEATURE_WLAN_TDLS
7190 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307191 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307192 mutex_unlock(&pHddCtx->tdls_lock);
7193#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007194 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7195 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7196 pAdapter->sessionId,
7197 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7198 else
7199 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7200 pAdapter->sessionId,
7201 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7202 //success implies disconnect command got queued up successfully
7203 if(halStatus == eHAL_STATUS_SUCCESS)
7204 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307205 ret = wait_for_completion_interruptible_timeout(
7206 &pAdapter->disconnect_comp_var,
7207 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7208 if (ret <= 0)
7209 {
7210 hddLog(VOS_TRACE_LEVEL_ERROR,
7211 "%s: wait on disconnect_comp_var failed %ld",
7212 __func__, ret);
7213 }
7214 }
7215 else
7216 {
7217 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7218 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007219 }
7220 memset(&wrqu, '\0', sizeof(wrqu));
7221 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7222 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7223 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7224 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307225 else if(pstation->conn_info.connState ==
7226 eConnectionState_Disconnecting)
7227 {
7228 ret = wait_for_completion_interruptible_timeout(
7229 &pAdapter->disconnect_comp_var,
7230 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7231 if (ret <= 0)
7232 {
7233 hddLog(VOS_TRACE_LEVEL_ERROR,
7234 FL("wait on disconnect_comp_var failed %ld"), ret);
7235 }
7236 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307237 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007238 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307239 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307240 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007241 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307242 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7243 {
7244 while (pAdapter->is_roc_inprogress)
7245 {
7246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7247 "%s: ROC in progress for session %d!!!",
7248 __func__, pAdapter->sessionId);
7249 // waiting for ROC to expire
7250 msleep(500);
7251 /* In GO present case , if retry exceeds 3,
7252 it means something went wrong. */
7253 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7254 {
7255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7256 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307257 if (eHAL_STATUS_SUCCESS !=
7258 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7259 pAdapter->sessionId ))
7260 {
7261 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7262 FL("Failed to Cancel Remain on Channel"));
7263 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307264 wait_for_completion_interruptible_timeout(
7265 &pAdapter->cancel_rem_on_chan_var,
7266 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7267 break;
7268 }
7269 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307270 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307271 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307272#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307273 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307274#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307275
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307276 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307277
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307278 /* It is possible that the caller of this function does not
7279 * wish to close the session
7280 */
7281 if (VOS_TRUE == bCloseSession &&
7282 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007283 {
7284 INIT_COMPLETION(pAdapter->session_close_comp_var);
7285 if (eHAL_STATUS_SUCCESS ==
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307286 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
7287 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007288 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307289 unsigned long ret;
7290
Jeff Johnson295189b2012-06-20 16:38:30 -07007291 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307292 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307293 &pAdapter->session_close_comp_var,
7294 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307295 if ( 0 >= ret)
7296 {
7297 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307298 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307299 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007300 }
7301 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307302 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007303 break;
7304
7305 case WLAN_HDD_SOFTAP:
7306 case WLAN_HDD_P2P_GO:
7307 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307308 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7309 while (pAdapter->is_roc_inprogress) {
7310 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7311 "%s: ROC in progress for session %d!!!",
7312 __func__, pAdapter->sessionId);
7313 msleep(500);
7314 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7316 "%s: ROC completion is not received.!!!", __func__);
7317 WLANSAP_CancelRemainOnChannel(
7318 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7319 wait_for_completion_interruptible_timeout(
7320 &pAdapter->cancel_rem_on_chan_var,
7321 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7322 break;
7323 }
7324 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307325
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307326 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307327 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007328 mutex_lock(&pHddCtx->sap_lock);
7329 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7330 {
7331 VOS_STATUS status;
7332 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7333
7334 //Stop Bss.
7335 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7336 if (VOS_IS_STATUS_SUCCESS(status))
7337 {
7338 hdd_hostapd_state_t *pHostapdState =
7339 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7340
7341 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7342
7343 if (!VOS_IS_STATUS_SUCCESS(status))
7344 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307345 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7346 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007347 }
7348 }
7349 else
7350 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007351 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007352 }
7353 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307354 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007355
7356 if (eHAL_STATUS_FAILURE ==
7357 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7358 0, NULL, eANI_BOOLEAN_FALSE))
7359 {
7360 hddLog(LOGE,
7361 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007362 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007363 }
7364
7365 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7366 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7367 eANI_BOOLEAN_FALSE) )
7368 {
7369 hddLog(LOGE,
7370 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7371 }
7372
7373 // Reset WNI_CFG_PROBE_RSP Flags
7374 wlan_hdd_reset_prob_rspies(pAdapter);
7375 kfree(pAdapter->sessionCtx.ap.beacon);
7376 pAdapter->sessionCtx.ap.beacon = NULL;
7377 }
7378 mutex_unlock(&pHddCtx->sap_lock);
7379 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007380
Jeff Johnson295189b2012-06-20 16:38:30 -07007381 case WLAN_HDD_MONITOR:
7382 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007383
Jeff Johnson295189b2012-06-20 16:38:30 -07007384 default:
7385 break;
7386 }
7387
7388 EXIT();
7389 return VOS_STATUS_SUCCESS;
7390}
7391
7392VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7393{
7394 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7395 VOS_STATUS status;
7396 hdd_adapter_t *pAdapter;
7397
7398 ENTER();
7399
7400 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7401
7402 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7403 {
7404 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007405
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307406 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007407
7408 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7409 pAdapterNode = pNext;
7410 }
7411
7412 EXIT();
7413
7414 return VOS_STATUS_SUCCESS;
7415}
7416
Rajeev Kumarf999e582014-01-09 17:33:29 -08007417
7418#ifdef FEATURE_WLAN_BATCH_SCAN
7419/**---------------------------------------------------------------------------
7420
7421 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7422 structures
7423
7424 \param - pAdapter Pointer to HDD adapter
7425
7426 \return - None
7427
7428 --------------------------------------------------------------------------*/
7429void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7430{
7431 tHddBatchScanRsp *pNode;
7432 tHddBatchScanRsp *pPrev;
7433
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307434 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007435 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307436 hddLog(VOS_TRACE_LEVEL_ERROR,
7437 "%s: Adapter context is Null", __func__);
7438 return;
7439 }
7440
7441 pNode = pAdapter->pBatchScanRsp;
7442 while (pNode)
7443 {
7444 pPrev = pNode;
7445 pNode = pNode->pNext;
7446 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007447 }
7448
7449 pAdapter->pBatchScanRsp = NULL;
7450 pAdapter->numScanList = 0;
7451 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7452 pAdapter->prev_batch_id = 0;
7453
7454 return;
7455}
7456#endif
7457
7458
Jeff Johnson295189b2012-06-20 16:38:30 -07007459VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7460{
7461 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7462 VOS_STATUS status;
7463 hdd_adapter_t *pAdapter;
7464
7465 ENTER();
7466
7467 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7468
7469 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7470 {
7471 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307472 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007473 netif_tx_disable(pAdapter->dev);
7474 netif_carrier_off(pAdapter->dev);
7475
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007476 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7477
Jeff Johnson295189b2012-06-20 16:38:30 -07007478 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307479
Katya Nigam1fd24402015-02-16 14:52:19 +05307480 if(pAdapter->device_mode == WLAN_HDD_IBSS )
7481 hdd_ibss_deinit_tx_rx(pAdapter);
7482
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307483 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7484
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307485 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7486 {
7487 hdd_wmm_adapter_close( pAdapter );
7488 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7489 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007490
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307491 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7492 {
7493 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7494 }
7495
Rajeev Kumarf999e582014-01-09 17:33:29 -08007496#ifdef FEATURE_WLAN_BATCH_SCAN
7497 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7498 {
7499 hdd_deinit_batch_scan(pAdapter);
7500 }
7501#endif
7502
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307503#ifdef FEATURE_WLAN_TDLS
7504 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307505 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307506 mutex_unlock(&pHddCtx->tdls_lock);
7507#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007508 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7509 pAdapterNode = pNext;
7510 }
7511
7512 EXIT();
7513
7514 return VOS_STATUS_SUCCESS;
7515}
7516
7517VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7518{
7519 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7520 VOS_STATUS status;
7521 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307522 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007523
7524 ENTER();
7525
7526 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7527
7528 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7529 {
7530 pAdapter = pAdapterNode->pAdapter;
7531
Kumar Anand82c009f2014-05-29 00:29:42 -07007532 hdd_wmm_init( pAdapter );
7533
Jeff Johnson295189b2012-06-20 16:38:30 -07007534 switch(pAdapter->device_mode)
7535 {
7536 case WLAN_HDD_INFRA_STATION:
7537 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007538 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307539
7540 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7541
Jeff Johnson295189b2012-06-20 16:38:30 -07007542 hdd_init_station_mode(pAdapter);
7543 /* Open the gates for HDD to receive Wext commands */
7544 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007545 pHddCtx->scan_info.mScanPending = FALSE;
7546 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007547
7548 //Trigger the initial scan
7549 hdd_wlan_initial_scan(pAdapter);
7550
7551 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307552 if (eConnectionState_Associated == connState ||
7553 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007554 {
7555 union iwreq_data wrqu;
7556 memset(&wrqu, '\0', sizeof(wrqu));
7557 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7558 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7559 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007560 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007561
Jeff Johnson295189b2012-06-20 16:38:30 -07007562 /* indicate disconnected event to nl80211 */
7563 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7564 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007565 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307566 else if (eConnectionState_Connecting == connState)
7567 {
7568 /*
7569 * Indicate connect failure to supplicant if we were in the
7570 * process of connecting
7571 */
7572 cfg80211_connect_result(pAdapter->dev, NULL,
7573 NULL, 0, NULL, 0,
7574 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7575 GFP_KERNEL);
7576 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007577 break;
7578
7579 case WLAN_HDD_SOFTAP:
7580 /* softAP can handle SSR */
7581 break;
7582
7583 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007584 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007585 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007586 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007587 break;
7588
7589 case WLAN_HDD_MONITOR:
7590 /* monitor interface start */
7591 break;
7592 default:
7593 break;
7594 }
7595
7596 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7597 pAdapterNode = pNext;
7598 }
7599
7600 EXIT();
7601
7602 return VOS_STATUS_SUCCESS;
7603}
7604
7605VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7606{
7607 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7608 hdd_adapter_t *pAdapter;
7609 VOS_STATUS status;
7610 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307611 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007612
7613 ENTER();
7614
7615 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7616
7617 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7618 {
7619 pAdapter = pAdapterNode->pAdapter;
7620
7621 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7622 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7623 {
7624 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7625 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7626
Abhishek Singhf4669da2014-05-26 15:07:49 +05307627 hddLog(VOS_TRACE_LEVEL_INFO,
7628 "%s: Set HDD connState to eConnectionState_NotConnected",
7629 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007630 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7631 init_completion(&pAdapter->disconnect_comp_var);
7632 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7633 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7634
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307635 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007636 &pAdapter->disconnect_comp_var,
7637 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307638 if (0 >= ret)
7639 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7640 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007641
7642 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7643 pHddCtx->isAmpAllowed = VOS_FALSE;
7644 sme_RoamConnect(pHddCtx->hHal,
7645 pAdapter->sessionId, &(pWextState->roamProfile),
7646 &roamId);
7647 }
7648
7649 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7650 pAdapterNode = pNext;
7651 }
7652
7653 EXIT();
7654
7655 return VOS_STATUS_SUCCESS;
7656}
7657
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007658void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7659{
7660 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7661 VOS_STATUS status;
7662 hdd_adapter_t *pAdapter;
7663 hdd_station_ctx_t *pHddStaCtx;
7664 hdd_ap_ctx_t *pHddApCtx;
7665 hdd_hostapd_state_t * pHostapdState;
7666 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7667 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7668 const char *p2pMode = "DEV";
7669 const char *ccMode = "Standalone";
7670 int n;
7671
7672 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7673 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7674 {
7675 pAdapter = pAdapterNode->pAdapter;
7676 switch (pAdapter->device_mode) {
7677 case WLAN_HDD_INFRA_STATION:
7678 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7679 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7680 staChannel = pHddStaCtx->conn_info.operationChannel;
7681 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7682 }
7683 break;
7684 case WLAN_HDD_P2P_CLIENT:
7685 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7686 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7687 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7688 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7689 p2pMode = "CLI";
7690 }
7691 break;
7692 case WLAN_HDD_P2P_GO:
7693 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7694 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7695 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7696 p2pChannel = pHddApCtx->operatingChannel;
7697 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7698 }
7699 p2pMode = "GO";
7700 break;
7701 case WLAN_HDD_SOFTAP:
7702 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7703 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7704 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7705 apChannel = pHddApCtx->operatingChannel;
7706 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7707 }
7708 break;
7709 default:
7710 break;
7711 }
7712 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7713 pAdapterNode = pNext;
7714 }
7715 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7716 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7717 }
7718 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7719 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7720 if (p2pChannel > 0) {
7721 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7722 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7723 }
7724 if (apChannel > 0) {
7725 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7726 apChannel, MAC_ADDR_ARRAY(apBssid));
7727 }
7728
7729 if (p2pChannel > 0 && apChannel > 0) {
7730 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7731 }
7732}
7733
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007734bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007735{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007736 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007737}
7738
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007739/* Once SSR is disabled then it cannot be set. */
7740void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007741{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007742 if (HDD_SSR_DISABLED == isSsrRequired)
7743 return;
7744
Jeff Johnson295189b2012-06-20 16:38:30 -07007745 isSsrRequired = value;
7746}
7747
7748VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7749 hdd_adapter_list_node_t** ppAdapterNode)
7750{
7751 VOS_STATUS status;
7752 spin_lock(&pHddCtx->hddAdapters.lock);
7753 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7754 (hdd_list_node_t**) ppAdapterNode );
7755 spin_unlock(&pHddCtx->hddAdapters.lock);
7756 return status;
7757}
7758
7759VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7760 hdd_adapter_list_node_t* pAdapterNode,
7761 hdd_adapter_list_node_t** pNextAdapterNode)
7762{
7763 VOS_STATUS status;
7764 spin_lock(&pHddCtx->hddAdapters.lock);
7765 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7766 (hdd_list_node_t*) pAdapterNode,
7767 (hdd_list_node_t**)pNextAdapterNode );
7768
7769 spin_unlock(&pHddCtx->hddAdapters.lock);
7770 return status;
7771}
7772
7773VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7774 hdd_adapter_list_node_t* pAdapterNode)
7775{
7776 VOS_STATUS status;
7777 spin_lock(&pHddCtx->hddAdapters.lock);
7778 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7779 &pAdapterNode->node );
7780 spin_unlock(&pHddCtx->hddAdapters.lock);
7781 return status;
7782}
7783
7784VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7785 hdd_adapter_list_node_t** ppAdapterNode)
7786{
7787 VOS_STATUS status;
7788 spin_lock(&pHddCtx->hddAdapters.lock);
7789 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7790 (hdd_list_node_t**) ppAdapterNode );
7791 spin_unlock(&pHddCtx->hddAdapters.lock);
7792 return status;
7793}
7794
7795VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7796 hdd_adapter_list_node_t* pAdapterNode)
7797{
7798 VOS_STATUS status;
7799 spin_lock(&pHddCtx->hddAdapters.lock);
7800 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7801 (hdd_list_node_t*) pAdapterNode );
7802 spin_unlock(&pHddCtx->hddAdapters.lock);
7803 return status;
7804}
7805
7806VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7807 hdd_adapter_list_node_t* pAdapterNode)
7808{
7809 VOS_STATUS status;
7810 spin_lock(&pHddCtx->hddAdapters.lock);
7811 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7812 (hdd_list_node_t*) pAdapterNode );
7813 spin_unlock(&pHddCtx->hddAdapters.lock);
7814 return status;
7815}
7816
7817hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7818 tSirMacAddr macAddr )
7819{
7820 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7821 hdd_adapter_t *pAdapter;
7822 VOS_STATUS status;
7823
7824 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7825
7826 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7827 {
7828 pAdapter = pAdapterNode->pAdapter;
7829
7830 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7831 macAddr, sizeof(tSirMacAddr) ) )
7832 {
7833 return pAdapter;
7834 }
7835 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7836 pAdapterNode = pNext;
7837 }
7838
7839 return NULL;
7840
7841}
7842
7843hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7844{
7845 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7846 hdd_adapter_t *pAdapter;
7847 VOS_STATUS status;
7848
7849 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7850
7851 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7852 {
7853 pAdapter = pAdapterNode->pAdapter;
7854
7855 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7856 IFNAMSIZ ) )
7857 {
7858 return pAdapter;
7859 }
7860 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7861 pAdapterNode = pNext;
7862 }
7863
7864 return NULL;
7865
7866}
7867
7868hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7869{
7870 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7871 hdd_adapter_t *pAdapter;
7872 VOS_STATUS status;
7873
7874 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7875
7876 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7877 {
7878 pAdapter = pAdapterNode->pAdapter;
7879
7880 if( pAdapter && (mode == pAdapter->device_mode) )
7881 {
7882 return pAdapter;
7883 }
7884 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7885 pAdapterNode = pNext;
7886 }
7887
7888 return NULL;
7889
7890}
7891
7892//Remove this function later
7893hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7894{
7895 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7896 hdd_adapter_t *pAdapter;
7897 VOS_STATUS status;
7898
7899 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7900
7901 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7902 {
7903 pAdapter = pAdapterNode->pAdapter;
7904
7905 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7906 {
7907 return pAdapter;
7908 }
7909
7910 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7911 pAdapterNode = pNext;
7912 }
7913
7914 return NULL;
7915
7916}
7917
Jeff Johnson295189b2012-06-20 16:38:30 -07007918/**---------------------------------------------------------------------------
7919
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307920 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007921
7922 This API returns the operating channel of the requested device mode
7923
7924 \param - pHddCtx - Pointer to the HDD context.
7925 - mode - Device mode for which operating channel is required
7926 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7927 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7928 \return - channel number. "0" id the requested device is not found OR it is not connected.
7929 --------------------------------------------------------------------------*/
7930v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7931{
7932 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7933 VOS_STATUS status;
7934 hdd_adapter_t *pAdapter;
7935 v_U8_t operatingChannel = 0;
7936
7937 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7938
7939 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7940 {
7941 pAdapter = pAdapterNode->pAdapter;
7942
7943 if( mode == pAdapter->device_mode )
7944 {
7945 switch(pAdapter->device_mode)
7946 {
7947 case WLAN_HDD_INFRA_STATION:
7948 case WLAN_HDD_P2P_CLIENT:
7949 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7950 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7951 break;
7952 case WLAN_HDD_SOFTAP:
7953 case WLAN_HDD_P2P_GO:
7954 /*softap connection info */
7955 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7956 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7957 break;
7958 default:
7959 break;
7960 }
7961
7962 break; //Found the device of interest. break the loop
7963 }
7964
7965 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7966 pAdapterNode = pNext;
7967 }
7968 return operatingChannel;
7969}
7970
7971#ifdef WLAN_FEATURE_PACKET_FILTERING
7972/**---------------------------------------------------------------------------
7973
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307974 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007975
7976 This used to set the multicast address list.
7977
7978 \param - dev - Pointer to the WLAN device.
7979 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307980 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07007981
7982 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307983static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007984{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307985 hdd_adapter_t *pAdapter;
7986 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007987 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307988 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007989 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307990
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307991 ENTER();
7992
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307993 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307994 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007995 {
7996 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307997 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007998 return;
7999 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308000 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8001 ret = wlan_hdd_validate_context(pHddCtx);
8002 if (0 != ret)
8003 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308004 return;
8005 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008006 if (dev->flags & IFF_ALLMULTI)
8007 {
8008 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008009 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308010 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008011 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308012 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008013 {
8014 mc_count = netdev_mc_count(dev);
8015 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008016 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07008017 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
8018 {
8019 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008020 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308021 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008022 return;
8023 }
8024
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308025 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07008026
8027 netdev_for_each_mc_addr(ha, dev) {
8028 if (i == mc_count)
8029 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308030 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
8031 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008032 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308033 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308034 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07008035 i++;
8036 }
8037 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308038
8039 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008040 return;
8041}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308042
8043static void hdd_set_multicast_list(struct net_device *dev)
8044{
8045 vos_ssr_protect(__func__);
8046 __hdd_set_multicast_list(dev);
8047 vos_ssr_unprotect(__func__);
8048}
Jeff Johnson295189b2012-06-20 16:38:30 -07008049#endif
8050
8051/**---------------------------------------------------------------------------
8052
8053 \brief hdd_select_queue() -
8054
8055 This function is registered with the Linux OS for network
8056 core to decide which queue to use first.
8057
8058 \param - dev - Pointer to the WLAN device.
8059 - skb - Pointer to OS packet (sk_buff).
8060 \return - ac, Queue Index/access category corresponding to UP in IP header
8061
8062 --------------------------------------------------------------------------*/
8063v_U16_t hdd_select_queue(struct net_device *dev,
8064 struct sk_buff *skb)
8065{
8066 return hdd_wmm_select_queue(dev, skb);
8067}
8068
8069
8070/**---------------------------------------------------------------------------
8071
8072 \brief hdd_wlan_initial_scan() -
8073
8074 This function triggers the initial scan
8075
8076 \param - pAdapter - Pointer to the HDD adapter.
8077
8078 --------------------------------------------------------------------------*/
8079void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8080{
8081 tCsrScanRequest scanReq;
8082 tCsrChannelInfo channelInfo;
8083 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008084 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008085 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8086
8087 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8088 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8089 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8090
8091 if(sme_Is11dSupported(pHddCtx->hHal))
8092 {
8093 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8094 if ( HAL_STATUS_SUCCESS( halStatus ) )
8095 {
8096 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8097 if( !scanReq.ChannelInfo.ChannelList )
8098 {
8099 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8100 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008101 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008102 return;
8103 }
8104 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8105 channelInfo.numOfChannels);
8106 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8107 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008108 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008109 }
8110
8111 scanReq.scanType = eSIR_PASSIVE_SCAN;
8112 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8113 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8114 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8115 }
8116 else
8117 {
8118 scanReq.scanType = eSIR_ACTIVE_SCAN;
8119 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8120 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8121 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8122 }
8123
8124 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8125 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8126 {
8127 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8128 __func__, halStatus );
8129 }
8130
8131 if(sme_Is11dSupported(pHddCtx->hHal))
8132 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8133}
8134
Jeff Johnson295189b2012-06-20 16:38:30 -07008135/**---------------------------------------------------------------------------
8136
8137 \brief hdd_full_power_callback() - HDD full power callback function
8138
8139 This is the function invoked by SME to inform the result of a full power
8140 request issued by HDD
8141
8142 \param - callbackcontext - Pointer to cookie
8143 \param - status - result of request
8144
8145 \return - None
8146
8147 --------------------------------------------------------------------------*/
8148static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8149{
Jeff Johnson72a40512013-12-19 10:14:15 -08008150 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008151
8152 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308153 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008154
8155 if (NULL == callbackContext)
8156 {
8157 hddLog(VOS_TRACE_LEVEL_ERROR,
8158 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008159 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008160 return;
8161 }
8162
Jeff Johnson72a40512013-12-19 10:14:15 -08008163 /* there is a race condition that exists between this callback
8164 function and the caller since the caller could time out either
8165 before or while this code is executing. we use a spinlock to
8166 serialize these actions */
8167 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008168
8169 if (POWER_CONTEXT_MAGIC != pContext->magic)
8170 {
8171 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008172 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008173 hddLog(VOS_TRACE_LEVEL_WARN,
8174 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008175 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008176 return;
8177 }
8178
Jeff Johnson72a40512013-12-19 10:14:15 -08008179 /* context is valid so caller is still waiting */
8180
8181 /* paranoia: invalidate the magic */
8182 pContext->magic = 0;
8183
8184 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008185 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008186
8187 /* serialization is complete */
8188 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008189}
8190
Katya Nigamf0511f62015-05-05 16:40:57 +05308191void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
8192{
8193 pMonCtx->typeSubtypeBitmap = 0;
8194 if( type%10 ) /* Management Packets */
8195 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
8196 type/=10;
8197 if( type%10 ) /* Control Packets */
8198 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
8199 type/=10;
8200 if( type%10 ) /* Data Packets */
8201 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
8202}
8203
8204VOS_STATUS wlan_hdd_mon_poststartmsg( hdd_mon_ctx_t *pMonCtx )
8205{
8206 vos_msg_t monMsg;
8207
8208 monMsg.type = WDA_MON_START_REQ;
8209 monMsg.reserved = 0;
8210 monMsg.bodyptr = (v_U8_t*)pMonCtx;
8211 monMsg.bodyval = 0;
8212
8213 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8214 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8215 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8216 return VOS_STATUS_E_FAILURE;
8217 }
8218
8219 return VOS_STATUS_SUCCESS;
8220}
8221
8222void wlan_hdd_mon_poststopmsg(void)
8223{
8224 vos_msg_t monMsg;
8225
8226 monMsg.type = WDA_MON_STOP_REQ;
8227 monMsg.reserved = 0;
8228 monMsg.bodyptr = NULL;
8229 monMsg.bodyval = 0;
8230
8231 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8232 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8233 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8234 }
8235}
8236
Katya Nigame7b69a82015-04-28 15:24:06 +05308237void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
8238{
8239 VOS_STATUS vosStatus;
8240 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8241 struct wiphy *wiphy = pHddCtx->wiphy;
8242
8243 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
8244 if(pAdapter == NULL || pVosContext == NULL)
8245 {
8246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
8247 return ;
8248 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308249
8250 wlan_hdd_mon_poststopmsg();
Katya Nigame7b69a82015-04-28 15:24:06 +05308251 hdd_UnregisterWext(pAdapter->dev);
8252
8253 vos_mon_stop( pVosContext );
8254
8255 vosStatus = vos_sched_close( pVosContext );
8256 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8257 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8258 "%s: Failed to close VOSS Scheduler",__func__);
8259 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8260 }
8261
8262 vosStatus = vos_nv_close();
8263 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8264 {
8265 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8266 "%s: Failed to close NV", __func__);
8267 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8268 }
8269
8270 vos_close(pVosContext);
8271
8272 #ifdef WLAN_KD_READY_NOTIFIER
8273 nl_srv_exit(pHddCtx->ptt_pid);
8274 #else
8275 nl_srv_exit();
8276 #endif
8277
8278 if (pHddCtx->cfg_ini)
8279 {
8280 kfree(pHddCtx->cfg_ini);
8281 pHddCtx->cfg_ini= NULL;
8282 }
8283 hdd_close_all_adapters( pHddCtx );
8284
8285 wiphy_free(wiphy) ;
8286
8287}
Jeff Johnson295189b2012-06-20 16:38:30 -07008288/**---------------------------------------------------------------------------
8289
8290 \brief hdd_wlan_exit() - HDD WLAN exit function
8291
8292 This is the driver exit point (invoked during rmmod)
8293
8294 \param - pHddCtx - Pointer to the HDD Context
8295
8296 \return - None
8297
8298 --------------------------------------------------------------------------*/
8299void hdd_wlan_exit(hdd_context_t *pHddCtx)
8300{
8301 eHalStatus halStatus;
8302 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8303 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308304 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008305 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008306 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008307 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308308 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008309
8310 ENTER();
8311
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308312
Katya Nigame7b69a82015-04-28 15:24:06 +05308313 if (VOS_MONITOR_MODE == hdd_get_conparam())
8314 {
8315 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
8316 wlan_hdd_mon_close(pHddCtx);
8317 return;
8318 }
8319 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08008320 {
8321 // Unloading, restart logic is no more required.
8322 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008323
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308324#ifdef FEATURE_WLAN_TDLS
8325 /* At the time of driver unloading; if tdls connection is present;
8326 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8327 * wlan_hdd_tdls_find_peer always checks for valid context;
8328 * as load/unload in progress there can be a race condition.
8329 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8330 * when tdls state is enabled.
8331 * As soon as driver set load/unload flag; tdls flag also needs
8332 * to be disabled so that hdd_rx_packet_cbk won't call
8333 * wlan_hdd_tdls_find_peer.
8334 */
8335 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8336#endif
8337
c_hpothu5ab05e92014-06-13 17:34:05 +05308338 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8339 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008340 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308341 pAdapter = pAdapterNode->pAdapter;
8342 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008343 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308344 /* Disable TX on the interface, after this hard_start_xmit() will
8345 * not be called on that interface
8346 */
8347 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8348 netif_tx_disable(pAdapter->dev);
8349
8350 /* Mark the interface status as "down" for outside world */
8351 netif_carrier_off(pAdapter->dev);
8352
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308353 /* DeInit the adapter. This ensures that all data packets
8354 * are freed.
8355 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308356#ifdef FEATURE_WLAN_TDLS
8357 mutex_lock(&pHddCtx->tdls_lock);
8358#endif
c_hpothu002231a2015-02-05 14:58:51 +05308359 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308360#ifdef FEATURE_WLAN_TDLS
8361 mutex_unlock(&pHddCtx->tdls_lock);
8362#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308363
c_hpothu5ab05e92014-06-13 17:34:05 +05308364 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8365 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8366 {
8367 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8368 hdd_UnregisterWext(pAdapter->dev);
8369 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308370
Jeff Johnson295189b2012-06-20 16:38:30 -07008371 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308372 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8373 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008374 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308375 // Cancel any outstanding scan requests. We are about to close all
8376 // of our adapters, but an adapter structure is what SME passes back
8377 // to our callback function. Hence if there are any outstanding scan
8378 // requests then there is a race condition between when the adapter
8379 // is closed and when the callback is invoked.We try to resolve that
8380 // race condition here by canceling any outstanding scans before we
8381 // close the adapters.
8382 // Note that the scans may be cancelled in an asynchronous manner,
8383 // so ideally there needs to be some kind of synchronization. Rather
8384 // than introduce a new synchronization here, we will utilize the
8385 // fact that we are about to Request Full Power, and since that is
8386 // synchronized, the expectation is that by the time Request Full
8387 // Power has completed all scans will be cancelled.
8388 if (pHddCtx->scan_info.mScanPending)
8389 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308390 if(NULL != pAdapter)
8391 {
8392 hddLog(VOS_TRACE_LEVEL_INFO,
8393 FL("abort scan mode: %d sessionId: %d"),
8394 pAdapter->device_mode,
8395 pAdapter->sessionId);
8396 }
8397 hdd_abort_mac_scan(pHddCtx,
8398 pHddCtx->scan_info.sessionId,
8399 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308400 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008401 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308402 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008403 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308404 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308405 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8406 {
8407 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8408 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8409 "%s: in middle of FTM START", __func__);
8410 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8411 msecs_to_jiffies(20000));
8412 if(!lrc)
8413 {
8414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8415 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8416 }
8417 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008418 wlan_hdd_ftm_close(pHddCtx);
8419 goto free_hdd_ctx;
8420 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308421
Jeff Johnson295189b2012-06-20 16:38:30 -07008422 /* DeRegister with platform driver as client for Suspend/Resume */
8423 vosStatus = hddDeregisterPmOps(pHddCtx);
8424 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8425 {
8426 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8427 VOS_ASSERT(0);
8428 }
8429
8430 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8431 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8432 {
8433 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8434 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008435
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008436 //Stop the traffic monitor timer
8437 if ( VOS_TIMER_STATE_RUNNING ==
8438 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8439 {
8440 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8441 }
8442
8443 // Destroy the traffic monitor timer
8444 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8445 &pHddCtx->tx_rx_trafficTmr)))
8446 {
8447 hddLog(VOS_TRACE_LEVEL_ERROR,
8448 "%s: Cannot deallocate Traffic monitor timer", __func__);
8449 }
8450
Jeff Johnson295189b2012-06-20 16:38:30 -07008451 //Disable IMPS/BMPS as we do not want the device to enter any power
8452 //save mode during shutdown
8453 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8454 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8455 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8456
8457 //Ensure that device is in full power as we will touch H/W during vos_Stop
8458 init_completion(&powerContext.completion);
8459 powerContext.magic = POWER_CONTEXT_MAGIC;
8460
8461 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8462 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8463
8464 if (eHAL_STATUS_SUCCESS != halStatus)
8465 {
8466 if (eHAL_STATUS_PMC_PENDING == halStatus)
8467 {
8468 /* request was sent -- wait for the response */
8469 lrc = wait_for_completion_interruptible_timeout(
8470 &powerContext.completion,
8471 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008472 if (lrc <= 0)
8473 {
8474 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008475 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008476 }
8477 }
8478 else
8479 {
8480 hddLog(VOS_TRACE_LEVEL_ERROR,
8481 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008482 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008483 /* continue -- need to clean up as much as possible */
8484 }
8485 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +05308486 if ((eHAL_STATUS_SUCCESS == halStatus) ||
8487 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
8488 {
8489 /* This will issue a dump command which will clean up
8490 BTQM queues and unblock MC thread */
8491 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
8492 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008493
Jeff Johnson72a40512013-12-19 10:14:15 -08008494 /* either we never sent a request, we sent a request and received a
8495 response or we sent a request and timed out. if we never sent a
8496 request or if we sent a request and got a response, we want to
8497 clear the magic out of paranoia. if we timed out there is a
8498 race condition such that the callback function could be
8499 executing at the same time we are. of primary concern is if the
8500 callback function had already verified the "magic" but had not
8501 yet set the completion variable when a timeout occurred. we
8502 serialize these activities by invalidating the magic while
8503 holding a shared spinlock which will cause us to block if the
8504 callback is currently executing */
8505 spin_lock(&hdd_context_lock);
8506 powerContext.magic = 0;
8507 spin_unlock(&hdd_context_lock);
8508
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +05308509 /* If Device is shutdown, no point for SME to wait for responses
8510 from device. Pre Close SME */
8511 if(wcnss_device_is_shutdown())
8512 {
8513 sme_PreClose(pHddCtx->hHal);
8514 }
Yue Ma0d4891e2013-08-06 17:01:45 -07008515 hdd_debugfs_exit(pHddCtx);
8516
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308517#ifdef WLAN_NS_OFFLOAD
8518 hddLog(LOGE, FL("Unregister IPv6 notifier"));
8519 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8520#endif
8521 hddLog(LOGE, FL("Unregister IPv4 notifier"));
8522 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8523
Jeff Johnson295189b2012-06-20 16:38:30 -07008524 // Unregister the Net Device Notifier
8525 unregister_netdevice_notifier(&hdd_netdev_notifier);
8526
Jeff Johnson295189b2012-06-20 16:38:30 -07008527 hdd_stop_all_adapters( pHddCtx );
8528
Jeff Johnson295189b2012-06-20 16:38:30 -07008529#ifdef WLAN_BTAMP_FEATURE
8530 vosStatus = WLANBAP_Stop(pVosContext);
8531 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8532 {
8533 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8534 "%s: Failed to stop BAP",__func__);
8535 }
8536#endif //WLAN_BTAMP_FEATURE
8537
8538 //Stop all the modules
8539 vosStatus = vos_stop( pVosContext );
8540 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8541 {
8542 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8543 "%s: Failed to stop VOSS",__func__);
8544 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8545 }
8546
Jeff Johnson295189b2012-06-20 16:38:30 -07008547 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008548 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008549
8550 //Close the scheduler before calling vos_close to make sure no thread is
8551 // scheduled after the each module close is called i.e after all the data
8552 // structures are freed.
8553 vosStatus = vos_sched_close( pVosContext );
8554 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8555 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8556 "%s: Failed to close VOSS Scheduler",__func__);
8557 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8558 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008559#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008560#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8561 /* Destroy the wake lock */
8562 wake_lock_destroy(&pHddCtx->rx_wake_lock);
8563#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008564 /* Destroy the wake lock */
8565 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008566#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008567
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308568#ifdef CONFIG_ENABLE_LINUX_REG
8569 vosStatus = vos_nv_close();
8570 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8571 {
8572 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8573 "%s: Failed to close NV", __func__);
8574 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8575 }
8576#endif
8577
Jeff Johnson295189b2012-06-20 16:38:30 -07008578 //Close VOSS
8579 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8580 vos_close(pVosContext);
8581
Jeff Johnson295189b2012-06-20 16:38:30 -07008582 //Close Watchdog
8583 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8584 vos_watchdog_close(pVosContext);
8585
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308586 //Clean up HDD Nlink Service
8587 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308588
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308589#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308590 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308591 {
8592 wlan_logging_sock_deactivate_svc();
8593 }
8594#endif
8595
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308596#ifdef WLAN_KD_READY_NOTIFIER
8597 nl_srv_exit(pHddCtx->ptt_pid);
8598#else
8599 nl_srv_exit();
8600#endif /* WLAN_KD_READY_NOTIFIER */
8601
8602
Jeff Johnson295189b2012-06-20 16:38:30 -07008603 hdd_close_all_adapters( pHddCtx );
8604
Jeff Johnson295189b2012-06-20 16:38:30 -07008605 /* free the power on lock from platform driver */
8606 if (free_riva_power_on_lock("wlan"))
8607 {
8608 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8609 __func__);
8610 }
8611
Jeff Johnson88ba7742013-02-27 14:36:02 -08008612free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308613
8614 //Free up dynamically allocated members inside HDD Adapter
8615 if (pHddCtx->cfg_ini)
8616 {
8617 kfree(pHddCtx->cfg_ini);
8618 pHddCtx->cfg_ini= NULL;
8619 }
8620
Leo Changf04ddad2013-09-18 13:46:38 -07008621 /* FTM mode, WIPHY did not registered
8622 If un-register here, system crash will happen */
8623 if (VOS_FTM_MODE != hdd_get_conparam())
8624 {
8625 wiphy_unregister(wiphy) ;
8626 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008627 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008628 if (hdd_is_ssr_required())
8629 {
8630 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008631 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008632 msleep(5000);
8633 }
8634 hdd_set_ssr_required (VOS_FALSE);
8635}
8636
8637
8638/**---------------------------------------------------------------------------
8639
8640 \brief hdd_update_config_from_nv() - Function to update the contents of
8641 the running configuration with parameters taken from NV storage
8642
8643 \param - pHddCtx - Pointer to the HDD global context
8644
8645 \return - VOS_STATUS_SUCCESS if successful
8646
8647 --------------------------------------------------------------------------*/
8648static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8649{
Jeff Johnson295189b2012-06-20 16:38:30 -07008650 v_BOOL_t itemIsValid = VOS_FALSE;
8651 VOS_STATUS status;
8652 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8653 v_U8_t macLoop;
8654
8655 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8656 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8657 if(status != VOS_STATUS_SUCCESS)
8658 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008659 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008660 return VOS_STATUS_E_FAILURE;
8661 }
8662
8663 if (itemIsValid == VOS_TRUE)
8664 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008665 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008666 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8667 VOS_MAX_CONCURRENCY_PERSONA);
8668 if(status != VOS_STATUS_SUCCESS)
8669 {
8670 /* Get MAC from NV fail, not update CFG info
8671 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008672 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008673 return VOS_STATUS_E_FAILURE;
8674 }
8675
8676 /* If first MAC is not valid, treat all others are not valid
8677 * Then all MACs will be got from ini file */
8678 if(vos_is_macaddr_zero(&macFromNV[0]))
8679 {
8680 /* MAC address in NV file is not configured yet */
8681 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8682 return VOS_STATUS_E_INVAL;
8683 }
8684
8685 /* Get MAC address from NV, update CFG info */
8686 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8687 {
8688 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8689 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308690 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008691 /* This MAC is not valid, skip it
8692 * This MAC will be got from ini file */
8693 }
8694 else
8695 {
8696 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8697 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8698 VOS_MAC_ADDR_SIZE);
8699 }
8700 }
8701 }
8702 else
8703 {
8704 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8705 return VOS_STATUS_E_FAILURE;
8706 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008707
Jeff Johnson295189b2012-06-20 16:38:30 -07008708
8709 return VOS_STATUS_SUCCESS;
8710}
8711
8712/**---------------------------------------------------------------------------
8713
8714 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8715
8716 \param - pAdapter - Pointer to the HDD
8717
8718 \return - None
8719
8720 --------------------------------------------------------------------------*/
8721VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8722{
8723 eHalStatus halStatus;
8724 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308725 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008726
Jeff Johnson295189b2012-06-20 16:38:30 -07008727
8728 // Send ready indication to the HDD. This will kick off the MAC
8729 // into a 'running' state and should kick off an initial scan.
8730 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8731 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8732 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308733 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008734 "code %08d [x%08x]",__func__, halStatus, halStatus );
8735 return VOS_STATUS_E_FAILURE;
8736 }
8737
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308738 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008739 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8740 // And RIVA will crash
8741 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8742 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308743 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8744 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8745
8746
Jeff Johnson295189b2012-06-20 16:38:30 -07008747 return VOS_STATUS_SUCCESS;
8748}
8749
Jeff Johnson295189b2012-06-20 16:38:30 -07008750/* wake lock APIs for HDD */
8751void hdd_prevent_suspend(void)
8752{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008753#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008754 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008755#else
8756 wcnss_prevent_suspend();
8757#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008758}
8759
8760void hdd_allow_suspend(void)
8761{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008762#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008763 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008764#else
8765 wcnss_allow_suspend();
8766#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008767}
8768
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308769void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008770{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008771#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008772 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008773#else
8774 /* Do nothing as there is no API in wcnss for timeout*/
8775#endif
8776}
8777
Jeff Johnson295189b2012-06-20 16:38:30 -07008778/**---------------------------------------------------------------------------
8779
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008780 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8781 information between Host and Riva
8782
8783 This function gets reported version of FW
8784 It also finds the version of Riva headers used to compile the host
8785 It compares the above two and prints a warning if they are different
8786 It gets the SW and HW version string
8787 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8788 indicating the features they support through a bitmap
8789
8790 \param - pHddCtx - Pointer to HDD context
8791
8792 \return - void
8793
8794 --------------------------------------------------------------------------*/
8795
8796void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8797{
8798
8799 tSirVersionType versionCompiled;
8800 tSirVersionType versionReported;
8801 tSirVersionString versionString;
8802 tANI_U8 fwFeatCapsMsgSupported = 0;
8803 VOS_STATUS vstatus;
8804
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008805 memset(&versionCompiled, 0, sizeof(versionCompiled));
8806 memset(&versionReported, 0, sizeof(versionReported));
8807
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008808 /* retrieve and display WCNSS version information */
8809 do {
8810
8811 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8812 &versionCompiled);
8813 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8814 {
8815 hddLog(VOS_TRACE_LEVEL_FATAL,
8816 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008817 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008818 break;
8819 }
8820
8821 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8822 &versionReported);
8823 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8824 {
8825 hddLog(VOS_TRACE_LEVEL_FATAL,
8826 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008827 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008828 break;
8829 }
8830
8831 if ((versionCompiled.major != versionReported.major) ||
8832 (versionCompiled.minor != versionReported.minor) ||
8833 (versionCompiled.version != versionReported.version) ||
8834 (versionCompiled.revision != versionReported.revision))
8835 {
8836 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8837 "Host expected %u.%u.%u.%u\n",
8838 WLAN_MODULE_NAME,
8839 (int)versionReported.major,
8840 (int)versionReported.minor,
8841 (int)versionReported.version,
8842 (int)versionReported.revision,
8843 (int)versionCompiled.major,
8844 (int)versionCompiled.minor,
8845 (int)versionCompiled.version,
8846 (int)versionCompiled.revision);
8847 }
8848 else
8849 {
8850 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8851 WLAN_MODULE_NAME,
8852 (int)versionReported.major,
8853 (int)versionReported.minor,
8854 (int)versionReported.version,
8855 (int)versionReported.revision);
8856 }
8857
8858 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8859 versionString,
8860 sizeof(versionString));
8861 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8862 {
8863 hddLog(VOS_TRACE_LEVEL_FATAL,
8864 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008865 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008866 break;
8867 }
8868
8869 pr_info("%s: WCNSS software version %s\n",
8870 WLAN_MODULE_NAME, versionString);
8871
8872 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8873 versionString,
8874 sizeof(versionString));
8875 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8876 {
8877 hddLog(VOS_TRACE_LEVEL_FATAL,
8878 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008879 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008880 break;
8881 }
8882
8883 pr_info("%s: WCNSS hardware version %s\n",
8884 WLAN_MODULE_NAME, versionString);
8885
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008886 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8887 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008888 send the message only if it the riva is 1.1
8889 minor numbers for different riva branches:
8890 0 -> (1.0)Mainline Build
8891 1 -> (1.1)Mainline Build
8892 2->(1.04) Stability Build
8893 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008894 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008895 ((versionReported.minor>=1) && (versionReported.version>=1)))
8896 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8897 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008898
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008899 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008900 {
8901#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8902 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8903 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8904#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008905 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8906 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8907 {
8908 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8909 }
8910
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008911 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008912 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008913
8914 } while (0);
8915
8916}
Neelansh Mittaledafed22014-09-04 18:54:39 +05308917void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
8918{
8919 struct sk_buff *skb;
8920 struct nlmsghdr *nlh;
8921 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05308922 int flags = GFP_KERNEL;
Neelansh Mittaledafed22014-09-04 18:54:39 +05308923
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05308924 if (in_interrupt() || irqs_disabled() || in_atomic())
8925 flags = GFP_ATOMIC;
8926
8927 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +05308928
8929 if(skb == NULL) {
8930 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8931 "%s: alloc_skb failed", __func__);
8932 return;
8933 }
8934
8935 nlh = (struct nlmsghdr *)skb->data;
8936 nlh->nlmsg_pid = 0; /* from kernel */
8937 nlh->nlmsg_flags = 0;
8938 nlh->nlmsg_seq = 0;
8939 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
8940
8941 ani_hdr = NLMSG_DATA(nlh);
8942 ani_hdr->type = type;
8943
8944 switch(type) {
8945 case WLAN_SVC_SAP_RESTART_IND:
8946 ani_hdr->length = 0;
8947 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
8948 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
8949 break;
8950 default:
8951 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8952 "Attempt to send unknown nlink message %d", type);
8953 kfree_skb(skb);
8954 return;
8955 }
8956
8957 nl_srv_bcast(skb);
8958
8959 return;
8960}
8961
8962
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008963
8964/**---------------------------------------------------------------------------
8965
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308966 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8967
8968 \param - pHddCtx - Pointer to the hdd context
8969
8970 \return - true if hardware supports 5GHz
8971
8972 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308973boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308974{
8975 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8976 * then hardware support 5Ghz.
8977 */
8978 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8979 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308980 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308981 return true;
8982 }
8983 else
8984 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308985 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308986 __func__);
8987 return false;
8988 }
8989}
8990
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308991/**---------------------------------------------------------------------------
8992
8993 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8994 generate function
8995
8996 This is generate the random mac address for WLAN interface
8997
8998 \param - pHddCtx - Pointer to HDD context
8999 idx - Start interface index to get auto
9000 generated mac addr.
9001 mac_addr - Mac address
9002
9003 \return - 0 for success, < 0 for failure
9004
9005 --------------------------------------------------------------------------*/
9006
9007static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
9008 int idx, v_MACADDR_t mac_addr)
9009{
9010 int i;
9011 unsigned int serialno;
9012 serialno = wcnss_get_serial_number();
9013
9014 if (0 != serialno)
9015 {
9016 /* MAC address has 3 bytes of OUI so we have a maximum of 3
9017 bytes of the serial number that can be used to generate
9018 the other 3 bytes of the MAC address. Mask off all but
9019 the lower 3 bytes (this will also make sure we don't
9020 overflow in the next step) */
9021 serialno &= 0x00FFFFFF;
9022
9023 /* we need a unique address for each session */
9024 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
9025
9026 /* autogen other Mac addresses */
9027 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
9028 {
9029 /* start with the entire default address */
9030 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
9031 /* then replace the lower 3 bytes */
9032 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
9033 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
9034 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
9035
9036 serialno++;
9037 hddLog(VOS_TRACE_LEVEL_ERROR,
9038 "%s: Derived Mac Addr: "
9039 MAC_ADDRESS_STR, __func__,
9040 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
9041 }
9042
9043 }
9044 else
9045 {
9046 hddLog(LOGE, FL("Failed to Get Serial NO"));
9047 return -1;
9048 }
9049 return 0;
9050}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309051
Katya Nigame7b69a82015-04-28 15:24:06 +05309052int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
9053{
9054 VOS_STATUS status;
9055 v_CONTEXT_t pVosContext= NULL;
9056 hdd_adapter_t *pAdapter= NULL;
9057
9058 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9059
9060 if (NULL == pVosContext)
9061 {
9062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9063 "%s: Trying to open VOSS without a PreOpen", __func__);
9064 VOS_ASSERT(0);
9065 return VOS_STATUS_E_FAILURE;
9066 }
9067
9068 status = vos_nv_open();
9069 if (!VOS_IS_STATUS_SUCCESS(status))
9070 {
9071 /* NV module cannot be initialized */
9072 hddLog( VOS_TRACE_LEVEL_FATAL,
9073 "%s: vos_nv_open failed", __func__);
9074 return VOS_STATUS_E_FAILURE;
9075 }
9076
9077 status = vos_init_wiphy_from_nv_bin();
9078 if (!VOS_IS_STATUS_SUCCESS(status))
9079 {
9080 /* NV module cannot be initialized */
9081 hddLog( VOS_TRACE_LEVEL_FATAL,
9082 "%s: vos_init_wiphy failed", __func__);
9083 goto err_vos_nv_close;
9084 }
9085
9086 status = vos_open( &pVosContext, pHddCtx->parent_dev);
9087 if ( !VOS_IS_STATUS_SUCCESS( status ))
9088 {
9089 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
9090 goto err_vos_nv_close;
9091 }
9092
9093 status = vos_mon_start( pVosContext );
9094 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9095 {
9096 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
9097 goto err_vosclose;
9098 }
9099
9100 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9101 WDA_featureCapsExchange(pVosContext);
9102 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9103
9104 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
9105 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9106 if( pAdapter == NULL )
9107 {
9108 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9109 goto err_close_adapter;
9110 }
9111
9112 //Initialize the nlink service
9113 if(nl_srv_init() != 0)
9114 {
9115 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
9116 goto err_close_adapter;
9117 }
9118 return VOS_STATUS_SUCCESS;
9119
9120err_close_adapter:
9121 hdd_close_all_adapters( pHddCtx );
9122 vos_mon_stop( pVosContext );
9123err_vosclose:
9124 status = vos_sched_close( pVosContext );
9125 if (!VOS_IS_STATUS_SUCCESS(status)) {
9126 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9127 "%s: Failed to close VOSS Scheduler", __func__);
9128 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9129 }
9130 vos_close(pVosContext );
9131
9132err_vos_nv_close:
9133 vos_nv_close();
9134
9135return status;
9136}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309137/**---------------------------------------------------------------------------
9138
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309139 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
9140 completed to flush out the scan results
9141
9142 11d scan is done during driver load and is a passive scan on all
9143 channels supported by the device, 11d scans may find some APs on
9144 frequencies which are forbidden to be used in the regulatory domain
9145 the device is operating in. If these APs are notified to the supplicant
9146 it may try to connect to these APs, thus flush out all the scan results
9147 which are present in SME after 11d scan is done.
9148
9149 \return - eHalStatus
9150
9151 --------------------------------------------------------------------------*/
9152static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
9153 tANI_U32 scanId, eCsrScanStatus status)
9154{
9155 ENTER();
9156
9157 sme_ScanFlushResult(halHandle, 0);
9158
9159 EXIT();
9160
9161 return eHAL_STATUS_SUCCESS;
9162}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309163/**---------------------------------------------------------------------------
9164
9165 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
9166 logging is completed successfully.
9167
9168 \return - None
9169
9170 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309171void hdd_init_frame_logging_done(void *fwlogInitCbContext, VOS_STATUS status)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309172{
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309173 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309174
9175 if (NULL == pHddCtx)
9176 {
9177 hddLog(VOS_TRACE_LEVEL_ERROR,
9178 "%s: HDD context is NULL",__func__);
9179 return;
9180 }
9181
9182 if (VOS_STATUS_SUCCESS == status)
9183 {
9184 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
9185 pHddCtx->mgmt_frame_logging = TRUE;
9186 }
9187 else
9188 {
9189 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
9190 pHddCtx->mgmt_frame_logging = FALSE;
9191 }
9192
9193 return;
9194}
9195/**---------------------------------------------------------------------------
9196
9197 \brief hdd_init_frame_logging - function to initialize frame logging.
9198 Currently only Mgmt Frames are logged in both TX
9199 and Rx direction and are sent to userspace
9200 application using logger thread when queried.
9201
9202 \return - None
9203
9204 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309205void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309206{
9207 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309208 tpSirFWLoggingInitParam wlanFWLoggingInitParam;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309209
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309210 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
9211 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309212 {
9213 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
9214 return;
9215 }
9216
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309217 wlanFWLoggingInitParam = vos_mem_malloc(sizeof(tSirFWLoggingInitParam));
9218 if(NULL == wlanFWLoggingInitParam)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309219 {
9220 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed ", __func__);
9221 return;
9222 }
9223
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309224 vos_mem_set(wlanFWLoggingInitParam, sizeof(tSirFWLoggingInitParam), 0);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309225
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309226 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s Logging",__func__,
9227 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
9228 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
9229 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309230
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309231 if (pHddCtx->cfg_ini->enableFWLogging ||
9232 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309233 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309234 wlanFWLoggingInitParam->enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309235 }
9236
9237 if (pHddCtx->cfg_ini->enableBMUHWtracing)
9238 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309239 wlanFWLoggingInitParam->enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309240 }
9241
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309242 wlanFWLoggingInitParam->frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
9243 wlanFWLoggingInitParam->frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
9244 wlanFWLoggingInitParam->bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
9245 wlanFWLoggingInitParam->continuousFrameLogging =
9246 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309247
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309248 wlanFWLoggingInitParam->enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309249
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309250 wlanFWLoggingInitParam->minLogBufferSize =
9251 pHddCtx->cfg_ini->minLoggingBufferSize;
9252 wlanFWLoggingInitParam->maxLogBufferSize =
9253 pHddCtx->cfg_ini->maxLoggingBufferSize;
9254 wlanFWLoggingInitParam->fwlogInitCallback = hdd_init_frame_logging_done;
9255 wlanFWLoggingInitParam->fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309256
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309257 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309258
9259 if (eHAL_STATUS_SUCCESS != halStatus)
9260 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309261 vos_mem_free(wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309262 }
9263
9264 return;
9265}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309266
9267/**---------------------------------------------------------------------------
9268
Jeff Johnson295189b2012-06-20 16:38:30 -07009269 \brief hdd_wlan_startup() - HDD init function
9270
9271 This is the driver startup code executed once a WLAN device has been detected
9272
9273 \param - dev - Pointer to the underlying device
9274
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009275 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07009276
9277 --------------------------------------------------------------------------*/
9278
9279int hdd_wlan_startup(struct device *dev )
9280{
9281 VOS_STATUS status;
9282 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009283 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009284 hdd_context_t *pHddCtx = NULL;
9285 v_CONTEXT_t pVosContext= NULL;
9286#ifdef WLAN_BTAMP_FEATURE
9287 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
9288 WLANBAP_ConfigType btAmpConfig;
9289 hdd_config_t *pConfig;
9290#endif
9291 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009292 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309293 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009294
9295 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009296 /*
9297 * cfg80211: wiphy allocation
9298 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309299 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009300
9301 if(wiphy == NULL)
9302 {
9303 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009304 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009305 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009306 pHddCtx = wiphy_priv(wiphy);
9307
Jeff Johnson295189b2012-06-20 16:38:30 -07009308 //Initialize the adapter context to zeros.
9309 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
9310
Jeff Johnson295189b2012-06-20 16:38:30 -07009311 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07009312 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05309313 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009314
9315 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9316
9317 /*Get vos context here bcoz vos_open requires it*/
9318 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9319
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08009320 if(pVosContext == NULL)
9321 {
9322 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
9323 goto err_free_hdd_context;
9324 }
9325
Jeff Johnson295189b2012-06-20 16:38:30 -07009326 //Save the Global VOSS context in adapter context for future.
9327 pHddCtx->pvosContext = pVosContext;
9328
9329 //Save the adapter context in global context for future.
9330 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
9331
Jeff Johnson295189b2012-06-20 16:38:30 -07009332 pHddCtx->parent_dev = dev;
9333
9334 init_completion(&pHddCtx->full_pwr_comp_var);
9335 init_completion(&pHddCtx->standby_comp_var);
9336 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009337 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009338 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05309339 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309340 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07009341
9342#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07009343 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07009344#else
9345 init_completion(&pHddCtx->driver_crda_req);
9346#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009347
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309348 spin_lock_init(&pHddCtx->schedScan_lock);
9349
Jeff Johnson295189b2012-06-20 16:38:30 -07009350 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
9351
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309352#ifdef FEATURE_WLAN_TDLS
9353 /* tdls_lock is initialized before an hdd_open_adapter ( which is
9354 * invoked by other instances also) to protect the concurrent
9355 * access for the Adapters by TDLS module.
9356 */
9357 mutex_init(&pHddCtx->tdls_lock);
9358#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05309359 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05309360 mutex_init(&pHddCtx->wmmLock);
9361
Agarwal Ashish1f422872014-07-22 00:11:55 +05309362 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309363
Agarwal Ashish1f422872014-07-22 00:11:55 +05309364 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009365 // Load all config first as TL config is needed during vos_open
9366 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9367 if(pHddCtx->cfg_ini == NULL)
9368 {
9369 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9370 goto err_free_hdd_context;
9371 }
9372
9373 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9374
9375 // Read and parse the qcom_cfg.ini file
9376 status = hdd_parse_config_ini( pHddCtx );
9377 if ( VOS_STATUS_SUCCESS != status )
9378 {
9379 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9380 __func__, WLAN_INI_FILE);
9381 goto err_config;
9382 }
Arif Hussaind5218912013-12-05 01:10:55 -08009383#ifdef MEMORY_DEBUG
9384 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9385 vos_mem_init();
9386
9387 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9388 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9389#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009390
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309391 /* INI has been read, initialise the configuredMcastBcastFilter with
9392 * INI value as this will serve as the default value
9393 */
9394 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9395 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9396 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309397
9398 if (false == hdd_is_5g_supported(pHddCtx))
9399 {
9400 //5Ghz is not supported.
9401 if (1 != pHddCtx->cfg_ini->nBandCapability)
9402 {
9403 hddLog(VOS_TRACE_LEVEL_INFO,
9404 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9405 pHddCtx->cfg_ini->nBandCapability = 1;
9406 }
9407 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309408
9409 /* If SNR Monitoring is enabled, FW has to parse all beacons
9410 * for calcaluting and storing the average SNR, so set Nth beacon
9411 * filter to 1 to enable FW to parse all the beaocons
9412 */
9413 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9414 {
9415 /* The log level is deliberately set to WARN as overriding
9416 * nthBeaconFilter to 1 will increase power cosumption and this
9417 * might just prove helpful to detect the power issue.
9418 */
9419 hddLog(VOS_TRACE_LEVEL_WARN,
9420 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9421 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9422 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009423 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309424 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009425 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009426 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009427 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009428 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9429 {
9430 hddLog(VOS_TRACE_LEVEL_FATAL,
9431 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9432 goto err_config;
9433 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009434 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009435
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009436 // Update VOS trace levels based upon the cfg.ini
9437 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9438 pHddCtx->cfg_ini->vosTraceEnableBAP);
9439 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9440 pHddCtx->cfg_ini->vosTraceEnableTL);
9441 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9442 pHddCtx->cfg_ini->vosTraceEnableWDI);
9443 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9444 pHddCtx->cfg_ini->vosTraceEnableHDD);
9445 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9446 pHddCtx->cfg_ini->vosTraceEnableSME);
9447 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9448 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309449 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9450 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009451 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9452 pHddCtx->cfg_ini->vosTraceEnableWDA);
9453 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9454 pHddCtx->cfg_ini->vosTraceEnableSYS);
9455 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9456 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009457 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9458 pHddCtx->cfg_ini->vosTraceEnableSAP);
9459 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9460 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009461
Jeff Johnson295189b2012-06-20 16:38:30 -07009462 // Update WDI trace levels based upon the cfg.ini
9463 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9464 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9465 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9466 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9467 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9468 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9469 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9470 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009471
Jeff Johnson88ba7742013-02-27 14:36:02 -08009472 if (VOS_FTM_MODE == hdd_get_conparam())
9473 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009474 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9475 {
9476 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9477 goto err_free_hdd_context;
9478 }
9479 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +05309480 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +05309481 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009482 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009483 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009484
Katya Nigame7b69a82015-04-28 15:24:06 +05309485 if( VOS_MONITOR_MODE == hdd_get_conparam())
9486 {
9487 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
9488 {
9489 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
9490 goto err_free_hdd_context;
9491 }
9492 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
9493 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
9494 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9495 return VOS_STATUS_SUCCESS;
9496 }
9497
Jeff Johnson88ba7742013-02-27 14:36:02 -08009498 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009499 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9500 {
9501 status = vos_watchdog_open(pVosContext,
9502 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9503
9504 if(!VOS_IS_STATUS_SUCCESS( status ))
9505 {
9506 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309507 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009508 }
9509 }
9510
9511 pHddCtx->isLogpInProgress = FALSE;
9512 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9513
Amar Singhala49cbc52013-10-08 18:37:44 -07009514#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009515 /* initialize the NV module. This is required so that
9516 we can initialize the channel information in wiphy
9517 from the NV.bin data. The channel information in
9518 wiphy needs to be initialized before wiphy registration */
9519
9520 status = vos_nv_open();
9521 if (!VOS_IS_STATUS_SUCCESS(status))
9522 {
9523 /* NV module cannot be initialized */
9524 hddLog( VOS_TRACE_LEVEL_FATAL,
9525 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309526 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009527 }
9528
9529 status = vos_init_wiphy_from_nv_bin();
9530 if (!VOS_IS_STATUS_SUCCESS(status))
9531 {
9532 /* NV module cannot be initialized */
9533 hddLog( VOS_TRACE_LEVEL_FATAL,
9534 "%s: vos_init_wiphy failed", __func__);
9535 goto err_vos_nv_close;
9536 }
9537
Amar Singhala49cbc52013-10-08 18:37:44 -07009538#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309539 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309540 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009541 if ( !VOS_IS_STATUS_SUCCESS( status ))
9542 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009543 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309544 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009545 }
9546
Jeff Johnson295189b2012-06-20 16:38:30 -07009547 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9548
9549 if ( NULL == pHddCtx->hHal )
9550 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009551 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009552 goto err_vosclose;
9553 }
9554
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009555 status = vos_preStart( pHddCtx->pvosContext );
9556 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9557 {
9558 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309559 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009560 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009561
Arif Hussaineaf68602013-12-30 23:10:44 -08009562 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9563 {
9564 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9565 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9566 __func__, enable_dfs_chan_scan);
9567 }
9568 if (0 == enable_11d || 1 == enable_11d)
9569 {
9570 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9571 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9572 __func__, enable_11d);
9573 }
9574
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009575 /* Note that the vos_preStart() sequence triggers the cfg download.
9576 The cfg download must occur before we update the SME config
9577 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009578 status = hdd_set_sme_config( pHddCtx );
9579
9580 if ( VOS_STATUS_SUCCESS != status )
9581 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009582 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309583 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009584 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009585
Jeff Johnson295189b2012-06-20 16:38:30 -07009586 /* In the integrated architecture we update the configuration from
9587 the INI file and from NV before vOSS has been started so that
9588 the final contents are available to send down to the cCPU */
9589
9590 // Apply the cfg.ini to cfg.dat
9591 if (FALSE == hdd_update_config_dat(pHddCtx))
9592 {
9593 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309594 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009595 }
9596
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309597 // Get mac addr from platform driver
9598 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9599
9600 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009601 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309602 /* Store the mac addr for first interface */
9603 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9604
9605 hddLog(VOS_TRACE_LEVEL_ERROR,
9606 "%s: WLAN Mac Addr: "
9607 MAC_ADDRESS_STR, __func__,
9608 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9609
9610 /* Here, passing Arg2 as 1 because we do not want to change the
9611 last 3 bytes (means non OUI bytes) of first interface mac
9612 addr.
9613 */
9614 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9615 {
9616 hddLog(VOS_TRACE_LEVEL_ERROR,
9617 "%s: Failed to generate wlan interface mac addr "
9618 "using MAC from ini file ", __func__);
9619 }
9620 }
9621 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9622 {
9623 // Apply the NV to cfg.dat
9624 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009625#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9626 /* There was not a valid set of MAC Addresses in NV. See if the
9627 default addresses were modified by the cfg.ini settings. If so,
9628 we'll use them, but if not, we'll autogenerate a set of MAC
9629 addresses based upon the device serial number */
9630
9631 static const v_MACADDR_t default_address =
9632 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009633
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309634 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9635 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009636 {
9637 /* cfg.ini has the default address, invoke autogen logic */
9638
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309639 /* Here, passing Arg2 as 0 because we want to change the
9640 last 3 bytes (means non OUI bytes) of all the interfaces
9641 mac addr.
9642 */
9643 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9644 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009645 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309646 hddLog(VOS_TRACE_LEVEL_ERROR,
9647 "%s: Failed to generate wlan interface mac addr "
9648 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9649 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009650 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009651 }
9652 else
9653#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9654 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009655 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009656 "%s: Invalid MAC address in NV, using MAC from ini file "
9657 MAC_ADDRESS_STR, __func__,
9658 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9659 }
9660 }
9661 {
9662 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309663
9664 /* Set the MAC Address Currently this is used by HAL to
9665 * add self sta. Remove this once self sta is added as
9666 * part of session open.
9667 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009668 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9669 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9670 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309671
Jeff Johnson295189b2012-06-20 16:38:30 -07009672 if (!HAL_STATUS_SUCCESS( halStatus ))
9673 {
9674 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9675 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309676 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009677 }
9678 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009679
9680 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9681 Note: Firmware image will be read and downloaded inside vos_start API */
9682 status = vos_start( pHddCtx->pvosContext );
9683 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9684 {
9685 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309686 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009687 }
9688
Leo Chang6cec3e22014-01-21 15:33:49 -08009689#ifdef FEATURE_WLAN_CH_AVOID
9690 /* Plug in avoid channel notification callback
9691 * This should happen before ADD_SELF_STA
9692 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309693
9694 /* check the Channel Avoidance is enabled */
9695 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9696 {
9697 sme_AddChAvoidCallback(pHddCtx->hHal,
9698 hdd_hostapd_ch_avoid_cb);
9699 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009700#endif /* FEATURE_WLAN_CH_AVOID */
9701
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009702 /* Exchange capability info between Host and FW and also get versioning info from FW */
9703 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009704
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309705#ifdef CONFIG_ENABLE_LINUX_REG
9706 status = wlan_hdd_init_channels(pHddCtx);
9707 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9708 {
9709 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9710 __func__);
9711 goto err_vosstop;
9712 }
9713#endif
9714
Jeff Johnson295189b2012-06-20 16:38:30 -07009715 status = hdd_post_voss_start_config( pHddCtx );
9716 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9717 {
9718 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9719 __func__);
9720 goto err_vosstop;
9721 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009722
9723#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309724 wlan_hdd_cfg80211_update_reg_info( wiphy );
9725
9726 /* registration of wiphy dev with cfg80211 */
9727 if (0 > wlan_hdd_cfg80211_register(wiphy))
9728 {
9729 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9730 goto err_vosstop;
9731 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009732#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009733
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309734#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309735 /* registration of wiphy dev with cfg80211 */
9736 if (0 > wlan_hdd_cfg80211_register(wiphy))
9737 {
9738 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9739 goto err_vosstop;
9740 }
9741
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309742 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309743 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9744 {
9745 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9746 __func__);
9747 goto err_unregister_wiphy;
9748 }
9749#endif
9750
c_hpothu4a298be2014-12-22 21:12:51 +05309751 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9752
Jeff Johnson295189b2012-06-20 16:38:30 -07009753 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9754 {
9755 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9756 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9757 }
9758 else
9759 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009760 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9761 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9762 if (pAdapter != NULL)
9763 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309764 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009765 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309766 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9767 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9768 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009769
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309770 /* Generate the P2P Device Address. This consists of the device's
9771 * primary MAC address with the locally administered bit set.
9772 */
9773 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009774 }
9775 else
9776 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309777 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9778 if (p2p_dev_addr != NULL)
9779 {
9780 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9781 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9782 }
9783 else
9784 {
9785 hddLog(VOS_TRACE_LEVEL_FATAL,
9786 "%s: Failed to allocate mac_address for p2p_device",
9787 __func__);
9788 goto err_close_adapter;
9789 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009790 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009791
9792 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9793 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9794 if ( NULL == pP2pAdapter )
9795 {
9796 hddLog(VOS_TRACE_LEVEL_FATAL,
9797 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009798 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009799 goto err_close_adapter;
9800 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009801 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009802 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009803
9804 if( pAdapter == NULL )
9805 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009806 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9807 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009808 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009809
Arif Hussain66559122013-11-21 10:11:40 -08009810 if (country_code)
9811 {
9812 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009813 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009814 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9815#ifndef CONFIG_ENABLE_LINUX_REG
9816 hdd_checkandupdate_phymode(pAdapter, country_code);
9817#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009818 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9819 (void *)(tSmeChangeCountryCallback)
9820 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009821 country_code,
9822 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309823 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009824 if (eHAL_STATUS_SUCCESS == ret)
9825 {
Arif Hussaincb607082013-12-20 11:57:42 -08009826 ret = wait_for_completion_interruptible_timeout(
9827 &pAdapter->change_country_code,
9828 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9829
9830 if (0 >= ret)
9831 {
9832 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9833 "%s: SME while setting country code timed out", __func__);
9834 }
Arif Hussain66559122013-11-21 10:11:40 -08009835 }
9836 else
9837 {
Arif Hussaincb607082013-12-20 11:57:42 -08009838 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9839 "%s: SME Change Country code from module param fail ret=%d",
9840 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009841 }
9842 }
9843
Jeff Johnson295189b2012-06-20 16:38:30 -07009844#ifdef WLAN_BTAMP_FEATURE
9845 vStatus = WLANBAP_Open(pVosContext);
9846 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9847 {
9848 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9849 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009850 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009851 }
9852
9853 vStatus = BSL_Init(pVosContext);
9854 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9855 {
9856 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9857 "%s: Failed to Init BSL",__func__);
9858 goto err_bap_close;
9859 }
9860 vStatus = WLANBAP_Start(pVosContext);
9861 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9862 {
9863 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9864 "%s: Failed to start TL",__func__);
9865 goto err_bap_close;
9866 }
9867
9868 pConfig = pHddCtx->cfg_ini;
9869 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9870 status = WLANBAP_SetConfig(&btAmpConfig);
9871
9872#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009873
Mihir Shete9c238772014-10-15 14:35:16 +05309874 /*
9875 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9876 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9877 * which is greater than 0xf. So the below check is safe to make
9878 * sure that there is no entry for UapsdMask in the ini
9879 */
9880 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9881 {
9882 if(IS_DYNAMIC_WMM_PS_ENABLED)
9883 {
9884 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9885 __func__);
9886 pHddCtx->cfg_ini->UapsdMask =
9887 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
9888 }
9889 else
9890 {
9891 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
9892 __func__);
9893 pHddCtx->cfg_ini->UapsdMask =
9894 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
9895 }
9896 }
9897
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07009898#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
9899 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
9900 {
9901 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
9902 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
9903 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
9904 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
9905 }
9906#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009907
Agarwal Ashish4b87f922014-06-18 03:03:21 +05309908 wlan_hdd_tdls_init(pHddCtx);
9909
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309910 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
9911
Jeff Johnson295189b2012-06-20 16:38:30 -07009912 /* Register with platform driver as client for Suspend/Resume */
9913 status = hddRegisterPmOps(pHddCtx);
9914 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9915 {
9916 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
9917#ifdef WLAN_BTAMP_FEATURE
9918 goto err_bap_stop;
9919#else
Jeff Johnsone7245742012-09-05 17:12:55 -07009920 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009921#endif //WLAN_BTAMP_FEATURE
9922 }
9923
Yue Ma0d4891e2013-08-06 17:01:45 -07009924 /* Open debugfs interface */
9925 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
9926 {
9927 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9928 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07009929 }
9930
Jeff Johnson295189b2012-06-20 16:38:30 -07009931 /* Register TM level change handler function to the platform */
9932 status = hddDevTmRegisterNotifyCallback(pHddCtx);
9933 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9934 {
9935 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
9936 goto err_unregister_pmops;
9937 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009938
9939 /* register for riva power on lock to platform driver */
9940 if (req_riva_power_on_lock("wlan"))
9941 {
9942 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9943 __func__);
9944 goto err_unregister_pmops;
9945 }
9946
Jeff Johnson295189b2012-06-20 16:38:30 -07009947 // register net device notifier for device change notification
9948 ret = register_netdevice_notifier(&hdd_netdev_notifier);
9949
9950 if(ret < 0)
9951 {
9952 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
9953 goto err_free_power_on_lock;
9954 }
9955
9956 //Initialize the nlink service
9957 if(nl_srv_init() != 0)
9958 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309959 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009960 goto err_reg_netdev;
9961 }
9962
Leo Chang4ce1cc52013-10-21 18:27:15 -07009963#ifdef WLAN_KD_READY_NOTIFIER
9964 pHddCtx->kd_nl_init = 1;
9965#endif /* WLAN_KD_READY_NOTIFIER */
9966
Jeff Johnson295189b2012-06-20 16:38:30 -07009967 //Initialize the BTC service
9968 if(btc_activate_service(pHddCtx) != 0)
9969 {
9970 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
9971 goto err_nl_srv;
9972 }
9973
9974#ifdef PTT_SOCK_SVC_ENABLE
9975 //Initialize the PTT service
9976 if(ptt_sock_activate_svc(pHddCtx) != 0)
9977 {
9978 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
9979 goto err_nl_srv;
9980 }
9981#endif
9982
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309983#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9984 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
9985 {
Deepthi Gowri78083a32014-11-04 12:55:51 +05309986 if(wlan_logging_sock_activate_svc(
9987 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
9988 pHddCtx->cfg_ini->wlanLoggingNumBuf))
9989 {
9990 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
9991 " failed", __func__);
9992 goto err_nl_srv;
9993 }
9994 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
9995 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +05309996 if (!pHddCtx->cfg_ini->gEnableDebugLog)
9997 pHddCtx->cfg_ini->gEnableDebugLog =
9998 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309999 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010000
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010001 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
10002 (pHddCtx->cfg_ini->enableFWLogging ||
10003 pHddCtx->cfg_ini->enableContFWLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010004 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010005 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010006 }
10007 else
10008 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010009 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010010 }
10011
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010012#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010013
10014
Sushant Kaushik215778f2015-05-21 14:05:36 +053010015 if (vos_is_multicast_logging())
10016 wlan_logging_set_log_level();
10017
Jeff Johnson295189b2012-06-20 16:38:30 -070010018 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010019 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070010020 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070010021 /* Action frame registered in one adapter which will
10022 * applicable to all interfaces
10023 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053010024 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010025 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010026
10027 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053010028 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010029
Jeff Johnson295189b2012-06-20 16:38:30 -070010030
Sameer Thalappil50dc0092013-02-19 17:23:33 -080010031#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -070010032#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10033 /* Initialize the wake lcok */
10034 wake_lock_init(&pHddCtx->rx_wake_lock,
10035 WAKE_LOCK_SUSPEND,
10036 "qcom_rx_wakelock");
10037#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010038 /* Initialize the wake lcok */
10039 wake_lock_init(&pHddCtx->sap_wake_lock,
10040 WAKE_LOCK_SUSPEND,
10041 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -080010042#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010043
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010044 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
10045 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010046
Katya Nigam5c306ea2014-06-19 15:39:54 +053010047 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
10049 hdd_allow_suspend();
Katya Nigam5c306ea2014-06-19 15:39:54 +053010050
10051#ifdef FEATURE_WLAN_SCAN_PNO
10052 /*SME must send channel update configuration to RIVA*/
10053 sme_UpdateChannelConfig(pHddCtx->hHal);
10054#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053010055 /* Send the update default channel list to the FW*/
10056 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053010057
10058 /* Fwr capabilities received, Set the Dot11 mode */
10059 sme_SetDefDot11Mode(pHddCtx->hHal);
10060
Abhishek Singha306a442013-11-07 18:39:01 +053010061#ifndef CONFIG_ENABLE_LINUX_REG
10062 /*updating wiphy so that regulatory user hints can be processed*/
10063 if (wiphy)
10064 {
10065 regulatory_hint(wiphy, "00");
10066 }
10067#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010068 // Initialize the restart logic
10069 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053010070
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010071 //Register the traffic monitor timer now
10072 if ( pHddCtx->cfg_ini->dynSplitscan)
10073 {
10074 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
10075 VOS_TIMER_TYPE_SW,
10076 hdd_tx_rx_pkt_cnt_stat_timer_handler,
10077 (void *)pHddCtx);
10078 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053010079 wlan_hdd_cfg80211_nan_init(pHddCtx);
10080
Dino Mycle6fb96c12014-06-10 11:52:40 +053010081#ifdef WLAN_FEATURE_EXTSCAN
10082 sme_EXTScanRegisterCallback(pHddCtx->hHal,
10083 wlan_hdd_cfg80211_extscan_callback,
10084 pHddCtx);
10085#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010086
10087#ifdef WLAN_NS_OFFLOAD
10088 // Register IPv6 notifier to notify if any change in IP
10089 // So that we can reconfigure the offload parameters
10090 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
10091 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10092 if (ret)
10093 {
10094 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
10095 }
10096 else
10097 {
10098 hddLog(LOGE, FL("Registered IPv6 notifier"));
10099 }
10100#endif
10101
10102 // Register IPv4 notifier to notify if any change in IP
10103 // So that we can reconfigure the offload parameters
10104 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
10105 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10106 if (ret)
10107 {
10108 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
10109 }
10110 else
10111 {
10112 hddLog(LOGE, FL("Registered IPv4 notifier"));
10113 }
10114
Jeff Johnson295189b2012-06-20 16:38:30 -070010115 goto success;
10116
10117err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -070010118#ifdef WLAN_KD_READY_NOTIFIER
10119 nl_srv_exit(pHddCtx->ptt_pid);
10120#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010121 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -070010122#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -070010123err_reg_netdev:
10124 unregister_netdevice_notifier(&hdd_netdev_notifier);
10125
10126err_free_power_on_lock:
10127 free_riva_power_on_lock("wlan");
10128
10129err_unregister_pmops:
10130 hddDevTmUnregisterNotifyCallback(pHddCtx);
10131 hddDeregisterPmOps(pHddCtx);
10132
Yue Ma0d4891e2013-08-06 17:01:45 -070010133 hdd_debugfs_exit(pHddCtx);
10134
Jeff Johnson295189b2012-06-20 16:38:30 -070010135#ifdef WLAN_BTAMP_FEATURE
10136err_bap_stop:
10137 WLANBAP_Stop(pVosContext);
10138#endif
10139
10140#ifdef WLAN_BTAMP_FEATURE
10141err_bap_close:
10142 WLANBAP_Close(pVosContext);
10143#endif
10144
Jeff Johnson295189b2012-06-20 16:38:30 -070010145err_close_adapter:
10146 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010147#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010148err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010149#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010150 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010151err_vosstop:
10152 vos_stop(pVosContext);
10153
Amar Singhala49cbc52013-10-08 18:37:44 -070010154err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070010155 status = vos_sched_close( pVosContext );
10156 if (!VOS_IS_STATUS_SUCCESS(status)) {
10157 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10158 "%s: Failed to close VOSS Scheduler", __func__);
10159 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
10160 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010161 vos_close(pVosContext );
10162
Amar Singhal0a402232013-10-11 20:57:16 -070010163err_vos_nv_close:
10164
c_hpothue6a36282014-03-19 12:27:38 +053010165#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070010166 vos_nv_close();
10167
c_hpothu70f8d812014-03-22 22:59:23 +053010168#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010169
10170err_wdclose:
10171 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10172 vos_watchdog_close(pVosContext);
10173
Jeff Johnson295189b2012-06-20 16:38:30 -070010174err_config:
10175 kfree(pHddCtx->cfg_ini);
10176 pHddCtx->cfg_ini= NULL;
10177
10178err_free_hdd_context:
10179 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -070010180 wiphy_free(wiphy) ;
10181 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010182 VOS_BUG(1);
10183
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080010184 if (hdd_is_ssr_required())
10185 {
10186 /* WDI timeout had happened during load, so SSR is needed here */
10187 subsystem_restart("wcnss");
10188 msleep(5000);
10189 }
10190 hdd_set_ssr_required (VOS_FALSE);
10191
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010192 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010193
10194success:
10195 EXIT();
10196 return 0;
10197}
10198
10199/**---------------------------------------------------------------------------
10200
Jeff Johnson32d95a32012-09-10 13:15:23 -070010201 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070010202
Jeff Johnson32d95a32012-09-10 13:15:23 -070010203 This is the driver entry point - called in different timeline depending
10204 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070010205
10206 \param - None
10207
10208 \return - 0 for success, non zero for failure
10209
10210 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070010211static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010212{
10213 VOS_STATUS status;
10214 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010215 struct device *dev = NULL;
10216 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010217#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10218 int max_retries = 0;
10219#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010220#ifdef HAVE_CBC_DONE
10221 int max_cbc_retries = 0;
10222#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010223
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010224#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10225 wlan_logging_sock_init_svc();
10226#endif
10227
Jeff Johnson295189b2012-06-20 16:38:30 -070010228 ENTER();
10229
Sameer Thalappil50dc0092013-02-19 17:23:33 -080010230#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -070010231 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -070010232#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010233
10234 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
10235 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
10236
Jeff Johnson295189b2012-06-20 16:38:30 -070010237#ifdef ANI_BUS_TYPE_PCI
10238
10239 dev = wcnss_wlan_get_device();
10240
10241#endif // ANI_BUS_TYPE_PCI
10242
10243#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010244
10245#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10246 /* wait until WCNSS driver downloads NV */
10247 while (!wcnss_device_ready() && 5 >= ++max_retries) {
10248 msleep(1000);
10249 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010250
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010251 if (max_retries >= 5) {
10252 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +053010253#ifdef WLAN_OPEN_SOURCE
10254 wake_lock_destroy(&wlan_wake_lock);
10255#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010256
10257#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10258 wlan_logging_sock_deinit_svc();
10259#endif
10260
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010261 return -ENODEV;
10262 }
10263#endif
10264
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010265#ifdef HAVE_CBC_DONE
10266 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
10267 msleep(1000);
10268 }
10269 if (max_cbc_retries >= 10) {
10270 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
10271 }
10272#endif
10273
Jeff Johnson295189b2012-06-20 16:38:30 -070010274 dev = wcnss_wlan_get_device();
10275#endif // ANI_BUS_TYPE_PLATFORM
10276
10277
10278 do {
10279 if (NULL == dev) {
10280 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
10281 ret_status = -1;
10282 break;
10283 }
10284
Jeff Johnson295189b2012-06-20 16:38:30 -070010285#ifdef TIMER_MANAGER
10286 vos_timer_manager_init();
10287#endif
10288
10289 /* Preopen VOSS so that it is ready to start at least SAL */
10290 status = vos_preOpen(&pVosContext);
10291
10292 if (!VOS_IS_STATUS_SUCCESS(status))
10293 {
10294 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
10295 ret_status = -1;
10296 break;
10297 }
10298
Sushant Kaushik02beb352015-06-04 15:15:01 +053010299 hddTraceInit();
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010300#ifndef MODULE
10301 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
10302 */
10303 hdd_set_conparam((v_UINT_t)con_mode);
10304#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010305
10306 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010307 if (hdd_wlan_startup(dev))
10308 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010309 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010310 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010311 vos_preClose( &pVosContext );
10312 ret_status = -1;
10313 break;
10314 }
10315
Jeff Johnson295189b2012-06-20 16:38:30 -070010316 } while (0);
10317
10318 if (0 != ret_status)
10319 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010320#ifdef TIMER_MANAGER
10321 vos_timer_exit();
10322#endif
10323#ifdef MEMORY_DEBUG
10324 vos_mem_exit();
10325#endif
10326
Sameer Thalappil50dc0092013-02-19 17:23:33 -080010327#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -070010328 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070010329#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010330
10331#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10332 wlan_logging_sock_deinit_svc();
10333#endif
10334
Jeff Johnson295189b2012-06-20 16:38:30 -070010335 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
10336 }
10337 else
10338 {
10339 //Send WLAN UP indication to Nlink Service
10340 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
10341
10342 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070010343 }
10344
10345 EXIT();
10346
10347 return ret_status;
10348}
10349
Jeff Johnson32d95a32012-09-10 13:15:23 -070010350/**---------------------------------------------------------------------------
10351
10352 \brief hdd_module_init() - Init Function
10353
10354 This is the driver entry point (invoked when module is loaded using insmod)
10355
10356 \param - None
10357
10358 \return - 0 for success, non zero for failure
10359
10360 --------------------------------------------------------------------------*/
10361#ifdef MODULE
10362static int __init hdd_module_init ( void)
10363{
10364 return hdd_driver_init();
10365}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010366#else /* #ifdef MODULE */
10367static int __init hdd_module_init ( void)
10368{
10369 /* Driver initialization is delayed to fwpath_changed_handler */
10370 return 0;
10371}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010372#endif /* #ifdef MODULE */
10373
Jeff Johnson295189b2012-06-20 16:38:30 -070010374
10375/**---------------------------------------------------------------------------
10376
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010377 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070010378
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010379 This is the driver exit point (invoked when module is unloaded using rmmod
10380 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070010381
10382 \param - None
10383
10384 \return - None
10385
10386 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010387static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010388{
10389 hdd_context_t *pHddCtx = NULL;
10390 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053010391 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053010392 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010393
10394 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
10395
10396 //Get the global vos context
10397 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10398
10399 if(!pVosContext)
10400 {
10401 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10402 goto done;
10403 }
10404
10405 //Get the HDD context.
10406 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10407
10408 if(!pHddCtx)
10409 {
10410 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10411 }
Katya Nigame7b69a82015-04-28 15:24:06 +053010412 else if (VOS_MONITOR_MODE == hdd_get_conparam())
10413 {
10414 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
10415 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10416 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
10417 hdd_wlan_exit(pHddCtx);
10418 vos_preClose( &pVosContext );
10419 goto done;
10420 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010421 else
10422 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053010423 /* We wait for active entry threads to exit from driver
10424 * by waiting until rtnl_lock is available.
10425 */
10426 rtnl_lock();
10427 rtnl_unlock();
10428
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010429 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10430 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10431 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10432 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010433 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010434 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010435 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10436 msecs_to_jiffies(30000));
10437 if(!rc)
10438 {
10439 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10440 "%s:SSR timedout, fatal error", __func__);
10441 VOS_BUG(0);
10442 }
10443 }
10444
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010445 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10446 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010447
c_hpothu8adb97b2014-12-08 19:38:20 +053010448 /* Driver Need to send country code 00 in below condition
10449 * 1) If gCountryCodePriority is set to 1; and last country
10450 * code set is through 11d. This needs to be done in case
10451 * when NV country code is 00.
10452 * This Needs to be done as when kernel store last country
10453 * code and if stored country code is not through 11d,
10454 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10455 * in next load/unload as soon as we get any country through
10456 * 11d. In sme_HandleChangeCountryCodeByUser
10457 * pMsg->countryCode will be last countryCode and
10458 * pMac->scan.countryCode11d will be country through 11d so
10459 * due to mismatch driver will disable 11d.
10460 *
10461 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010462
c_hpothu8adb97b2014-12-08 19:38:20 +053010463 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010464 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010465 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010466 {
10467 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010468 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010469 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10470 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010471
c_hpothu8adb97b2014-12-08 19:38:20 +053010472 //Do all the cleanup before deregistering the driver
10473 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010474 }
10475
Jeff Johnson295189b2012-06-20 16:38:30 -070010476 vos_preClose( &pVosContext );
10477
10478#ifdef TIMER_MANAGER
10479 vos_timer_exit();
10480#endif
10481#ifdef MEMORY_DEBUG
10482 vos_mem_exit();
10483#endif
10484
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010485#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10486 wlan_logging_sock_deinit_svc();
10487#endif
10488
Jeff Johnson295189b2012-06-20 16:38:30 -070010489done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -080010490#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -070010491 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070010492#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010493
Jeff Johnson295189b2012-06-20 16:38:30 -070010494 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10495}
10496
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010497/**---------------------------------------------------------------------------
10498
10499 \brief hdd_module_exit() - Exit function
10500
10501 This is the driver exit point (invoked when module is unloaded using rmmod)
10502
10503 \param - None
10504
10505 \return - None
10506
10507 --------------------------------------------------------------------------*/
10508static void __exit hdd_module_exit(void)
10509{
10510 hdd_driver_exit();
10511}
10512
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010513#ifdef MODULE
10514static int fwpath_changed_handler(const char *kmessage,
10515 struct kernel_param *kp)
10516{
Jeff Johnson76052702013-04-16 13:55:05 -070010517 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010518}
10519
10520static int con_mode_handler(const char *kmessage,
10521 struct kernel_param *kp)
10522{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010523 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010524}
10525#else /* #ifdef MODULE */
10526/**---------------------------------------------------------------------------
10527
Jeff Johnson76052702013-04-16 13:55:05 -070010528 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010529
Jeff Johnson76052702013-04-16 13:55:05 -070010530 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010531 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010532 - invoked when module parameter fwpath is modified from userspace to signal
10533 initializing the WLAN driver or when con_mode is modified from userspace
10534 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010535
10536 \return - 0 for success, non zero for failure
10537
10538 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010539static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010540{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010541 int ret_status;
10542
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010543 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010544 ret_status = hdd_driver_init();
10545 wlan_hdd_inited = ret_status ? 0 : 1;
10546 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010547 }
10548
10549 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010550
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010551 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010552
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010553 ret_status = hdd_driver_init();
10554 wlan_hdd_inited = ret_status ? 0 : 1;
10555 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010556}
10557
Jeff Johnson295189b2012-06-20 16:38:30 -070010558/**---------------------------------------------------------------------------
10559
Jeff Johnson76052702013-04-16 13:55:05 -070010560 \brief fwpath_changed_handler() - Handler Function
10561
10562 Handle changes to the fwpath parameter
10563
10564 \return - 0 for success, non zero for failure
10565
10566 --------------------------------------------------------------------------*/
10567static int fwpath_changed_handler(const char *kmessage,
10568 struct kernel_param *kp)
10569{
10570 int ret;
10571
10572 ret = param_set_copystring(kmessage, kp);
10573 if (0 == ret)
10574 ret = kickstart_driver();
10575 return ret;
10576}
10577
10578/**---------------------------------------------------------------------------
10579
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010580 \brief con_mode_handler() -
10581
10582 Handler function for module param con_mode when it is changed by userspace
10583 Dynamically linked - do nothing
10584 Statically linked - exit and init driver, as in rmmod and insmod
10585
Jeff Johnson76052702013-04-16 13:55:05 -070010586 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010587
Jeff Johnson76052702013-04-16 13:55:05 -070010588 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010589
10590 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010591static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010592{
Jeff Johnson76052702013-04-16 13:55:05 -070010593 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010594
Jeff Johnson76052702013-04-16 13:55:05 -070010595 ret = param_set_int(kmessage, kp);
10596 if (0 == ret)
10597 ret = kickstart_driver();
10598 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010599}
10600#endif /* #ifdef MODULE */
10601
10602/**---------------------------------------------------------------------------
10603
Jeff Johnson295189b2012-06-20 16:38:30 -070010604 \brief hdd_get_conparam() -
10605
10606 This is the driver exit point (invoked when module is unloaded using rmmod)
10607
10608 \param - None
10609
10610 \return - tVOS_CON_MODE
10611
10612 --------------------------------------------------------------------------*/
10613tVOS_CON_MODE hdd_get_conparam ( void )
10614{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010615#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010616 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010617#else
10618 return (tVOS_CON_MODE)curr_con_mode;
10619#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010620}
10621void hdd_set_conparam ( v_UINT_t newParam )
10622{
10623 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010624#ifndef MODULE
10625 curr_con_mode = con_mode;
10626#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010627}
10628/**---------------------------------------------------------------------------
10629
10630 \brief hdd_softap_sta_deauth() - function
10631
10632 This to take counter measure to handle deauth req from HDD
10633
10634 \param - pAdapter - Pointer to the HDD
10635
10636 \param - enable - boolean value
10637
10638 \return - None
10639
10640 --------------------------------------------------------------------------*/
10641
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010642VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10643 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010644{
Jeff Johnson295189b2012-06-20 16:38:30 -070010645 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010646 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010647
10648 ENTER();
10649
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010650 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10651 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010652
10653 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010654 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010655 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010656
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010657 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010658
10659 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010660 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010661}
10662
10663/**---------------------------------------------------------------------------
10664
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010665 \brief hdd_del_all_sta() - function
10666
10667 This function removes all the stations associated on stopping AP/P2P GO.
10668
10669 \param - pAdapter - Pointer to the HDD
10670
10671 \return - None
10672
10673 --------------------------------------------------------------------------*/
10674
10675int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10676{
10677 v_U16_t i;
10678 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010679 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10680 ptSapContext pSapCtx = NULL;
10681 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10682 if(pSapCtx == NULL){
10683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10684 FL("psapCtx is NULL"));
10685 return 1;
10686 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010687 ENTER();
10688
10689 hddLog(VOS_TRACE_LEVEL_INFO,
10690 "%s: Delete all STAs associated.",__func__);
10691 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10692 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10693 )
10694 {
10695 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10696 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010697 if ((pSapCtx->aStaInfo[i].isUsed) &&
10698 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010699 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010700 struct tagCsrDelStaParams delStaParams;
10701
10702 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010703 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010704 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10705 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010706 &delStaParams);
10707 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010708 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010709 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010710 }
10711 }
10712 }
10713
10714 EXIT();
10715 return 0;
10716}
10717
10718/**---------------------------------------------------------------------------
10719
Jeff Johnson295189b2012-06-20 16:38:30 -070010720 \brief hdd_softap_sta_disassoc() - function
10721
10722 This to take counter measure to handle deauth req from HDD
10723
10724 \param - pAdapter - Pointer to the HDD
10725
10726 \param - enable - boolean value
10727
10728 \return - None
10729
10730 --------------------------------------------------------------------------*/
10731
10732void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10733{
10734 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10735
10736 ENTER();
10737
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010738 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010739
10740 //Ignore request to disassoc bcmc station
10741 if( pDestMacAddress[0] & 0x1 )
10742 return;
10743
10744 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10745}
10746
10747void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10748{
10749 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10750
10751 ENTER();
10752
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010753 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010754
10755 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10756}
10757
Jeff Johnson295189b2012-06-20 16:38:30 -070010758/**---------------------------------------------------------------------------
10759 *
10760 * \brief hdd_get__concurrency_mode() -
10761 *
10762 *
10763 * \param - None
10764 *
10765 * \return - CONCURRENCY MODE
10766 *
10767 * --------------------------------------------------------------------------*/
10768tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10769{
10770 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10771 hdd_context_t *pHddCtx;
10772
10773 if (NULL != pVosContext)
10774 {
10775 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10776 if (NULL != pHddCtx)
10777 {
10778 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10779 }
10780 }
10781
10782 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010783 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010784 return VOS_STA;
10785}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010786v_BOOL_t
10787wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10788{
10789 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010790
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010791 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10792 if (pAdapter == NULL)
10793 {
10794 hddLog(VOS_TRACE_LEVEL_INFO,
10795 FL("GO doesn't exist"));
10796 return TRUE;
10797 }
10798 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10799 {
10800 hddLog(VOS_TRACE_LEVEL_INFO,
10801 FL("GO started"));
10802 return TRUE;
10803 }
10804 else
10805 /* wait till GO changes its interface to p2p device */
10806 hddLog(VOS_TRACE_LEVEL_INFO,
10807 FL("Del_bss called, avoid apps suspend"));
10808 return FALSE;
10809
10810}
Jeff Johnson295189b2012-06-20 16:38:30 -070010811/* Decide whether to allow/not the apps power collapse.
10812 * Allow apps power collapse if we are in connected state.
10813 * if not, allow only if we are in IMPS */
10814v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10815{
10816 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010817 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010818 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010819 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10820 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10821 hdd_adapter_t *pAdapter = NULL;
10822 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010823 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010824
Jeff Johnson295189b2012-06-20 16:38:30 -070010825 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10826 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010827
Yathish9f22e662012-12-10 14:21:35 -080010828 concurrent_state = hdd_get_concurrency_mode();
10829
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010830 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10831 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10832 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010833#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010834
Yathish9f22e662012-12-10 14:21:35 -080010835 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010836 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010837 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10838 return TRUE;
10839#endif
10840
Jeff Johnson295189b2012-06-20 16:38:30 -070010841 /*loop through all adapters. TBD fix for Concurrency */
10842 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10843 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10844 {
10845 pAdapter = pAdapterNode->pAdapter;
10846 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10847 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10848 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010849 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010850 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010851 && pmcState != STOPPED && pmcState != STANDBY &&
10852 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010853 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10854 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010855 {
Mukul Sharma4be88422015-03-09 20:29:07 +053010856 if(pmcState == FULL_POWER &&
10857 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
10858 {
10859 /*
10860 * When SCO indication comes from Coex module , host will
10861 * enter in to full power mode, but this should not prevent
10862 * apps processor power collapse.
10863 */
10864 hddLog(LOG1,
10865 FL("Allow apps power collapse"
10866 "even when sco indication is set"));
10867 return TRUE;
10868 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080010869 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010870 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10871 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010872 return FALSE;
10873 }
10874 }
10875 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10876 pAdapterNode = pNext;
10877 }
10878 return TRUE;
10879}
10880
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010881/* Decides whether to send suspend notification to Riva
10882 * if any adapter is in BMPS; then it is required */
10883v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10884{
10885 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10886 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10887
10888 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10889 {
10890 return TRUE;
10891 }
10892 return FALSE;
10893}
10894
Jeff Johnson295189b2012-06-20 16:38:30 -070010895void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10896{
10897 switch(mode)
10898 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010899 case VOS_STA_MODE:
10900 case VOS_P2P_CLIENT_MODE:
10901 case VOS_P2P_GO_MODE:
10902 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010903 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010904 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010905 break;
10906 default:
10907 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010908 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010909 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10910 "Number of open sessions for mode %d = %d"),
10911 pHddCtx->concurrency_mode, mode,
10912 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010913}
10914
10915
10916void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10917{
10918 switch(mode)
10919 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010920 case VOS_STA_MODE:
10921 case VOS_P2P_CLIENT_MODE:
10922 case VOS_P2P_GO_MODE:
10923 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053010924 pHddCtx->no_of_open_sessions[mode]--;
10925 if (!(pHddCtx->no_of_open_sessions[mode]))
10926 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070010927 break;
10928 default:
10929 break;
10930 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010931 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10932 "Number of open sessions for mode %d = %d"),
10933 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
10934
10935}
10936/**---------------------------------------------------------------------------
10937 *
10938 * \brief wlan_hdd_incr_active_session()
10939 *
10940 * This function increments the number of active sessions
10941 * maintained per device mode
10942 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
10943 * Incase of SAP/P2P GO upon bss start it is incremented
10944 *
10945 * \param pHddCtx - HDD Context
10946 * \param mode - device mode
10947 *
10948 * \return - None
10949 *
10950 * --------------------------------------------------------------------------*/
10951void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10952{
10953 switch (mode) {
10954 case VOS_STA_MODE:
10955 case VOS_P2P_CLIENT_MODE:
10956 case VOS_P2P_GO_MODE:
10957 case VOS_STA_SAP_MODE:
10958 pHddCtx->no_of_active_sessions[mode]++;
10959 break;
10960 default:
10961 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10962 break;
10963 }
10964 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10965 mode,
10966 pHddCtx->no_of_active_sessions[mode]);
10967}
10968
10969/**---------------------------------------------------------------------------
10970 *
10971 * \brief wlan_hdd_decr_active_session()
10972 *
10973 * This function decrements the number of active sessions
10974 * maintained per device mode
10975 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
10976 * Incase of SAP/P2P GO upon bss stop it is decremented
10977 *
10978 * \param pHddCtx - HDD Context
10979 * \param mode - device mode
10980 *
10981 * \return - None
10982 *
10983 * --------------------------------------------------------------------------*/
10984void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10985{
10986 switch (mode) {
10987 case VOS_STA_MODE:
10988 case VOS_P2P_CLIENT_MODE:
10989 case VOS_P2P_GO_MODE:
10990 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053010991 if (pHddCtx->no_of_active_sessions[mode] > 0)
10992 pHddCtx->no_of_active_sessions[mode]--;
10993 else
10994 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
10995 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053010996 break;
10997 default:
10998 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10999 break;
11000 }
11001 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11002 mode,
11003 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011004}
11005
Jeff Johnsone7245742012-09-05 17:12:55 -070011006/**---------------------------------------------------------------------------
11007 *
11008 * \brief wlan_hdd_restart_init
11009 *
11010 * This function initalizes restart timer/flag. An internal function.
11011 *
11012 * \param - pHddCtx
11013 *
11014 * \return - None
11015 *
11016 * --------------------------------------------------------------------------*/
11017
11018static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
11019{
11020 /* Initialize */
11021 pHddCtx->hdd_restart_retries = 0;
11022 atomic_set(&pHddCtx->isRestartInProgress, 0);
11023 vos_timer_init(&pHddCtx->hdd_restart_timer,
11024 VOS_TIMER_TYPE_SW,
11025 wlan_hdd_restart_timer_cb,
11026 pHddCtx);
11027}
11028/**---------------------------------------------------------------------------
11029 *
11030 * \brief wlan_hdd_restart_deinit
11031 *
11032 * This function cleans up the resources used. An internal function.
11033 *
11034 * \param - pHddCtx
11035 *
11036 * \return - None
11037 *
11038 * --------------------------------------------------------------------------*/
11039
11040static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
11041{
11042
11043 VOS_STATUS vos_status;
11044 /* Block any further calls */
11045 atomic_set(&pHddCtx->isRestartInProgress, 1);
11046 /* Cleanup */
11047 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
11048 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011049 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011050 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
11051 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011052 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011053
11054}
11055
11056/**---------------------------------------------------------------------------
11057 *
11058 * \brief wlan_hdd_framework_restart
11059 *
11060 * This function uses a cfg80211 API to start a framework initiated WLAN
11061 * driver module unload/load.
11062 *
11063 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
11064 *
11065 *
11066 * \param - pHddCtx
11067 *
11068 * \return - VOS_STATUS_SUCCESS: Success
11069 * VOS_STATUS_E_EMPTY: Adapter is Empty
11070 * VOS_STATUS_E_NOMEM: No memory
11071
11072 * --------------------------------------------------------------------------*/
11073
11074static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
11075{
11076 VOS_STATUS status = VOS_STATUS_SUCCESS;
11077 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011078 int len = (sizeof (struct ieee80211_mgmt));
11079 struct ieee80211_mgmt *mgmt = NULL;
11080
11081 /* Prepare the DEAUTH managment frame with reason code */
11082 mgmt = kzalloc(len, GFP_KERNEL);
11083 if(mgmt == NULL)
11084 {
11085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11086 "%s: memory allocation failed (%d bytes)", __func__, len);
11087 return VOS_STATUS_E_NOMEM;
11088 }
11089 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070011090
11091 /* Iterate over all adapters/devices */
11092 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011093 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
11094 {
11095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11096 FL("fail to get adapter: %p %d"), pAdapterNode, status);
11097 goto end;
11098 }
11099
Jeff Johnsone7245742012-09-05 17:12:55 -070011100 do
11101 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011102 if(pAdapterNode->pAdapter &&
11103 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070011104 {
11105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11106 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
11107 pAdapterNode->pAdapter->dev->name,
11108 pAdapterNode->pAdapter->device_mode,
11109 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011110 /*
11111 * CFG80211 event to restart the driver
11112 *
11113 * 'cfg80211_send_unprot_deauth' sends a
11114 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
11115 * of SME(Linux Kernel) state machine.
11116 *
11117 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
11118 * the driver.
11119 *
11120 */
11121
11122 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070011123 }
11124 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11125 pAdapterNode = pNext;
11126 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
11127
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011128 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011129 /* Free the allocated management frame */
11130 kfree(mgmt);
11131
Jeff Johnsone7245742012-09-05 17:12:55 -070011132 /* Retry until we unload or reach max count */
11133 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
11134 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
11135
11136 return status;
11137
11138}
11139/**---------------------------------------------------------------------------
11140 *
11141 * \brief wlan_hdd_restart_timer_cb
11142 *
11143 * Restart timer callback. An internal function.
11144 *
11145 * \param - User data:
11146 *
11147 * \return - None
11148 *
11149 * --------------------------------------------------------------------------*/
11150
11151void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
11152{
11153 hdd_context_t *pHddCtx = usrDataForCallback;
11154 wlan_hdd_framework_restart(pHddCtx);
11155 return;
11156
11157}
11158
11159
11160/**---------------------------------------------------------------------------
11161 *
11162 * \brief wlan_hdd_restart_driver
11163 *
11164 * This function sends an event to supplicant to restart the WLAN driver.
11165 *
11166 * This function is called from vos_wlanRestart.
11167 *
11168 * \param - pHddCtx
11169 *
11170 * \return - VOS_STATUS_SUCCESS: Success
11171 * VOS_STATUS_E_EMPTY: Adapter is Empty
11172 * VOS_STATUS_E_ALREADY: Request already in progress
11173
11174 * --------------------------------------------------------------------------*/
11175VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
11176{
11177 VOS_STATUS status = VOS_STATUS_SUCCESS;
11178
11179 /* A tight check to make sure reentrancy */
11180 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
11181 {
Mihir Shetefd528652014-06-23 19:07:50 +053011182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070011183 "%s: WLAN restart is already in progress", __func__);
11184
11185 return VOS_STATUS_E_ALREADY;
11186 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070011187 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080011188#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053011189 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070011190#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011191
Jeff Johnsone7245742012-09-05 17:12:55 -070011192 return status;
11193}
11194
Mihir Shetee1093ba2014-01-21 20:13:32 +053011195/**---------------------------------------------------------------------------
11196 *
11197 * \brief wlan_hdd_init_channels
11198 *
11199 * This function is used to initialize the channel list in CSR
11200 *
11201 * This function is called from hdd_wlan_startup
11202 *
11203 * \param - pHddCtx: HDD context
11204 *
11205 * \return - VOS_STATUS_SUCCESS: Success
11206 * VOS_STATUS_E_FAULT: Failure reported by SME
11207
11208 * --------------------------------------------------------------------------*/
11209static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
11210{
11211 eHalStatus status;
11212
11213 status = sme_InitChannels(pHddCtx->hHal);
11214 if (HAL_STATUS_SUCCESS(status))
11215 {
11216 return VOS_STATUS_SUCCESS;
11217 }
11218 else
11219 {
11220 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
11221 __func__, status);
11222 return VOS_STATUS_E_FAULT;
11223 }
11224}
11225
Mihir Shete04206452014-11-20 17:50:58 +053011226#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011227VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011228{
11229 eHalStatus status;
11230
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011231 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011232 if (HAL_STATUS_SUCCESS(status))
11233 {
11234 return VOS_STATUS_SUCCESS;
11235 }
11236 else
11237 {
11238 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
11239 __func__, status);
11240 return VOS_STATUS_E_FAULT;
11241 }
11242}
Mihir Shete04206452014-11-20 17:50:58 +053011243#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070011244/*
11245 * API to find if there is any STA or P2P-Client is connected
11246 */
11247VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
11248{
11249 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
11250}
Jeff Johnsone7245742012-09-05 17:12:55 -070011251
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011252
11253/*
11254 * API to find if the firmware will send logs using DXE channel
11255 */
11256v_U8_t hdd_is_fw_logging_enabled(void)
11257{
11258 hdd_context_t *pHddCtx;
11259
11260 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11261 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11262
Sachin Ahuja084313e2015-05-21 17:57:10 +053011263 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011264}
11265
Agarwal Ashish57e84372014-12-05 18:26:53 +053011266/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053011267 * API to find if the firmware will send trace logs using DXE channel
11268 */
11269v_U8_t hdd_is_fw_ev_logging_enabled(void)
11270{
11271 hdd_context_t *pHddCtx;
11272
11273 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11274 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11275
11276 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
11277}
11278/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053011279 * API to find if there is any session connected
11280 */
11281VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
11282{
11283 return sme_is_any_session_connected(pHddCtx->hHal);
11284}
11285
11286
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011287int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
11288{
11289 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11290 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053011291 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053011292 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011293
11294 pScanInfo = &pHddCtx->scan_info;
11295 if (pScanInfo->mScanPending)
11296 {
c_hpothua3d45d52015-01-05 14:11:17 +053011297 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
11298 eCSR_SCAN_ABORT_DEFAULT);
11299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11300 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011301
c_hpothua3d45d52015-01-05 14:11:17 +053011302 /* If there is active scan command lets wait for the completion else
11303 * there is no need to wait as scan command might be in the SME pending
11304 * command list.
11305 */
11306 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
11307 {
11308 INIT_COMPLETION(pScanInfo->abortscan_event_var);
11309 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011310 &pScanInfo->abortscan_event_var,
11311 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053011312 if (0 >= status)
11313 {
11314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053011315 "%s: Timeout or Interrupt occurred while waiting for abort"
11316 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053011317 return -ETIMEDOUT;
11318 }
11319 }
11320 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
11321 {
11322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11323 FL("hdd_abort_mac_scan failed"));
11324 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011325 }
11326 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053011327 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011328}
11329
c_hpothu225aa7c2014-10-22 17:45:13 +053011330VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
11331{
11332 hdd_adapter_t *pAdapter;
11333 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11334 VOS_STATUS vosStatus;
11335
11336 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11337 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11338 {
11339 pAdapter = pAdapterNode->pAdapter;
11340 if (NULL != pAdapter)
11341 {
11342 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
11343 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
11344 WLAN_HDD_P2P_GO == pAdapter->device_mode)
11345 {
11346 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
11347 pAdapter->device_mode);
11348 if (VOS_STATUS_SUCCESS !=
11349 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
11350 {
11351 hddLog(LOGE, FL("failed to abort ROC"));
11352 return VOS_STATUS_E_FAILURE;
11353 }
11354 }
11355 }
11356 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11357 pAdapterNode = pNext;
11358 }
11359 return VOS_STATUS_SUCCESS;
11360}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053011361
Mihir Shete0be28772015-02-17 18:42:14 +053011362hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
11363{
11364 hdd_adapter_t *pAdapter;
11365 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11366 hdd_cfg80211_state_t *cfgState;
11367 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
11368 VOS_STATUS vosStatus;
11369
11370 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
11371 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11372 {
11373 pAdapter = pAdapterNode->pAdapter;
11374 if (NULL != pAdapter)
11375 {
11376 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
11377 pRemainChanCtx = cfgState->remain_on_chan_ctx;
11378 if (pRemainChanCtx)
11379 break;
11380 }
11381 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
11382 pAdapterNode = pNext;
11383 }
11384 return pRemainChanCtx;
11385}
11386
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053011387/**
11388 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
11389 *
11390 * @pHddCtx: HDD context within host driver
11391 * @dfsScanMode: dfsScanMode passed from ioctl
11392 *
11393 */
11394
11395VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
11396 tANI_U8 dfsScanMode)
11397{
11398 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11399 hdd_adapter_t *pAdapter;
11400 VOS_STATUS vosStatus;
11401 hdd_station_ctx_t *pHddStaCtx;
11402 eHalStatus status = eHAL_STATUS_SUCCESS;
11403
11404 if(!pHddCtx)
11405 {
11406 hddLog(LOGE, FL("HDD context is Null"));
11407 return eHAL_STATUS_FAILURE;
11408 }
11409
11410 if (pHddCtx->scan_info.mScanPending)
11411 {
11412 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
11413 pHddCtx->scan_info.sessionId);
11414 hdd_abort_mac_scan(pHddCtx,
11415 pHddCtx->scan_info.sessionId,
11416 eCSR_SCAN_ABORT_DEFAULT);
11417 }
11418
11419 if (!dfsScanMode)
11420 {
11421 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11422 while ((NULL != pAdapterNode) &&
11423 (VOS_STATUS_SUCCESS == vosStatus))
11424 {
11425 pAdapter = pAdapterNode->pAdapter;
11426
11427 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11428 {
11429 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11430
11431 if(!pHddStaCtx)
11432 {
11433 hddLog(LOGE, FL("HDD STA context is Null"));
11434 return eHAL_STATUS_FAILURE;
11435 }
11436
11437 /* if STA is already connected on DFS channel,
11438 disconnect immediately*/
11439 if (hdd_connIsConnected(pHddStaCtx) &&
11440 (NV_CHANNEL_DFS ==
11441 vos_nv_getChannelEnabledState(
11442 pHddStaCtx->conn_info.operationChannel)))
11443 {
11444 status = sme_RoamDisconnect(pHddCtx->hHal,
11445 pAdapter->sessionId,
11446 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11447 hddLog(LOG1, FL("Client connected on DFS channel %d,"
11448 "sme_RoamDisconnect returned with status: %d"
11449 "for sessionid: %d"), pHddStaCtx->conn_info.
11450 operationChannel, status, pAdapter->sessionId);
11451 }
11452 }
11453
11454 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
11455 &pNext);
11456 pAdapterNode = pNext;
11457 }
11458 }
11459
11460 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
11461 sme_UpdateDFSRoamMode(pHddCtx->hHal,
11462 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
11463
11464 status = sme_HandleDFSChanScan(pHddCtx->hHal);
11465 if (!HAL_STATUS_SUCCESS(status))
11466 {
11467 hddLog(LOGE,
11468 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
11469 return status;
11470 }
11471
11472 return status;
11473}
11474
Jeff Johnson295189b2012-06-20 16:38:30 -070011475//Register the module init/exit functions
11476module_init(hdd_module_init);
11477module_exit(hdd_module_exit);
11478
11479MODULE_LICENSE("Dual BSD/GPL");
11480MODULE_AUTHOR("Qualcomm Atheros, Inc.");
11481MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
11482
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011483module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
11484 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011485
Jeff Johnson76052702013-04-16 13:55:05 -070011486module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011487 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080011488
11489module_param(enable_dfs_chan_scan, int,
11490 S_IRUSR | S_IRGRP | S_IROTH);
11491
11492module_param(enable_11d, int,
11493 S_IRUSR | S_IRGRP | S_IROTH);
11494
11495module_param(country_code, charp,
11496 S_IRUSR | S_IRGRP | S_IROTH);