blob: 9afc876747e10dea70e48dcf0d9bcc0ed52efc7f [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
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800229#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700230VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800231#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700232
Mihir Shetee1093ba2014-01-21 20:13:32 +0530233static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530234const char * hdd_device_modetoString(v_U8_t device_mode)
235{
236 switch(device_mode)
237 {
238 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
239 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
240 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
241 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
242 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
243 CASE_RETURN_STRING( WLAN_HDD_FTM );
244 CASE_RETURN_STRING( WLAN_HDD_IBSS );
245 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
246 default:
247 return "device_mode Unknown";
248 }
249}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530250
Jeff Johnson295189b2012-06-20 16:38:30 -0700251static int hdd_netdev_notifier_call(struct notifier_block * nb,
252 unsigned long state,
253 void *ndev)
254{
255 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700256 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700257 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700258#ifdef WLAN_BTAMP_FEATURE
259 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700260#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530261 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700262
263 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700264 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700265 (strncmp(dev->name, "p2p", 3)))
266 return NOTIFY_DONE;
267
Jeff Johnson295189b2012-06-20 16:38:30 -0700268 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700269 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700270
Jeff Johnson27cee452013-03-27 11:10:24 -0700271 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700272 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800273 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700274 VOS_ASSERT(0);
275 return NOTIFY_DONE;
276 }
277
Jeff Johnson27cee452013-03-27 11:10:24 -0700278 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
279 if (NULL == pHddCtx)
280 {
281 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
282 VOS_ASSERT(0);
283 return NOTIFY_DONE;
284 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800285 if (pHddCtx->isLogpInProgress)
286 return NOTIFY_DONE;
287
Jeff Johnson27cee452013-03-27 11:10:24 -0700288
289 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
290 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700291
292 switch (state) {
293 case NETDEV_REGISTER:
294 break;
295
296 case NETDEV_UNREGISTER:
297 break;
298
299 case NETDEV_UP:
300 break;
301
302 case NETDEV_DOWN:
303 break;
304
305 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700306 if(TRUE == pAdapter->isLinkUpSvcNeeded)
307 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700308 break;
309
310 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530311 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530312 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530313 {
314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
315 "%s: Timeout occurred while waiting for abortscan %ld",
316 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700317 }
318 else
319 {
320 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530321 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700322 }
323#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700325 status = WLANBAP_StopAmp();
326 if(VOS_STATUS_SUCCESS != status )
327 {
328 pHddCtx->isAmpAllowed = VOS_TRUE;
329 hddLog(VOS_TRACE_LEVEL_FATAL,
330 "%s: Failed to stop AMP", __func__);
331 }
332 else
333 {
334 //a state m/c implementation in PAL is TBD to avoid this delay
335 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700336 if ( pHddCtx->isAmpAllowed )
337 {
338 WLANBAP_DeregisterFromHCI();
339 pHddCtx->isAmpAllowed = VOS_FALSE;
340 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700341 }
342#endif //WLAN_BTAMP_FEATURE
343 break;
344
345 default:
346 break;
347 }
348
349 return NOTIFY_DONE;
350}
351
352struct notifier_block hdd_netdev_notifier = {
353 .notifier_call = hdd_netdev_notifier_call,
354};
355
356/*---------------------------------------------------------------------------
357 * Function definitions
358 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700359void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
360void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700361//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700362static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700363#ifndef MODULE
364/* current con_mode - used only for statically linked driver
365 * con_mode is changed by userspace to indicate a mode change which will
366 * result in calling the module exit and init functions. The module
367 * exit function will clean up based on the value of con_mode prior to it
368 * being changed by userspace. So curr_con_mode records the current con_mode
369 * for exit when con_mode becomes the next mode for init
370 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700371static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700372#endif
373
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800374/**---------------------------------------------------------------------------
375
376 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
377
378 Called immediately after the cfg.ini is read in order to configure
379 the desired trace levels.
380
381 \param - moduleId - module whose trace level is being configured
382 \param - bitmask - bitmask of log levels to be enabled
383
384 \return - void
385
386 --------------------------------------------------------------------------*/
387static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
388{
389 wpt_tracelevel level;
390
391 /* if the bitmask is the default value, then a bitmask was not
392 specified in cfg.ini, so leave the logging level alone (it
393 will remain at the "compiled in" default value) */
394 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
395 {
396 return;
397 }
398
399 /* a mask was specified. start by disabling all logging */
400 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
401
402 /* now cycle through the bitmask until all "set" bits are serviced */
403 level = VOS_TRACE_LEVEL_FATAL;
404 while (0 != bitmask)
405 {
406 if (bitmask & 1)
407 {
408 vos_trace_setValue(moduleId, level, 1);
409 }
410 level++;
411 bitmask >>= 1;
412 }
413}
414
415
Jeff Johnson295189b2012-06-20 16:38:30 -0700416/**---------------------------------------------------------------------------
417
418 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
419
420 Called immediately after the cfg.ini is read in order to configure
421 the desired trace levels in the WDI.
422
423 \param - moduleId - module whose trace level is being configured
424 \param - bitmask - bitmask of log levels to be enabled
425
426 \return - void
427
428 --------------------------------------------------------------------------*/
429static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
430{
431 wpt_tracelevel level;
432
433 /* if the bitmask is the default value, then a bitmask was not
434 specified in cfg.ini, so leave the logging level alone (it
435 will remain at the "compiled in" default value) */
436 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
437 {
438 return;
439 }
440
441 /* a mask was specified. start by disabling all logging */
442 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
443
444 /* now cycle through the bitmask until all "set" bits are serviced */
445 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
446 while (0 != bitmask)
447 {
448 if (bitmask & 1)
449 {
450 wpalTraceSetLevel(moduleId, level, 1);
451 }
452 level++;
453 bitmask >>= 1;
454 }
455}
Jeff Johnson295189b2012-06-20 16:38:30 -0700456
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530457/*
458 * FUNCTION: wlan_hdd_validate_context
459 * This function is used to check the HDD context
460 */
461int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
462{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530463
464 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
465 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530467 "%s: HDD context is Null", __func__);
468 return -ENODEV;
469 }
470
471 if (pHddCtx->isLogpInProgress)
472 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530473 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530474 "%s: LOGP %s. Ignore!!", __func__,
475 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
476 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530477 return -EAGAIN;
478 }
479
Mihir Shete18156292014-03-11 15:38:30 +0530480 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530481 {
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: Unloading/Loading in Progress. Ignore!!!", __func__);
484 return -EAGAIN;
485 }
486 return 0;
487}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700488#ifdef CONFIG_ENABLE_LINUX_REG
489void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
490{
491 hdd_adapter_t *pAdapter = NULL;
492 hdd_station_ctx_t *pHddStaCtx = NULL;
493 eCsrPhyMode phyMode;
494 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530495
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700496 if (NULL == pHddCtx)
497 {
498 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
499 "HDD Context is null !!");
500 return ;
501 }
502
503 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
504 if (NULL == pAdapter)
505 {
506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
507 "pAdapter is null !!");
508 return ;
509 }
510
511 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
512 if (NULL == pHddStaCtx)
513 {
514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
515 "pHddStaCtx is null !!");
516 return ;
517 }
518
519 cfg_param = pHddCtx->cfg_ini;
520 if (NULL == cfg_param)
521 {
522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
523 "cfg_params not available !!");
524 return ;
525 }
526
527 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
528
529 if (!pHddCtx->isVHT80Allowed)
530 {
531 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
532 (eCSR_DOT11_MODE_11ac == phyMode) ||
533 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
534 {
535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
536 "Setting phymode to 11n!!");
537 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
538 }
539 }
540 else
541 {
542 /*New country Supports 11ac as well resetting value back from .ini*/
543 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
544 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
545 return ;
546 }
547
548 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
549 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
550 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
551 {
552 VOS_STATUS vosStatus;
553
554 // need to issue a disconnect to CSR.
555 INIT_COMPLETION(pAdapter->disconnect_comp_var);
556 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
557 pAdapter->sessionId,
558 eCSR_DISCONNECT_REASON_UNSPECIFIED );
559
560 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530561 {
562 long ret;
563
564 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700565 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530566 if (0 >= ret)
567 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
568 ret);
569 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700570
571 }
572}
573#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530574void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
575{
576 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
577 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
578 hdd_config_t *cfg_param;
579 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530580 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530581
582 if (NULL == pHddCtx)
583 {
584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
585 "HDD Context is null !!");
586 return ;
587 }
588
589 cfg_param = pHddCtx->cfg_ini;
590
591 if (NULL == cfg_param)
592 {
593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
594 "cfg_params not available !!");
595 return ;
596 }
597
598 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
599
600 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
601 {
602 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
603 (eCSR_DOT11_MODE_11ac == phyMode) ||
604 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
605 {
606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
607 "Setting phymode to 11n!!");
608 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
609 }
610 }
611 else
612 {
613 /*New country Supports 11ac as well resetting value back from .ini*/
614 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
615 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
616 return ;
617 }
618
619 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
620 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
621 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
622 {
623 VOS_STATUS vosStatus;
624
625 // need to issue a disconnect to CSR.
626 INIT_COMPLETION(pAdapter->disconnect_comp_var);
627 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
628 pAdapter->sessionId,
629 eCSR_DISCONNECT_REASON_UNSPECIFIED );
630
631 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530632 {
633 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530634 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530635 if (ret <= 0)
636 {
637 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
638 "wait on disconnect_comp_var is failed %ld", ret);
639 }
640 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530641
642 }
643}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700644#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530645
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700646void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
647{
648 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
649 hdd_config_t *cfg_param;
650
651 if (NULL == pHddCtx)
652 {
653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
654 "HDD Context is null !!");
655 return ;
656 }
657
658 cfg_param = pHddCtx->cfg_ini;
659
660 if (NULL == cfg_param)
661 {
662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
663 "cfg_params not available !!");
664 return ;
665 }
666
Agarwal Ashish738843c2014-09-25 12:27:56 +0530667 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
668 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700669 {
670 /*New country doesn't support DFS */
671 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
672 }
673 else
674 {
675 /*New country Supports DFS as well resetting value back from .ini*/
676 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
677 }
678
679}
680
Rajeev79dbe4c2013-10-05 11:03:42 +0530681#ifdef FEATURE_WLAN_BATCH_SCAN
682
683/**---------------------------------------------------------------------------
684
685 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
686 input string
687
688 This function extracts assigned integer from string in below format:
689 "STRING=10" : extracts integer 10 from this string
690
691 \param - pInPtr Pointer to input string
692 \param - base Base for string to int conversion(10 for decimal 16 for hex)
693 \param - pOutPtr Pointer to variable in which extracted integer needs to be
694 assigned
695 \param - pLastArg to tell whether it is last arguement in input string or
696 not
697
698 \return - NULL for failure cases
699 pointer to next arguement in input string for success cases
700 --------------------------------------------------------------------------*/
701static tANI_U8 *
702hdd_extract_assigned_int_from_str
703(
704 tANI_U8 *pInPtr,
705 tANI_U8 base,
706 tANI_U32 *pOutPtr,
707 tANI_U8 *pLastArg
708)
709{
710 int tempInt;
711 int v = 0;
712 char buf[32];
713 int val = 0;
714 *pLastArg = FALSE;
715
716 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
717 if (NULL == pInPtr)
718 {
719 return NULL;
720 }
721
722 pInPtr++;
723
724 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
725
726 val = sscanf(pInPtr, "%32s ", buf);
727 if (val < 0 && val > strlen(pInPtr))
728 {
729 return NULL;
730 }
731 pInPtr += val;
732 v = kstrtos32(buf, base, &tempInt);
733 if (v < 0)
734 {
735 return NULL;
736 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800737 if (tempInt < 0)
738 {
739 tempInt = 0;
740 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530741 *pOutPtr = tempInt;
742
743 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
744 if (NULL == pInPtr)
745 {
746 *pLastArg = TRUE;
747 return NULL;
748 }
749 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
750
751 return pInPtr;
752}
753
754/**---------------------------------------------------------------------------
755
756 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
757 input string
758
759 This function extracts assigned character from string in below format:
760 "STRING=A" : extracts char 'A' from this string
761
762 \param - pInPtr Pointer to input string
763 \param - pOutPtr Pointer to variable in which extracted char needs to be
764 assigned
765 \param - pLastArg to tell whether it is last arguement in input string or
766 not
767
768 \return - NULL for failure cases
769 pointer to next arguement in input string for success cases
770 --------------------------------------------------------------------------*/
771static tANI_U8 *
772hdd_extract_assigned_char_from_str
773(
774 tANI_U8 *pInPtr,
775 tANI_U8 *pOutPtr,
776 tANI_U8 *pLastArg
777)
778{
779 *pLastArg = FALSE;
780
781 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
782 if (NULL == pInPtr)
783 {
784 return NULL;
785 }
786
787 pInPtr++;
788
789 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
790
791 *pOutPtr = *pInPtr;
792
793 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
794 if (NULL == pInPtr)
795 {
796 *pLastArg = TRUE;
797 return NULL;
798 }
799 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
800
801 return pInPtr;
802}
803
804
805/**---------------------------------------------------------------------------
806
807 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
808
809 This function parses set batch scan command in below format:
810 WLS_BATCHING_SET <space> followed by below arguements
811 "SCANFREQ=XX" : Optional defaults to 30 sec
812 "MSCAN=XX" : Required number of scans to attempt to batch
813 "BESTN=XX" : Best Network (RSSI) defaults to 16
814 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
815 A. implies only 5 GHz , B. implies only 2.4GHz
816 "RTT=X" : optional defaults to 0
817 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
818 error
819
820 For example input commands:
821 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
822 translated into set batch scan with following parameters:
823 a) Frequence 60 seconds
824 b) Batch 10 scans together
825 c) Best RSSI to be 20
826 d) 5GHz band only
827 e) RTT is equal to 0
828
829 \param - pValue Pointer to input channel list
830 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
831
832 \return - 0 for success non-zero for failure
833
834 --------------------------------------------------------------------------*/
835static int
836hdd_parse_set_batchscan_command
837(
838 tANI_U8 *pValue,
839 tSirSetBatchScanReq *pHddSetBatchScanReq
840)
841{
842 tANI_U8 *inPtr = pValue;
843 tANI_U8 val = 0;
844 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800845 tANI_U32 nScanFreq;
846 tANI_U32 nMscan;
847 tANI_U32 nBestN;
848 tANI_U8 ucRfBand;
849 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800850 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530851
852 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800853 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
854 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
855 nRtt = 0;
856 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530857
858 /*go to space after WLS_BATCHING_SET command*/
859 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
860 /*no argument after the command*/
861 if (NULL == inPtr)
862 {
863 return -EINVAL;
864 }
865
866 /*no space after the command*/
867 else if (SPACE_ASCII_VALUE != *inPtr)
868 {
869 return -EINVAL;
870 }
871
872 /*removing empty spaces*/
873 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
874
875 /*no argument followed by spaces*/
876 if ('\0' == *inPtr)
877 {
878 return -EINVAL;
879 }
880
881 /*check and parse SCANFREQ*/
882 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
883 {
884 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800885 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800886
Rajeev Kumarc933d982013-11-18 20:04:20 -0800887 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800888 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800889 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800890 }
891
Rajeev79dbe4c2013-10-05 11:03:42 +0530892 if ( (NULL == inPtr) || (TRUE == lastArg))
893 {
894 return -EINVAL;
895 }
896 }
897
898 /*check and parse MSCAN*/
899 if ((strncmp(inPtr, "MSCAN", 5) == 0))
900 {
901 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800902 &nMscan, &lastArg);
903
904 if (0 == nMscan)
905 {
906 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
907 "invalid MSCAN=%d", nMscan);
908 return -EINVAL;
909 }
910
Rajeev79dbe4c2013-10-05 11:03:42 +0530911 if (TRUE == lastArg)
912 {
913 goto done;
914 }
915 else if (NULL == inPtr)
916 {
917 return -EINVAL;
918 }
919 }
920 else
921 {
922 return -EINVAL;
923 }
924
925 /*check and parse BESTN*/
926 if ((strncmp(inPtr, "BESTN", 5) == 0))
927 {
928 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800929 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800930
Rajeev Kumarc933d982013-11-18 20:04:20 -0800931 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800932 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800933 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800934 }
935
Rajeev79dbe4c2013-10-05 11:03:42 +0530936 if (TRUE == lastArg)
937 {
938 goto done;
939 }
940 else if (NULL == inPtr)
941 {
942 return -EINVAL;
943 }
944 }
945
946 /*check and parse CHANNEL*/
947 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
948 {
949 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800950
Rajeev79dbe4c2013-10-05 11:03:42 +0530951 if (('A' == val) || ('a' == val))
952 {
c_hpothuebf89732014-02-25 13:00:24 +0530953 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530954 }
955 else if (('B' == val) || ('b' == val))
956 {
c_hpothuebf89732014-02-25 13:00:24 +0530957 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530958 }
959 else
960 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800961 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
962 }
963
964 if (TRUE == lastArg)
965 {
966 goto done;
967 }
968 else if (NULL == inPtr)
969 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530970 return -EINVAL;
971 }
972 }
973
974 /*check and parse RTT*/
975 if ((strncmp(inPtr, "RTT", 3) == 0))
976 {
977 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800978 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530979 if (TRUE == lastArg)
980 {
981 goto done;
982 }
983 if (NULL == inPtr)
984 {
985 return -EINVAL;
986 }
987 }
988
989
990done:
991
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800992 pHddSetBatchScanReq->scanFrequency = nScanFreq;
993 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
994 pHddSetBatchScanReq->bestNetwork = nBestN;
995 pHddSetBatchScanReq->rfBand = ucRfBand;
996 pHddSetBatchScanReq->rtt = nRtt;
997
Rajeev79dbe4c2013-10-05 11:03:42 +0530998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
999 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1000 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1001 pHddSetBatchScanReq->scanFrequency,
1002 pHddSetBatchScanReq->numberOfScansToBatch,
1003 pHddSetBatchScanReq->bestNetwork,
1004 pHddSetBatchScanReq->rfBand,
1005 pHddSetBatchScanReq->rtt);
1006
1007 return 0;
1008}/*End of hdd_parse_set_batchscan_command*/
1009
1010/**---------------------------------------------------------------------------
1011
1012 \brief hdd_set_batch_scan_req_callback () - This function is called after
1013 receiving set batch scan response from FW and it saves set batch scan
1014 response data FW to HDD context and sets the completion event on
1015 which hdd_ioctl is waiting
1016
1017 \param - callbackContext Pointer to HDD adapter
1018 \param - pRsp Pointer to set batch scan response data received from FW
1019
1020 \return - nothing
1021
1022 --------------------------------------------------------------------------*/
1023static void hdd_set_batch_scan_req_callback
1024(
1025 void *callbackContext,
1026 tSirSetBatchScanRsp *pRsp
1027)
1028{
1029 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1030 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1031
1032 /*sanity check*/
1033 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1034 {
1035 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1036 "%s: Invalid pAdapter magic", __func__);
1037 VOS_ASSERT(0);
1038 return;
1039 }
1040 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1041
1042 /*save set batch scan response*/
1043 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1044
1045 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1046 "Received set batch scan rsp from FW with nScansToBatch=%d",
1047 pHddSetBatchScanRsp->nScansToBatch);
1048
1049 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1050 complete(&pAdapter->hdd_set_batch_scan_req_var);
1051
1052 return;
1053}/*End of hdd_set_batch_scan_req_callback*/
1054
1055
1056/**---------------------------------------------------------------------------
1057
1058 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1059 info in hdd batch scan response queue
1060
1061 \param - pAdapter Pointer to hdd adapter
1062 \param - pAPMetaInfo Pointer to access point meta info
1063 \param - scanId scan ID of batch scan response
1064 \param - isLastAp tells whether AP is last AP in batch scan response or not
1065
1066 \return - nothing
1067
1068 --------------------------------------------------------------------------*/
1069static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1070 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1071{
1072 tHddBatchScanRsp *pHead;
1073 tHddBatchScanRsp *pNode;
1074 tHddBatchScanRsp *pPrev;
1075 tHddBatchScanRsp *pTemp;
1076 tANI_U8 ssidLen;
1077
1078 /*head of hdd batch scan response queue*/
1079 pHead = pAdapter->pBatchScanRsp;
1080
1081 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1082 if (NULL == pNode)
1083 {
1084 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1085 "%s: Could not allocate memory", __func__);
1086 VOS_ASSERT(0);
1087 return;
1088 }
1089
1090 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1091 sizeof(pNode->ApInfo.bssid));
1092 ssidLen = strlen(pApMetaInfo->ssid);
1093 if (SIR_MAX_SSID_SIZE < ssidLen)
1094 {
1095 /*invalid scan result*/
1096 vos_mem_free(pNode);
1097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1098 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1099 return;
1100 }
1101 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1102 /*null terminate ssid*/
1103 pNode->ApInfo.ssid[ssidLen] = '\0';
1104 pNode->ApInfo.ch = pApMetaInfo->ch;
1105 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1106 pNode->ApInfo.age = pApMetaInfo->timestamp;
1107 pNode->ApInfo.batchId = scanId;
1108 pNode->ApInfo.isLastAp = isLastAp;
1109
1110 pNode->pNext = NULL;
1111 if (NULL == pHead)
1112 {
1113 pAdapter->pBatchScanRsp = pNode;
1114 }
1115 else
1116 {
1117 pTemp = pHead;
1118 while (NULL != pTemp)
1119 {
1120 pPrev = pTemp;
1121 pTemp = pTemp->pNext;
1122 }
1123 pPrev->pNext = pNode;
1124 }
1125
1126 return;
1127}/*End of hdd_populate_batch_scan_rsp_queue*/
1128
1129/**---------------------------------------------------------------------------
1130
1131 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1132 receiving batch scan response indication from FW. It saves get batch scan
1133 response data in HDD batch scan response queue. This callback sets the
1134 completion event on which hdd_ioctl is waiting only after getting complete
1135 batch scan response data from FW
1136
1137 \param - callbackContext Pointer to HDD adapter
1138 \param - pRsp Pointer to get batch scan response data received from FW
1139
1140 \return - nothing
1141
1142 --------------------------------------------------------------------------*/
1143static void hdd_batch_scan_result_ind_callback
1144(
1145 void *callbackContext,
1146 void *pRsp
1147)
1148{
1149 v_BOOL_t isLastAp;
1150 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001151 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301152 tANI_U32 numberScanList;
1153 tANI_U32 nextScanListOffset;
1154 tANI_U32 nextApMetaInfoOffset;
1155 hdd_adapter_t* pAdapter;
1156 tpSirBatchScanList pScanList;
1157 tpSirBatchScanNetworkInfo pApMetaInfo;
1158 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1159 tSirSetBatchScanReq *pReq;
1160
1161 pAdapter = (hdd_adapter_t *)callbackContext;
1162 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001163 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301164 {
1165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1166 "%s: Invalid pAdapter magic", __func__);
1167 VOS_ASSERT(0);
1168 return;
1169 }
1170
1171 /*initialize locals*/
1172 pReq = &pAdapter->hddSetBatchScanReq;
1173 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1174 isLastAp = FALSE;
1175 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001176 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301177 numberScanList = 0;
1178 nextScanListOffset = 0;
1179 nextApMetaInfoOffset = 0;
1180 pScanList = NULL;
1181 pApMetaInfo = NULL;
1182
1183 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1184 {
1185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1186 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1187 isLastAp = TRUE;
1188 goto done;
1189 }
1190
1191 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1193 "Batch scan rsp: numberScalList %d", numberScanList);
1194
1195 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1196 {
1197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1198 "%s: numberScanList %d", __func__, numberScanList);
1199 isLastAp = TRUE;
1200 goto done;
1201 }
1202
1203 while (numberScanList)
1204 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001205 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301206 nextScanListOffset);
1207 if (NULL == pScanList)
1208 {
1209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1210 "%s: pScanList is %p", __func__, pScanList);
1211 isLastAp = TRUE;
1212 goto done;
1213 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001214 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001216 "Batch scan rsp: numApMetaInfo %d scanId %d",
1217 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301218
1219 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1220 {
1221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1222 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1223 isLastAp = TRUE;
1224 goto done;
1225 }
1226
Rajeev Kumarce651e42013-10-21 18:57:15 -07001227 /*Initialize next AP meta info offset for next scan list*/
1228 nextApMetaInfoOffset = 0;
1229
Rajeev79dbe4c2013-10-05 11:03:42 +05301230 while (numApMetaInfo)
1231 {
1232 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1233 nextApMetaInfoOffset);
1234 if (NULL == pApMetaInfo)
1235 {
1236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1237 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1238 isLastAp = TRUE;
1239 goto done;
1240 }
1241 /*calculate AP age*/
1242 pApMetaInfo->timestamp =
1243 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1244
1245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001246 "%s: bssId "MAC_ADDRESS_STR
1247 " ch %d rssi %d timestamp %d", __func__,
1248 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1249 pApMetaInfo->ch, pApMetaInfo->rssi,
1250 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301251
1252 /*mark last AP in batch scan response*/
1253 if ((TRUE == pBatchScanRsp->isLastResult) &&
1254 (1 == numberScanList) && (1 == numApMetaInfo))
1255 {
1256 isLastAp = TRUE;
1257 }
1258
1259 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1260 /*store batch scan repsonse in hdd queue*/
1261 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1262 pScanList->scanId, isLastAp);
1263 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1264
1265 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1266 numApMetaInfo--;
1267 }
1268
Rajeev Kumarce651e42013-10-21 18:57:15 -07001269 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1270 + (sizeof(tSirBatchScanNetworkInfo)
1271 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301272 numberScanList--;
1273 }
1274
1275done:
1276
1277 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1278 requested from hdd_ioctl*/
1279 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1280 (TRUE == isLastAp))
1281 {
1282 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1283 complete(&pAdapter->hdd_get_batch_scan_req_var);
1284 }
1285
1286 return;
1287}/*End of hdd_batch_scan_result_ind_callback*/
1288
1289/**---------------------------------------------------------------------------
1290
1291 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1292 response as per batch scan FR request format by putting proper markers
1293
1294 \param - pDest pointer to destination buffer
1295 \param - cur_len current length
1296 \param - tot_len total remaining size which can be written to user space
1297 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1298 \param - pAdapter Pointer to HDD adapter
1299
1300 \return - ret no of characters written
1301
1302 --------------------------------------------------------------------------*/
1303static tANI_U32
1304hdd_format_batch_scan_rsp
1305(
1306 tANI_U8 *pDest,
1307 tANI_U32 cur_len,
1308 tANI_U32 tot_len,
1309 tHddBatchScanRsp *pApMetaInfo,
1310 hdd_adapter_t* pAdapter
1311)
1312{
1313 tANI_U32 ret = 0;
1314 tANI_U32 rem_len = 0;
1315 tANI_U8 temp_len = 0;
1316 tANI_U8 temp_total_len = 0;
1317 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1318 tANI_U8 *pTemp = temp;
1319
1320 /*Batch scan reponse needs to be returned to user space in
1321 following format:
1322 "scancount=X\n" where X is the number of scans in current batch
1323 batch
1324 "trunc\n" optional present if current scan truncated
1325 "bssid=XX:XX:XX:XX:XX:XX\n"
1326 "ssid=XXXX\n"
1327 "freq=X\n" frequency in Mhz
1328 "level=XX\n"
1329 "age=X\n" ms
1330 "dist=X\n" cm (-1 if not available)
1331 "errror=X\n" (-1if not available)
1332 "====\n" (end of ap marker)
1333 "####\n" (end of scan marker)
1334 "----\n" (end of results)*/
1335 /*send scan result in above format to user space based on
1336 available length*/
1337 /*The GET response may have more data than the driver can return in its
1338 buffer. In that case the buffer should be filled to the nearest complete
1339 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1340 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1341 The final buffer should end with "----\n"*/
1342
1343 /*sanity*/
1344 if (cur_len > tot_len)
1345 {
1346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1347 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1348 return 0;
1349 }
1350 else
1351 {
1352 rem_len = (tot_len - cur_len);
1353 }
1354
1355 /*end scan marker*/
1356 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1357 {
1358 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1359 pTemp += temp_len;
1360 temp_total_len += temp_len;
1361 }
1362
1363 /*bssid*/
1364 temp_len = snprintf(pTemp, sizeof(temp),
1365 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1366 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1367 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1368 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1369 pTemp += temp_len;
1370 temp_total_len += temp_len;
1371
1372 /*ssid*/
1373 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1374 pApMetaInfo->ApInfo.ssid);
1375 pTemp += temp_len;
1376 temp_total_len += temp_len;
1377
1378 /*freq*/
1379 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001380 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301381 pTemp += temp_len;
1382 temp_total_len += temp_len;
1383
1384 /*level*/
1385 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1386 pApMetaInfo->ApInfo.rssi);
1387 pTemp += temp_len;
1388 temp_total_len += temp_len;
1389
1390 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001391 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301392 pApMetaInfo->ApInfo.age);
1393 pTemp += temp_len;
1394 temp_total_len += temp_len;
1395
1396 /*dist*/
1397 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1398 pTemp += temp_len;
1399 temp_total_len += temp_len;
1400
1401 /*error*/
1402 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1403 pTemp += temp_len;
1404 temp_total_len += temp_len;
1405
1406 /*end AP marker*/
1407 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1408 pTemp += temp_len;
1409 temp_total_len += temp_len;
1410
1411 /*last AP in batch scan response*/
1412 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1413 {
1414 /*end scan marker*/
1415 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1416 pTemp += temp_len;
1417 temp_total_len += temp_len;
1418
1419 /*end batch scan result marker*/
1420 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1421 pTemp += temp_len;
1422 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001423
Rajeev79dbe4c2013-10-05 11:03:42 +05301424 }
1425
1426 if (temp_total_len < rem_len)
1427 {
1428 ret = temp_total_len + 1;
1429 strlcpy(pDest, temp, ret);
1430 pAdapter->isTruncated = FALSE;
1431 }
1432 else
1433 {
1434 pAdapter->isTruncated = TRUE;
1435 if (rem_len >= strlen("%%%%"))
1436 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001437 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301438 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001439 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301440 {
1441 ret = 0;
1442 }
1443 }
1444
1445 return ret;
1446
1447}/*End of hdd_format_batch_scan_rsp*/
1448
1449/**---------------------------------------------------------------------------
1450
1451 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1452 buffer starting with head of hdd batch scan response queue
1453
1454 \param - pAdapter Pointer to HDD adapter
1455 \param - pDest Pointer to user data buffer
1456 \param - cur_len current offset in user buffer
1457 \param - rem_len remaining no of bytes in user buffer
1458
1459 \return - number of bytes written in user buffer
1460
1461 --------------------------------------------------------------------------*/
1462
1463tANI_U32 hdd_populate_user_batch_scan_rsp
1464(
1465 hdd_adapter_t* pAdapter,
1466 tANI_U8 *pDest,
1467 tANI_U32 cur_len,
1468 tANI_U32 rem_len
1469)
1470{
1471 tHddBatchScanRsp *pHead;
1472 tHddBatchScanRsp *pPrev;
1473 tANI_U32 len;
1474
Rajeev79dbe4c2013-10-05 11:03:42 +05301475 pAdapter->isTruncated = FALSE;
1476
1477 /*head of hdd batch scan response queue*/
1478 pHead = pAdapter->pBatchScanRsp;
1479 while (pHead)
1480 {
1481 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1482 pAdapter);
1483 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001484 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301485 cur_len += len;
1486 if(TRUE == pAdapter->isTruncated)
1487 {
1488 /*result is truncated return rest of scan rsp in next req*/
1489 cur_len = rem_len;
1490 break;
1491 }
1492 pPrev = pHead;
1493 pHead = pHead->pNext;
1494 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001495 if (TRUE == pPrev->ApInfo.isLastAp)
1496 {
1497 pAdapter->prev_batch_id = 0;
1498 }
1499 else
1500 {
1501 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1502 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301503 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001504 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301505 }
1506
1507 return cur_len;
1508}/*End of hdd_populate_user_batch_scan_rsp*/
1509
1510/**---------------------------------------------------------------------------
1511
1512 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1513 scan response data from HDD queue to user space
1514 It does following in detail:
1515 a) if HDD has enough data in its queue then it 1st copies data to user
1516 space and then send get batch scan indication message to FW. In this
1517 case it does not wait on any event and batch scan response data will
1518 be populated in HDD response queue in MC thread context after receiving
1519 indication from FW
1520 b) else send get batch scan indication message to FW and wait on an event
1521 which will be set once HDD receives complete batch scan response from
1522 FW and then this function returns batch scan response to user space
1523
1524 \param - pAdapter Pointer to HDD adapter
1525 \param - pPrivData Pointer to priv_data
1526
1527 \return - 0 for success -EFAULT for failure
1528
1529 --------------------------------------------------------------------------*/
1530
1531int hdd_return_batch_scan_rsp_to_user
1532(
1533 hdd_adapter_t* pAdapter,
1534 hdd_priv_data_t *pPrivData,
1535 tANI_U8 *command
1536)
1537{
1538 tANI_U8 *pDest;
1539 tANI_U32 count = 0;
1540 tANI_U32 len = 0;
1541 tANI_U32 cur_len = 0;
1542 tANI_U32 rem_len = 0;
1543 eHalStatus halStatus;
1544 unsigned long rc;
1545 tSirTriggerBatchScanResultInd *pReq;
1546
1547 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1548 pReq->param = 0;/*batch scan client*/
1549 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1550 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1551
1552 cur_len = pPrivData->used_len;
1553 if (pPrivData->total_len > pPrivData->used_len)
1554 {
1555 rem_len = pPrivData->total_len - pPrivData->used_len;
1556 }
1557 else
1558 {
1559 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1560 "%s: Invalid user data buffer total_len %d used_len %d",
1561 __func__, pPrivData->total_len, pPrivData->used_len);
1562 return -EFAULT;
1563 }
1564
1565 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1566 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1567 cur_len, rem_len);
1568 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1569
1570 /*enough scan result available in cache to return to user space or
1571 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001572 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301573 {
1574 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1575 halStatus = sme_TriggerBatchScanResultInd(
1576 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1577 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1578 pAdapter);
1579 if ( eHAL_STATUS_SUCCESS == halStatus )
1580 {
1581 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1582 {
1583 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1584 rc = wait_for_completion_timeout(
1585 &pAdapter->hdd_get_batch_scan_req_var,
1586 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1587 if (0 == rc)
1588 {
1589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1590 "%s: Timeout waiting to fetch batch scan rsp from fw",
1591 __func__);
1592 return -EFAULT;
1593 }
1594 }
1595
1596 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001597 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301598 pDest += len;
1599 cur_len += len;
1600
1601 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1602 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1603 cur_len, rem_len);
1604 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1605
1606 count = 0;
1607 len = (len - pPrivData->used_len);
1608 pDest = (command + pPrivData->used_len);
1609 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001610 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301611 while(count < len)
1612 {
1613 printk("%c", *(pDest + count));
1614 count++;
1615 }
1616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1617 "%s: copy %d data to user buffer", __func__, len);
1618 if (copy_to_user(pPrivData->buf, pDest, len))
1619 {
1620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1621 "%s: failed to copy data to user buffer", __func__);
1622 return -EFAULT;
1623 }
1624 }
1625 else
1626 {
1627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1628 "sme_GetBatchScanScan returned failure halStatus %d",
1629 halStatus);
1630 return -EINVAL;
1631 }
1632 }
1633 else
1634 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301635 count = 0;
1636 len = (len - pPrivData->used_len);
1637 pDest = (command + pPrivData->used_len);
1638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001639 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301640 while(count < len)
1641 {
1642 printk("%c", *(pDest + count));
1643 count++;
1644 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1646 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301647 if (copy_to_user(pPrivData->buf, pDest, len))
1648 {
1649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1650 "%s: failed to copy data to user buffer", __func__);
1651 return -EFAULT;
1652 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301653 }
1654
1655 return 0;
1656} /*End of hdd_return_batch_scan_rsp_to_user*/
1657
Rajeev Kumar8b373292014-01-08 20:36:55 -08001658
1659/**---------------------------------------------------------------------------
1660
1661 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1662 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1663 WLS_BATCHING VERSION
1664 WLS_BATCHING SET
1665 WLS_BATCHING GET
1666 WLS_BATCHING STOP
1667
1668 \param - pAdapter Pointer to HDD adapter
1669 \param - pPrivdata Pointer to priv_data
1670 \param - command Pointer to command
1671
1672 \return - 0 for success -EFAULT for failure
1673
1674 --------------------------------------------------------------------------*/
1675
1676int hdd_handle_batch_scan_ioctl
1677(
1678 hdd_adapter_t *pAdapter,
1679 hdd_priv_data_t *pPrivdata,
1680 tANI_U8 *command
1681)
1682{
1683 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001684 hdd_context_t *pHddCtx;
1685
1686 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1687 ret = wlan_hdd_validate_context(pHddCtx);
1688 if (ret)
1689 {
1690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1691 "%s: HDD context is not valid!", __func__);
1692 goto exit;
1693 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001694
1695 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1696 {
1697 char extra[32];
1698 tANI_U8 len = 0;
1699 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1700
1701 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1702 {
1703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1704 "%s: Batch scan feature is not supported by FW", __func__);
1705 ret = -EINVAL;
1706 goto exit;
1707 }
1708
1709 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1710 version);
1711 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1712 {
1713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1714 "%s: failed to copy data to user buffer", __func__);
1715 ret = -EFAULT;
1716 goto exit;
1717 }
1718 ret = HDD_BATCH_SCAN_VERSION;
1719 }
1720 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1721 {
1722 int status;
1723 tANI_U8 *value = (command + 16);
1724 eHalStatus halStatus;
1725 unsigned long rc;
1726 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1727 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1728
1729 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1730 {
1731 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1732 "%s: Batch scan feature is not supported by FW", __func__);
1733 ret = -EINVAL;
1734 goto exit;
1735 }
1736
1737 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1738 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1739 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1740 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1741 {
1742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301743 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001744 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301745 hdd_device_modetoString(pAdapter->device_mode),
1746 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001747 ret = -EINVAL;
1748 goto exit;
1749 }
1750
1751 status = hdd_parse_set_batchscan_command(value, pReq);
1752 if (status)
1753 {
1754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1755 "Invalid WLS_BATCHING SET command");
1756 ret = -EINVAL;
1757 goto exit;
1758 }
1759
1760
1761 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1762 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1763 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1764 pAdapter);
1765
1766 if ( eHAL_STATUS_SUCCESS == halStatus )
1767 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301768 char extra[32];
1769 tANI_U8 len = 0;
1770 tANI_U8 mScan = 0;
1771
Rajeev Kumar8b373292014-01-08 20:36:55 -08001772 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1773 "sme_SetBatchScanReq returned success halStatus %d",
1774 halStatus);
1775 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1776 {
1777 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1778 rc = wait_for_completion_timeout(
1779 &pAdapter->hdd_set_batch_scan_req_var,
1780 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1781 if (0 == rc)
1782 {
1783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1784 "%s: Timeout waiting for set batch scan to complete",
1785 __func__);
1786 ret = -EINVAL;
1787 goto exit;
1788 }
1789 }
1790 if ( !pRsp->nScansToBatch )
1791 {
1792 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1793 "%s: Received set batch scan failure response from FW",
1794 __func__);
1795 ret = -EINVAL;
1796 goto exit;
1797 }
1798 /*As per the Batch Scan Framework API we should return the MIN of
1799 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301800 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001801
1802 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1803
1804 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1805 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301806 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1807 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1808 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1809 {
1810 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1811 "%s: failed to copy MSCAN value to user buffer", __func__);
1812 ret = -EFAULT;
1813 goto exit;
1814 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001815 }
1816 else
1817 {
1818 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1819 "sme_SetBatchScanReq returned failure halStatus %d",
1820 halStatus);
1821 ret = -EINVAL;
1822 goto exit;
1823 }
1824 }
1825 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1826 {
1827 eHalStatus halStatus;
1828 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1829 pInd->param = 0;
1830
1831 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1832 {
1833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1834 "%s: Batch scan feature is not supported by FW", __func__);
1835 ret = -EINVAL;
1836 goto exit;
1837 }
1838
1839 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1840 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001842 "Batch scan is not yet enabled batch scan state %d",
1843 pAdapter->batchScanState);
1844 ret = -EINVAL;
1845 goto exit;
1846 }
1847
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001848 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1849 hdd_deinit_batch_scan(pAdapter);
1850 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1851
Rajeev Kumar8b373292014-01-08 20:36:55 -08001852 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1853
1854 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1855 pAdapter->sessionId);
1856 if ( eHAL_STATUS_SUCCESS == halStatus )
1857 {
1858 ret = 0;
1859 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1860 "sme_StopBatchScanInd returned success halStatus %d",
1861 halStatus);
1862 }
1863 else
1864 {
1865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1866 "sme_StopBatchScanInd returned failure halStatus %d",
1867 halStatus);
1868 ret = -EINVAL;
1869 goto exit;
1870 }
1871 }
1872 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1873 {
1874 tANI_U32 remain_len;
1875
1876 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1877 {
1878 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1879 "%s: Batch scan feature is not supported by FW", __func__);
1880 ret = -EINVAL;
1881 goto exit;
1882 }
1883
1884 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1885 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001887 "Batch scan is not yet enabled could not return results"
1888 "Batch Scan state %d",
1889 pAdapter->batchScanState);
1890 ret = -EINVAL;
1891 goto exit;
1892 }
1893
1894 pPrivdata->used_len = 16;
1895 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1896 if (remain_len < pPrivdata->total_len)
1897 {
1898 /*Clear previous batch scan response data if any*/
1899 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1900 }
1901 else
1902 {
1903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1904 "Invalid total length from user space can't fetch batch"
1905 " scan response total_len %d used_len %d remain len %d",
1906 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1907 ret = -EINVAL;
1908 goto exit;
1909 }
1910 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1911 }
1912
1913exit:
1914
1915 return ret;
1916}
1917
1918
Rajeev79dbe4c2013-10-05 11:03:42 +05301919#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1920
c_hpothu92367912014-05-01 15:18:17 +05301921static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1922{
c_hpothu39eb1e32014-06-26 16:31:50 +05301923 bcnMissRateContext_t *pCBCtx;
1924
1925 if (NULL == data)
1926 {
1927 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1928 return;
1929 }
c_hpothu92367912014-05-01 15:18:17 +05301930
1931 /* there is a race condition that exists between this callback
1932 function and the caller since the caller could time out either
1933 before or while this code is executing. we use a spinlock to
1934 serialize these actions */
1935 spin_lock(&hdd_context_lock);
1936
c_hpothu39eb1e32014-06-26 16:31:50 +05301937 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301938 gbcnMissRate = -1;
1939
c_hpothu39eb1e32014-06-26 16:31:50 +05301940 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301941 {
1942 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301943 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301944 spin_unlock(&hdd_context_lock);
1945 return ;
1946 }
1947
1948 if (VOS_STATUS_SUCCESS == status)
1949 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301950 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301951 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301952 else
1953 {
1954 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
1955 }
1956
c_hpothu92367912014-05-01 15:18:17 +05301957 complete(&(pCBCtx->completion));
1958 spin_unlock(&hdd_context_lock);
1959
1960 return;
1961}
1962
Abhishek Singh08aa7762014-12-16 13:59:03 +05301963void hdd_FWStatisCB( VOS_STATUS status,
1964 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05301965{
1966 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301967 hdd_adapter_t *pAdapter;
1968
1969 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
1970
Abhishek Singh08aa7762014-12-16 13:59:03 +05301971 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05301972 {
1973 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1974 return;
1975 }
1976 /* there is a race condition that exists between this callback
1977 function and the caller since the caller could time out either
1978 before or while this code is executing. we use a spinlock to
1979 serialize these actions */
1980 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05301981 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301982 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
1983 {
1984 hddLog(VOS_TRACE_LEVEL_ERROR,
1985 FL("invalid context magic: %08x"), fwStatsCtx->magic);
1986 spin_unlock(&hdd_context_lock);
1987 return;
1988 }
1989 pAdapter = fwStatsCtx->pAdapter;
1990 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
1991 {
1992 hddLog(VOS_TRACE_LEVEL_ERROR,
1993 FL("pAdapter returned is NULL or invalid"));
1994 spin_unlock(&hdd_context_lock);
1995 return;
1996 }
1997 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05301998 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05301999 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302000 switch( fwStatsResult->type )
2001 {
2002 case FW_UBSP_STATS:
2003 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302004 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302005 hddLog(VOS_TRACE_LEVEL_INFO,
2006 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302007 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2008 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302009 }
2010 break;
2011 default:
2012 {
2013 hddLog(VOS_TRACE_LEVEL_ERROR,
2014 FL(" No handling for stats type %d"),fwStatsResult->type);
2015 }
2016 }
2017 }
2018 complete(&(fwStatsCtx->completion));
2019 spin_unlock(&hdd_context_lock);
2020 return;
2021}
2022
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302023static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2024{
2025 int ret = 0;
2026
2027 if (!pCfg || !command || !extra || !len)
2028 {
2029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2030 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2031 ret = -EINVAL;
2032 return ret;
2033 }
2034
2035 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2036 {
2037 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2038 (int)pCfg->nActiveMaxChnTime);
2039 return ret;
2040 }
2041 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2042 {
2043 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2044 (int)pCfg->nActiveMinChnTime);
2045 return ret;
2046 }
2047 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2048 {
2049 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2050 (int)pCfg->nPassiveMaxChnTime);
2051 return ret;
2052 }
2053 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2054 {
2055 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2056 (int)pCfg->nPassiveMinChnTime);
2057 return ret;
2058 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302059 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2060 {
2061 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2062 (int)pCfg->nActiveMaxChnTime);
2063 return ret;
2064 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302065 else
2066 {
2067 ret = -EINVAL;
2068 }
2069
2070 return ret;
2071}
2072
2073static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2074{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302075 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302076 hdd_config_t *pCfg;
2077 tANI_U8 *value = command;
2078 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302079 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302080
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302081 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2082 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302083 {
2084 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2085 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2086 ret = -EINVAL;
2087 return ret;
2088 }
2089
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302090 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2091 sme_GetConfigParam(hHal, &smeConfig);
2092
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302093 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2094 {
2095 value = value + 24;
2096 temp = kstrtou32(value, 10, &val);
2097 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2098 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2099 {
2100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2101 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2102 ret = -EFAULT;
2103 return ret;
2104 }
2105 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302106 smeConfig.csrConfig.nActiveMaxChnTime = val;
2107 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302108 }
2109 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2110 {
2111 value = value + 24;
2112 temp = kstrtou32(value, 10, &val);
2113 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2114 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2115 {
2116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2117 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2118 ret = -EFAULT;
2119 return ret;
2120 }
2121 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302122 smeConfig.csrConfig.nActiveMinChnTime = val;
2123 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302124 }
2125 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2126 {
2127 value = value + 25;
2128 temp = kstrtou32(value, 10, &val);
2129 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2130 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2131 {
2132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2133 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2134 ret = -EFAULT;
2135 return ret;
2136 }
2137 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302138 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2139 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302140 }
2141 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2142 {
2143 value = value + 25;
2144 temp = kstrtou32(value, 10, &val);
2145 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2146 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2147 {
2148 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2149 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2150 ret = -EFAULT;
2151 return ret;
2152 }
2153 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302154 smeConfig.csrConfig.nPassiveMinChnTime = val;
2155 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302156 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302157 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2158 {
2159 value = value + 13;
2160 temp = kstrtou32(value, 10, &val);
2161 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2162 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2163 {
2164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2165 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2166 ret = -EFAULT;
2167 return ret;
2168 }
2169 pCfg->nActiveMaxChnTime = val;
2170 smeConfig.csrConfig.nActiveMaxChnTime = val;
2171 sme_UpdateConfig(hHal, &smeConfig);
2172 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302173 else
2174 {
2175 ret = -EINVAL;
2176 }
2177
2178 return ret;
2179}
2180
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002181static int hdd_driver_command(hdd_adapter_t *pAdapter,
2182 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002183{
Jeff Johnson295189b2012-06-20 16:38:30 -07002184 hdd_priv_data_t priv_data;
2185 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302186 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2187 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002188 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302189 int status;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002190 /*
2191 * Note that valid pointers are provided by caller
2192 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002193
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002194 /* copy to local struct to avoid numerous changes to legacy code */
2195 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002196
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002197 if (priv_data.total_len <= 0 ||
2198 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002199 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002200 hddLog(VOS_TRACE_LEVEL_WARN,
2201 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2202 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002203 ret = -EINVAL;
2204 goto exit;
2205 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302206 status = wlan_hdd_validate_context(pHddCtx);
2207 if (0 != status)
2208 {
2209 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2210 "%s: HDD context is not valid", __func__);
2211 return status;
2212 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002213 /* Allocate +1 for '\0' */
2214 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002215 if (!command)
2216 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002217 hddLog(VOS_TRACE_LEVEL_ERROR,
2218 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002219 ret = -ENOMEM;
2220 goto exit;
2221 }
2222
2223 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2224 {
2225 ret = -EFAULT;
2226 goto exit;
2227 }
2228
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002229 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002230 command[priv_data.total_len] = '\0';
2231
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002232 /* at one time the following block of code was conditional. braces
2233 * have been retained to avoid re-indenting the legacy code
2234 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002235 {
2236 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2237
2238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002239 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002240
2241 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2242 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302243 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2244 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2245 pAdapter->sessionId, (unsigned)
2246 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2247 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2248 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2249 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002250 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2251 sizeof(tSirMacAddr)))
2252 {
2253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002254 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002255 ret = -EFAULT;
2256 }
2257 }
Amar Singhal0974e402013-02-12 14:27:46 -08002258 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002259 {
Amar Singhal0974e402013-02-12 14:27:46 -08002260 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002261
Jeff Johnson295189b2012-06-20 16:38:30 -07002262 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002263
2264 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002265 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002267 "%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 -07002268 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002269 ret = hdd_setBand_helper(pAdapter->dev, ptr);
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05302270 if(ret < 0)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302271 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002272 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002273 }
Kiet Lamf040f472013-11-20 21:15:23 +05302274 else if(strncmp(command, "SETWMMPS", 8) == 0)
2275 {
2276 tANI_U8 *ptr = command;
2277 ret = hdd_wmmps_helper(pAdapter, ptr);
2278 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05302279
2280 else if(strncmp(command, "TDLSSCAN", 8) == 0)
2281 {
2282 tANI_U8 *ptr = command;
2283 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
2284 }
2285
Jeff Johnson32d95a32012-09-10 13:15:23 -07002286 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2287 {
2288 char *country_code;
2289
2290 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002291
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002292 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002293 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002294#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302295 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002296#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002297 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2298 (void *)(tSmeChangeCountryCallback)
2299 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302300 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002301 if (eHAL_STATUS_SUCCESS == ret)
2302 {
2303 ret = wait_for_completion_interruptible_timeout(
2304 &pAdapter->change_country_code,
2305 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2306 if (0 >= ret)
2307 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002308 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302309 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002310 }
2311 }
2312 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002313 {
2314 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002315 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002316 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002317 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002318
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002319 }
2320 /*
2321 command should be a string having format
2322 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2323 */
Amar Singhal0974e402013-02-12 14:27:46 -08002324 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002325 {
Amar Singhal0974e402013-02-12 14:27:46 -08002326 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002327
2328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002329 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002330
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002331 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002332 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002333 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2334 {
2335 int suspend = 0;
2336 tANI_U8 *ptr = (tANI_U8*)command + 15;
2337
2338 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302339 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2340 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2341 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002342 hdd_set_wlan_suspend_mode(suspend);
2343 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002344#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2345 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2346 {
2347 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002348 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002349 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2350 eHalStatus status = eHAL_STATUS_SUCCESS;
2351
2352 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2353 value = value + 15;
2354
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002355 /* Convert the value from ascii to integer */
2356 ret = kstrtos8(value, 10, &rssi);
2357 if (ret < 0)
2358 {
2359 /* If the input value is greater than max value of datatype, then also
2360 kstrtou8 fails */
2361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2362 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002363 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002364 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2365 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2366 ret = -EINVAL;
2367 goto exit;
2368 }
2369
Srinivas Girigowdade697412013-02-14 16:31:48 -08002370 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002371
Srinivas Girigowdade697412013-02-14 16:31:48 -08002372 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2373 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2374 {
2375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2376 "Neighbor lookup threshold value %d is out of range"
2377 " (Min: %d Max: %d)", lookUpThreshold,
2378 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2379 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2380 ret = -EINVAL;
2381 goto exit;
2382 }
2383
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302384 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2385 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2386 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2388 "%s: Received Command to Set Roam trigger"
2389 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2390
2391 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2392 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2393 if (eHAL_STATUS_SUCCESS != status)
2394 {
2395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2396 "%s: Failed to set roam trigger, try again", __func__);
2397 ret = -EPERM;
2398 goto exit;
2399 }
2400
2401 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302402 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002403 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2404 }
2405 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2406 {
2407 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2408 int rssi = (-1) * lookUpThreshold;
2409 char extra[32];
2410 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302411 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2412 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2413 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002414 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002415 if (copy_to_user(priv_data.buf, &extra, len + 1))
2416 {
2417 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2418 "%s: failed to copy data to user buffer", __func__);
2419 ret = -EFAULT;
2420 goto exit;
2421 }
2422 }
2423 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2424 {
2425 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002426 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002427 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002428
Srinivas Girigowdade697412013-02-14 16:31:48 -08002429 /* input refresh period is in terms of seconds */
2430 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2431 value = value + 18;
2432 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002433 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002434 if (ret < 0)
2435 {
2436 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002437 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002439 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002440 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002441 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2442 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002443 ret = -EINVAL;
2444 goto exit;
2445 }
2446
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002447 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2448 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002449 {
2450 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002451 "Roam scan period value %d is out of range"
2452 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002453 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2454 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002455 ret = -EINVAL;
2456 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302457 }
2458 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2459 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2460 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002461 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002462
2463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2464 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002465 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002466
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002467 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2468 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002469 }
2470 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2471 {
2472 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2473 char extra[32];
2474 tANI_U8 len = 0;
2475
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302476 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2477 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2478 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002479 len = scnprintf(extra, sizeof(extra), "%s %d",
2480 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002481 /* Returned value is in units of seconds */
2482 if (copy_to_user(priv_data.buf, &extra, len + 1))
2483 {
2484 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2485 "%s: failed to copy data to user buffer", __func__);
2486 ret = -EFAULT;
2487 goto exit;
2488 }
2489 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002490 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2491 {
2492 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002493 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002494 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002495
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002496 /* input refresh period is in terms of seconds */
2497 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2498 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002499
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002500 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002501 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002502 if (ret < 0)
2503 {
2504 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002505 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002506 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002507 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002508 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002509 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2510 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2511 ret = -EINVAL;
2512 goto exit;
2513 }
2514
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002515 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2516 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2517 {
2518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2519 "Neighbor scan results refresh period value %d is out of range"
2520 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2521 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2522 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2523 ret = -EINVAL;
2524 goto exit;
2525 }
2526 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2527
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002528 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2529 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002530 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002531
2532 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2533 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2534 }
2535 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2536 {
2537 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2538 char extra[32];
2539 tANI_U8 len = 0;
2540
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002541 len = scnprintf(extra, sizeof(extra), "%s %d",
2542 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002543 /* Returned value is in units of seconds */
2544 if (copy_to_user(priv_data.buf, &extra, len + 1))
2545 {
2546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2547 "%s: failed to copy data to user buffer", __func__);
2548 ret = -EFAULT;
2549 goto exit;
2550 }
2551 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002552#ifdef FEATURE_WLAN_LFR
2553 /* SETROAMMODE */
2554 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2555 {
2556 tANI_U8 *value = command;
2557 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2558
2559 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2560 value = value + SIZE_OF_SETROAMMODE + 1;
2561
2562 /* Convert the value from ascii to integer */
2563 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2564 if (ret < 0)
2565 {
2566 /* If the input value is greater than max value of datatype, then also
2567 kstrtou8 fails */
2568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2569 "%s: kstrtou8 failed range [%d - %d]", __func__,
2570 CFG_LFR_FEATURE_ENABLED_MIN,
2571 CFG_LFR_FEATURE_ENABLED_MAX);
2572 ret = -EINVAL;
2573 goto exit;
2574 }
2575 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2576 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2577 {
2578 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2579 "Roam Mode value %d is out of range"
2580 " (Min: %d Max: %d)", roamMode,
2581 CFG_LFR_FEATURE_ENABLED_MIN,
2582 CFG_LFR_FEATURE_ENABLED_MAX);
2583 ret = -EINVAL;
2584 goto exit;
2585 }
2586
2587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2588 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2589 /*
2590 * Note that
2591 * SETROAMMODE 0 is to enable LFR while
2592 * SETROAMMODE 1 is to disable LFR, but
2593 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2594 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2595 */
2596 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2597 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2598 else
2599 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2600
2601 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2602 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2603 }
2604 /* GETROAMMODE */
2605 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2606 {
2607 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2608 char extra[32];
2609 tANI_U8 len = 0;
2610
2611 /*
2612 * roamMode value shall be inverted because the sementics is different.
2613 */
2614 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2615 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2616 else
2617 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2618
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002619 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002620 if (copy_to_user(priv_data.buf, &extra, len + 1))
2621 {
2622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2623 "%s: failed to copy data to user buffer", __func__);
2624 ret = -EFAULT;
2625 goto exit;
2626 }
2627 }
2628#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002629#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002630#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002631 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2632 {
2633 tANI_U8 *value = command;
2634 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2635
2636 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2637 value = value + 13;
2638 /* Convert the value from ascii to integer */
2639 ret = kstrtou8(value, 10, &roamRssiDiff);
2640 if (ret < 0)
2641 {
2642 /* If the input value is greater than max value of datatype, then also
2643 kstrtou8 fails */
2644 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2645 "%s: kstrtou8 failed range [%d - %d]", __func__,
2646 CFG_ROAM_RSSI_DIFF_MIN,
2647 CFG_ROAM_RSSI_DIFF_MAX);
2648 ret = -EINVAL;
2649 goto exit;
2650 }
2651
2652 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2653 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2654 {
2655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2656 "Roam rssi diff value %d is out of range"
2657 " (Min: %d Max: %d)", roamRssiDiff,
2658 CFG_ROAM_RSSI_DIFF_MIN,
2659 CFG_ROAM_RSSI_DIFF_MAX);
2660 ret = -EINVAL;
2661 goto exit;
2662 }
2663
2664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2665 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2666
2667 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2668 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2669 }
2670 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2671 {
2672 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2673 char extra[32];
2674 tANI_U8 len = 0;
2675
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302676 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2677 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2678 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002679 len = scnprintf(extra, sizeof(extra), "%s %d",
2680 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002681 if (copy_to_user(priv_data.buf, &extra, len + 1))
2682 {
2683 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2684 "%s: failed to copy data to user buffer", __func__);
2685 ret = -EFAULT;
2686 goto exit;
2687 }
2688 }
2689#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002690#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002691 else if (strncmp(command, "GETBAND", 7) == 0)
2692 {
2693 int band = -1;
2694 char extra[32];
2695 tANI_U8 len = 0;
2696 hdd_getBand_helper(pHddCtx, &band);
2697
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302698 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2699 TRACE_CODE_HDD_GETBAND_IOCTL,
2700 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002701 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002702 if (copy_to_user(priv_data.buf, &extra, len + 1))
2703 {
2704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2705 "%s: failed to copy data to user buffer", __func__);
2706 ret = -EFAULT;
2707 goto exit;
2708 }
2709 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002710 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2711 {
2712 tANI_U8 *value = command;
2713 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2714 tANI_U8 numChannels = 0;
2715 eHalStatus status = eHAL_STATUS_SUCCESS;
2716
2717 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2718 if (eHAL_STATUS_SUCCESS != status)
2719 {
2720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2721 "%s: Failed to parse channel list information", __func__);
2722 ret = -EINVAL;
2723 goto exit;
2724 }
2725
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302726 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2727 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2728 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002729 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2730 {
2731 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2732 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2733 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2734 ret = -EINVAL;
2735 goto exit;
2736 }
2737 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2738 numChannels);
2739 if (eHAL_STATUS_SUCCESS != status)
2740 {
2741 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2742 "%s: Failed to update channel list information", __func__);
2743 ret = -EINVAL;
2744 goto exit;
2745 }
2746 }
2747 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2748 {
2749 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2750 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002751 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002752 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002753 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002754
2755 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2756 ChannelList, &numChannels ))
2757 {
2758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2759 "%s: failed to get roam scan channel list", __func__);
2760 ret = -EFAULT;
2761 goto exit;
2762 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302763 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2764 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2765 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002766 /* output channel list is of the format
2767 [Number of roam scan channels][Channel1][Channel2]... */
2768 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002769 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002770 for (j = 0; (j < numChannels); j++)
2771 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002772 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2773 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002774 }
2775
2776 if (copy_to_user(priv_data.buf, &extra, len + 1))
2777 {
2778 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2779 "%s: failed to copy data to user buffer", __func__);
2780 ret = -EFAULT;
2781 goto exit;
2782 }
2783 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002784 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2785 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002786 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002787 char extra[32];
2788 tANI_U8 len = 0;
2789
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002790 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002791 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002792 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002793 hdd_is_okc_mode_enabled(pHddCtx) &&
2794 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2795 {
2796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002797 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002798 " hence this operation is not permitted!", __func__);
2799 ret = -EPERM;
2800 goto exit;
2801 }
2802
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002803 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002804 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002805 if (copy_to_user(priv_data.buf, &extra, len + 1))
2806 {
2807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2808 "%s: failed to copy data to user buffer", __func__);
2809 ret = -EFAULT;
2810 goto exit;
2811 }
2812 }
2813 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2814 {
2815 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2816 char extra[32];
2817 tANI_U8 len = 0;
2818
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002819 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002820 then this operation is not permitted (return FAILURE) */
2821 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002822 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002823 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2824 {
2825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002826 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002827 " hence this operation is not permitted!", __func__);
2828 ret = -EPERM;
2829 goto exit;
2830 }
2831
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002832 len = scnprintf(extra, sizeof(extra), "%s %d",
2833 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002834 if (copy_to_user(priv_data.buf, &extra, len + 1))
2835 {
2836 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2837 "%s: failed to copy data to user buffer", __func__);
2838 ret = -EFAULT;
2839 goto exit;
2840 }
2841 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002842 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002843 {
2844 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2845 char extra[32];
2846 tANI_U8 len = 0;
2847
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002848 len = scnprintf(extra, sizeof(extra), "%s %d",
2849 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002850 if (copy_to_user(priv_data.buf, &extra, len + 1))
2851 {
2852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2853 "%s: failed to copy data to user buffer", __func__);
2854 ret = -EFAULT;
2855 goto exit;
2856 }
2857 }
2858 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2859 {
2860 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2861 char extra[32];
2862 tANI_U8 len = 0;
2863
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002864 len = scnprintf(extra, sizeof(extra), "%s %d",
2865 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002866 if (copy_to_user(priv_data.buf, &extra, len + 1))
2867 {
2868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2869 "%s: failed to copy data to user buffer", __func__);
2870 ret = -EFAULT;
2871 goto exit;
2872 }
2873 }
2874 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2875 {
2876 tANI_U8 *value = command;
2877 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2878
2879 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2880 value = value + 26;
2881 /* Convert the value from ascii to integer */
2882 ret = kstrtou8(value, 10, &minTime);
2883 if (ret < 0)
2884 {
2885 /* If the input value is greater than max value of datatype, then also
2886 kstrtou8 fails */
2887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2888 "%s: kstrtou8 failed range [%d - %d]", __func__,
2889 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2890 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2891 ret = -EINVAL;
2892 goto exit;
2893 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002894 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2895 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2896 {
2897 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2898 "scan min channel time value %d is out of range"
2899 " (Min: %d Max: %d)", minTime,
2900 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2901 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2902 ret = -EINVAL;
2903 goto exit;
2904 }
2905
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302906 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2907 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2908 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2910 "%s: Received Command to change channel min time = %d", __func__, minTime);
2911
2912 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2913 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2914 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002915 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2916 {
2917 tANI_U8 *value = command;
2918 tANI_U8 channel = 0;
2919 tANI_U8 dwellTime = 0;
2920 tANI_U8 bufLen = 0;
2921 tANI_U8 *buf = NULL;
2922 tSirMacAddr targetApBssid;
2923 eHalStatus status = eHAL_STATUS_SUCCESS;
2924 struct ieee80211_channel chan;
2925 tANI_U8 finalLen = 0;
2926 tANI_U8 *finalBuf = NULL;
2927 tANI_U8 temp = 0;
2928 u64 cookie;
2929 hdd_station_ctx_t *pHddStaCtx = NULL;
2930 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2931
2932 /* if not associated, no need to send action frame */
2933 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2934 {
2935 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2936 ret = -EINVAL;
2937 goto exit;
2938 }
2939
2940 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2941 &dwellTime, &buf, &bufLen);
2942 if (eHAL_STATUS_SUCCESS != status)
2943 {
2944 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2945 "%s: Failed to parse send action frame data", __func__);
2946 ret = -EINVAL;
2947 goto exit;
2948 }
2949
2950 /* if the target bssid is different from currently associated AP,
2951 then no need to send action frame */
2952 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2953 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2954 {
2955 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2956 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002957 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002958 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002959 goto exit;
2960 }
2961
2962 /* if the channel number is different from operating channel then
2963 no need to send action frame */
2964 if (channel != pHddStaCtx->conn_info.operationChannel)
2965 {
2966 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2967 "%s: channel(%d) is different from operating channel(%d)",
2968 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2969 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002970 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002971 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002972 goto exit;
2973 }
2974 chan.center_freq = sme_ChnToFreq(channel);
2975
2976 finalLen = bufLen + 24;
2977 finalBuf = vos_mem_malloc(finalLen);
2978 if (NULL == finalBuf)
2979 {
2980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2981 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002982 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002983 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002984 goto exit;
2985 }
2986 vos_mem_zero(finalBuf, finalLen);
2987
2988 /* Fill subtype */
2989 temp = SIR_MAC_MGMT_ACTION << 4;
2990 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2991
2992 /* Fill type */
2993 temp = SIR_MAC_MGMT_FRAME;
2994 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2995
2996 /* Fill destination address (bssid of the AP) */
2997 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2998
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002999 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003000 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3001
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003002 /* Fill BSSID (AP mac address) */
3003 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003004
3005 /* Fill received buffer from 24th address */
3006 vos_mem_copy(finalBuf + 24, buf, bufLen);
3007
Jeff Johnson11c33152013-04-16 17:52:40 -07003008 /* done with the parsed buffer */
3009 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003010 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003011
DARAM SUDHA39eede62014-02-12 11:16:40 +05303012 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003013#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3014 &(pAdapter->wdev),
3015#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003016 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003017#endif
3018 &chan, 0,
3019#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3020 NL80211_CHAN_HT20, 1,
3021#endif
3022 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003023 1, &cookie );
3024 vos_mem_free(finalBuf);
3025 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003026 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3027 {
3028 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3029 char extra[32];
3030 tANI_U8 len = 0;
3031
3032 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003033 len = scnprintf(extra, sizeof(extra), "%s %d",
3034 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303035 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3036 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3037 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003038 if (copy_to_user(priv_data.buf, &extra, len + 1))
3039 {
3040 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3041 "%s: failed to copy data to user buffer", __func__);
3042 ret = -EFAULT;
3043 goto exit;
3044 }
3045 }
3046 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3047 {
3048 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003049 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003050
3051 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3052 value = value + 19;
3053 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003054 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003055 if (ret < 0)
3056 {
3057 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003058 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003059 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003060 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003061 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3062 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3063 ret = -EINVAL;
3064 goto exit;
3065 }
3066
3067 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3068 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3069 {
3070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3071 "lfr mode value %d is out of range"
3072 " (Min: %d Max: %d)", maxTime,
3073 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3074 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3075 ret = -EINVAL;
3076 goto exit;
3077 }
3078
3079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3080 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3081
3082 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3083 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3084 }
3085 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3086 {
3087 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3088 char extra[32];
3089 tANI_U8 len = 0;
3090
3091 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003092 len = scnprintf(extra, sizeof(extra), "%s %d",
3093 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003094 if (copy_to_user(priv_data.buf, &extra, len + 1))
3095 {
3096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3097 "%s: failed to copy data to user buffer", __func__);
3098 ret = -EFAULT;
3099 goto exit;
3100 }
3101 }
3102 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3103 {
3104 tANI_U8 *value = command;
3105 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3106
3107 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3108 value = value + 16;
3109 /* Convert the value from ascii to integer */
3110 ret = kstrtou16(value, 10, &val);
3111 if (ret < 0)
3112 {
3113 /* If the input value is greater than max value of datatype, then also
3114 kstrtou16 fails */
3115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3116 "%s: kstrtou16 failed range [%d - %d]", __func__,
3117 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3118 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3119 ret = -EINVAL;
3120 goto exit;
3121 }
3122
3123 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3124 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3125 {
3126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3127 "scan home time value %d is out of range"
3128 " (Min: %d Max: %d)", val,
3129 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3130 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3131 ret = -EINVAL;
3132 goto exit;
3133 }
3134
3135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3136 "%s: Received Command to change scan home time = %d", __func__, val);
3137
3138 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3139 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3140 }
3141 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3142 {
3143 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3144 char extra[32];
3145 tANI_U8 len = 0;
3146
3147 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003148 len = scnprintf(extra, sizeof(extra), "%s %d",
3149 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003150 if (copy_to_user(priv_data.buf, &extra, len + 1))
3151 {
3152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3153 "%s: failed to copy data to user buffer", __func__);
3154 ret = -EFAULT;
3155 goto exit;
3156 }
3157 }
3158 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3159 {
3160 tANI_U8 *value = command;
3161 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3162
3163 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3164 value = value + 17;
3165 /* Convert the value from ascii to integer */
3166 ret = kstrtou8(value, 10, &val);
3167 if (ret < 0)
3168 {
3169 /* If the input value is greater than max value of datatype, then also
3170 kstrtou8 fails */
3171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3172 "%s: kstrtou8 failed range [%d - %d]", __func__,
3173 CFG_ROAM_INTRA_BAND_MIN,
3174 CFG_ROAM_INTRA_BAND_MAX);
3175 ret = -EINVAL;
3176 goto exit;
3177 }
3178
3179 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3180 (val > CFG_ROAM_INTRA_BAND_MAX))
3181 {
3182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3183 "intra band mode value %d is out of range"
3184 " (Min: %d Max: %d)", val,
3185 CFG_ROAM_INTRA_BAND_MIN,
3186 CFG_ROAM_INTRA_BAND_MAX);
3187 ret = -EINVAL;
3188 goto exit;
3189 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003190 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3191 "%s: Received Command to change intra band = %d", __func__, val);
3192
3193 pHddCtx->cfg_ini->nRoamIntraBand = val;
3194 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3195 }
3196 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3197 {
3198 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3199 char extra[32];
3200 tANI_U8 len = 0;
3201
3202 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003203 len = scnprintf(extra, sizeof(extra), "%s %d",
3204 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003205 if (copy_to_user(priv_data.buf, &extra, len + 1))
3206 {
3207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3208 "%s: failed to copy data to user buffer", __func__);
3209 ret = -EFAULT;
3210 goto exit;
3211 }
3212 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003213 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3214 {
3215 tANI_U8 *value = command;
3216 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3217
3218 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3219 value = value + 15;
3220 /* Convert the value from ascii to integer */
3221 ret = kstrtou8(value, 10, &nProbes);
3222 if (ret < 0)
3223 {
3224 /* If the input value is greater than max value of datatype, then also
3225 kstrtou8 fails */
3226 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3227 "%s: kstrtou8 failed range [%d - %d]", __func__,
3228 CFG_ROAM_SCAN_N_PROBES_MIN,
3229 CFG_ROAM_SCAN_N_PROBES_MAX);
3230 ret = -EINVAL;
3231 goto exit;
3232 }
3233
3234 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3235 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3236 {
3237 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3238 "NProbes value %d is out of range"
3239 " (Min: %d Max: %d)", nProbes,
3240 CFG_ROAM_SCAN_N_PROBES_MIN,
3241 CFG_ROAM_SCAN_N_PROBES_MAX);
3242 ret = -EINVAL;
3243 goto exit;
3244 }
3245
3246 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3247 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3248
3249 pHddCtx->cfg_ini->nProbes = nProbes;
3250 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3251 }
3252 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
3253 {
3254 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3255 char extra[32];
3256 tANI_U8 len = 0;
3257
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003258 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003259 if (copy_to_user(priv_data.buf, &extra, len + 1))
3260 {
3261 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3262 "%s: failed to copy data to user buffer", __func__);
3263 ret = -EFAULT;
3264 goto exit;
3265 }
3266 }
3267 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3268 {
3269 tANI_U8 *value = command;
3270 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3271
3272 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3273 /* input value is in units of msec */
3274 value = value + 20;
3275 /* Convert the value from ascii to integer */
3276 ret = kstrtou16(value, 10, &homeAwayTime);
3277 if (ret < 0)
3278 {
3279 /* If the input value is greater than max value of datatype, then also
3280 kstrtou8 fails */
3281 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3282 "%s: kstrtou8 failed range [%d - %d]", __func__,
3283 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3284 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3285 ret = -EINVAL;
3286 goto exit;
3287 }
3288
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003289 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3290 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3291 {
3292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3293 "homeAwayTime value %d is out of range"
3294 " (Min: %d Max: %d)", homeAwayTime,
3295 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3296 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3297 ret = -EINVAL;
3298 goto exit;
3299 }
3300
3301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3302 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003303 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3304 {
3305 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3306 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3307 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003308 }
3309 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3310 {
3311 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3312 char extra[32];
3313 tANI_U8 len = 0;
3314
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003315 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003316 if (copy_to_user(priv_data.buf, &extra, len + 1))
3317 {
3318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3319 "%s: failed to copy data to user buffer", __func__);
3320 ret = -EFAULT;
3321 goto exit;
3322 }
3323 }
3324 else if (strncmp(command, "REASSOC", 7) == 0)
3325 {
3326 tANI_U8 *value = command;
3327 tANI_U8 channel = 0;
3328 tSirMacAddr targetApBssid;
3329 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003330#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3331 tCsrHandoffRequest handoffInfo;
3332#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003333 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003334 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3335
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003336 /* if not associated, no need to proceed with reassoc */
3337 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3338 {
3339 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3340 ret = -EINVAL;
3341 goto exit;
3342 }
3343
3344 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3345 if (eHAL_STATUS_SUCCESS != status)
3346 {
3347 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3348 "%s: Failed to parse reassoc command data", __func__);
3349 ret = -EINVAL;
3350 goto exit;
3351 }
3352
3353 /* if the target bssid is same as currently associated AP,
3354 then no need to proceed with reassoc */
3355 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3356 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3357 {
3358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3359 ret = -EINVAL;
3360 goto exit;
3361 }
3362
3363 /* Check channel number is a valid channel number */
3364 if(VOS_STATUS_SUCCESS !=
3365 wlan_hdd_validate_operation_channel(pAdapter, channel))
3366 {
3367 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003368 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003369 return -EINVAL;
3370 }
3371
3372 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003373#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3374 handoffInfo.channel = channel;
3375 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3376 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3377#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003378 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003379 else if (strncmp(command, "SETWESMODE", 10) == 0)
3380 {
3381 tANI_U8 *value = command;
3382 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3383
3384 /* Move pointer to ahead of SETWESMODE<delimiter> */
3385 value = value + 11;
3386 /* Convert the value from ascii to integer */
3387 ret = kstrtou8(value, 10, &wesMode);
3388 if (ret < 0)
3389 {
3390 /* If the input value is greater than max value of datatype, then also
3391 kstrtou8 fails */
3392 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3393 "%s: kstrtou8 failed range [%d - %d]", __func__,
3394 CFG_ENABLE_WES_MODE_NAME_MIN,
3395 CFG_ENABLE_WES_MODE_NAME_MAX);
3396 ret = -EINVAL;
3397 goto exit;
3398 }
3399
3400 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3401 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3402 {
3403 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3404 "WES Mode value %d is out of range"
3405 " (Min: %d Max: %d)", wesMode,
3406 CFG_ENABLE_WES_MODE_NAME_MIN,
3407 CFG_ENABLE_WES_MODE_NAME_MAX);
3408 ret = -EINVAL;
3409 goto exit;
3410 }
3411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3412 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3413
3414 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3415 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3416 }
3417 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3418 {
3419 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3420 char extra[32];
3421 tANI_U8 len = 0;
3422
Arif Hussain826d9412013-11-12 16:44:54 -08003423 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003424 if (copy_to_user(priv_data.buf, &extra, len + 1))
3425 {
3426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3427 "%s: failed to copy data to user buffer", __func__);
3428 ret = -EFAULT;
3429 goto exit;
3430 }
3431 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003432#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003433#ifdef FEATURE_WLAN_LFR
3434 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3435 {
3436 tANI_U8 *value = command;
3437 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3438
3439 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3440 value = value + 12;
3441 /* Convert the value from ascii to integer */
3442 ret = kstrtou8(value, 10, &lfrMode);
3443 if (ret < 0)
3444 {
3445 /* If the input value is greater than max value of datatype, then also
3446 kstrtou8 fails */
3447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3448 "%s: kstrtou8 failed range [%d - %d]", __func__,
3449 CFG_LFR_FEATURE_ENABLED_MIN,
3450 CFG_LFR_FEATURE_ENABLED_MAX);
3451 ret = -EINVAL;
3452 goto exit;
3453 }
3454
3455 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3456 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3457 {
3458 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3459 "lfr mode value %d is out of range"
3460 " (Min: %d Max: %d)", lfrMode,
3461 CFG_LFR_FEATURE_ENABLED_MIN,
3462 CFG_LFR_FEATURE_ENABLED_MAX);
3463 ret = -EINVAL;
3464 goto exit;
3465 }
3466
3467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3468 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3469
3470 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3471 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3472 }
3473#endif
3474#ifdef WLAN_FEATURE_VOWIFI_11R
3475 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3476 {
3477 tANI_U8 *value = command;
3478 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3479
3480 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3481 value = value + 18;
3482 /* Convert the value from ascii to integer */
3483 ret = kstrtou8(value, 10, &ft);
3484 if (ret < 0)
3485 {
3486 /* If the input value is greater than max value of datatype, then also
3487 kstrtou8 fails */
3488 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3489 "%s: kstrtou8 failed range [%d - %d]", __func__,
3490 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3491 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3492 ret = -EINVAL;
3493 goto exit;
3494 }
3495
3496 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3497 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3498 {
3499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3500 "ft mode value %d is out of range"
3501 " (Min: %d Max: %d)", ft,
3502 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3503 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3504 ret = -EINVAL;
3505 goto exit;
3506 }
3507
3508 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3509 "%s: Received Command to change ft mode = %d", __func__, ft);
3510
3511 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3512 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3513 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303514
3515 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3516 {
3517 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303518 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303519 tSirMacAddr targetApBssid;
3520 tANI_U8 trigger = 0;
3521 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303522 tHalHandle hHal;
3523 v_U32_t roamId = 0;
3524 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303525 hdd_station_ctx_t *pHddStaCtx = NULL;
3526 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303527 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303528
3529 /* if not associated, no need to proceed with reassoc */
3530 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3531 {
3532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3533 ret = -EINVAL;
3534 goto exit;
3535 }
3536
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303537 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303538 if (eHAL_STATUS_SUCCESS != status)
3539 {
3540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3541 "%s: Failed to parse reassoc command data", __func__);
3542 ret = -EINVAL;
3543 goto exit;
3544 }
3545
3546 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303547 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303548 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3549 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3550 {
3551 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3552 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3553 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303554 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3555 &modProfileFields);
3556 sme_RoamReassoc(hHal, pAdapter->sessionId,
3557 NULL, modProfileFields, &roamId, 1);
3558 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303559 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303560
3561 /* Check channel number is a valid channel number */
3562 if(VOS_STATUS_SUCCESS !=
3563 wlan_hdd_validate_operation_channel(pAdapter, channel))
3564 {
3565 hddLog(VOS_TRACE_LEVEL_ERROR,
3566 "%s: Invalid Channel [%d]", __func__, channel);
3567 return -EINVAL;
3568 }
3569
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303570 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303571
3572 /* Proceed with scan/roam */
3573 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3574 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303575 (tSmeFastRoamTrigger)(trigger),
3576 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303577 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003578#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003579#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003580 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3581 {
3582 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003583 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003584
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003585 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003586 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003587 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003588 hdd_is_okc_mode_enabled(pHddCtx) &&
3589 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3590 {
3591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003592 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003593 " hence this operation is not permitted!", __func__);
3594 ret = -EPERM;
3595 goto exit;
3596 }
3597
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003598 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3599 value = value + 11;
3600 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003601 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003602 if (ret < 0)
3603 {
3604 /* If the input value is greater than max value of datatype, then also
3605 kstrtou8 fails */
3606 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3607 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003608 CFG_ESE_FEATURE_ENABLED_MIN,
3609 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003610 ret = -EINVAL;
3611 goto exit;
3612 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003613 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3614 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003615 {
3616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003617 "Ese mode value %d is out of range"
3618 " (Min: %d Max: %d)", eseMode,
3619 CFG_ESE_FEATURE_ENABLED_MIN,
3620 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003621 ret = -EINVAL;
3622 goto exit;
3623 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003625 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003626
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003627 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3628 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003629 }
3630#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003631 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3632 {
3633 tANI_U8 *value = command;
3634 tANI_BOOLEAN roamScanControl = 0;
3635
3636 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3637 value = value + 19;
3638 /* Convert the value from ascii to integer */
3639 ret = kstrtou8(value, 10, &roamScanControl);
3640 if (ret < 0)
3641 {
3642 /* If the input value is greater than max value of datatype, then also
3643 kstrtou8 fails */
3644 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3645 "%s: kstrtou8 failed ", __func__);
3646 ret = -EINVAL;
3647 goto exit;
3648 }
3649
3650 if (0 != roamScanControl)
3651 {
3652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3653 "roam scan control invalid value = %d",
3654 roamScanControl);
3655 ret = -EINVAL;
3656 goto exit;
3657 }
3658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3659 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3660
3661 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3662 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003663#ifdef FEATURE_WLAN_OKC
3664 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3665 {
3666 tANI_U8 *value = command;
3667 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3668
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003669 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003670 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003671 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003672 hdd_is_okc_mode_enabled(pHddCtx) &&
3673 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3674 {
3675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003676 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003677 " hence this operation is not permitted!", __func__);
3678 ret = -EPERM;
3679 goto exit;
3680 }
3681
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003682 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3683 value = value + 11;
3684 /* Convert the value from ascii to integer */
3685 ret = kstrtou8(value, 10, &okcMode);
3686 if (ret < 0)
3687 {
3688 /* If the input value is greater than max value of datatype, then also
3689 kstrtou8 fails */
3690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3691 "%s: kstrtou8 failed range [%d - %d]", __func__,
3692 CFG_OKC_FEATURE_ENABLED_MIN,
3693 CFG_OKC_FEATURE_ENABLED_MAX);
3694 ret = -EINVAL;
3695 goto exit;
3696 }
3697
3698 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3699 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3700 {
3701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3702 "Okc mode value %d is out of range"
3703 " (Min: %d Max: %d)", okcMode,
3704 CFG_OKC_FEATURE_ENABLED_MIN,
3705 CFG_OKC_FEATURE_ENABLED_MAX);
3706 ret = -EINVAL;
3707 goto exit;
3708 }
3709
3710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3711 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3712
3713 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3714 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003715#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003716 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3717 {
3718 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3719 char extra[32];
3720 tANI_U8 len = 0;
3721
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003722 len = scnprintf(extra, sizeof(extra), "%s %d",
3723 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003724 if (copy_to_user(priv_data.buf, &extra, len + 1))
3725 {
3726 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3727 "%s: failed to copy data to user buffer", __func__);
3728 ret = -EFAULT;
3729 goto exit;
3730 }
3731 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303732#ifdef WLAN_FEATURE_PACKET_FILTERING
3733 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3734 {
3735 tANI_U8 filterType = 0;
3736 tANI_U8 *value = command;
3737
3738 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3739 value = value + 22;
3740
3741 /* Convert the value from ascii to integer */
3742 ret = kstrtou8(value, 10, &filterType);
3743 if (ret < 0)
3744 {
3745 /* If the input value is greater than max value of datatype,
3746 * then also kstrtou8 fails
3747 */
3748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3749 "%s: kstrtou8 failed range ", __func__);
3750 ret = -EINVAL;
3751 goto exit;
3752 }
3753
3754 if (filterType != 0 && filterType != 1)
3755 {
3756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3757 "%s: Accepted Values are 0 and 1 ", __func__);
3758 ret = -EINVAL;
3759 goto exit;
3760 }
3761 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3762 pAdapter->sessionId);
3763 }
3764#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303765 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3766 {
Kiet Lamad161252014-07-22 11:23:32 -07003767 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303768 int ret;
3769
Kiet Lamad161252014-07-22 11:23:32 -07003770 dhcpPhase = command + 11;
3771 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303772 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003774 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303775
3776 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003777
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303778 ret = wlan_hdd_scan_abort(pAdapter);
3779 if (ret < 0)
3780 {
3781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3782 FL("failed to abort existing scan %d"), ret);
3783 }
3784
Kiet Lamad161252014-07-22 11:23:32 -07003785 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3786 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303787 }
Kiet Lamad161252014-07-22 11:23:32 -07003788 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303789 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003791 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303792
3793 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003794
3795 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3796 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303797 }
3798 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003799 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3800 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303801 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3802 FL("making default scan to ACTIVE"));
3803 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003804 }
3805 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3806 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3808 FL("making default scan to PASSIVE"));
3809 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003810 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303811 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3812 {
3813 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3814 char extra[32];
3815 tANI_U8 len = 0;
3816
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303817 memset(extra, 0, sizeof(extra));
3818 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3819 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303820 {
3821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3822 "%s: failed to copy data to user buffer", __func__);
3823 ret = -EFAULT;
3824 goto exit;
3825 }
3826 ret = len;
3827 }
3828 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3829 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303830 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303831 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003832 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3833 {
3834 tANI_U8 filterType = 0;
3835 tANI_U8 *value;
3836 value = command + 9;
3837
3838 /* Convert the value from ascii to integer */
3839 ret = kstrtou8(value, 10, &filterType);
3840 if (ret < 0)
3841 {
3842 /* If the input value is greater than max value of datatype,
3843 * then also kstrtou8 fails
3844 */
3845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3846 "%s: kstrtou8 failed range ", __func__);
3847 ret = -EINVAL;
3848 goto exit;
3849 }
3850 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3851 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3852 {
3853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3854 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3855 " 2-Sink ", __func__);
3856 ret = -EINVAL;
3857 goto exit;
3858 }
3859 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3860 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303861 pScanInfo = &pHddCtx->scan_info;
3862 if (filterType && pScanInfo != NULL &&
3863 pHddCtx->scan_info.mScanPending)
3864 {
3865 /*Miracast Session started. Abort Scan */
3866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3867 "%s, Aborting Scan For Miracast",__func__);
3868 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3869 eCSR_SCAN_ABORT_DEFAULT);
3870 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003871 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303872 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003873 }
Leo Chang614d2072013-08-22 14:59:44 -07003874 else if (strncmp(command, "SETMCRATE", 9) == 0)
3875 {
Leo Chang614d2072013-08-22 14:59:44 -07003876 tANI_U8 *value = command;
3877 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003878 tSirRateUpdateInd *rateUpdate;
3879 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003880
3881 /* Only valid for SAP mode */
3882 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3883 {
3884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3885 "%s: SAP mode is not running", __func__);
3886 ret = -EFAULT;
3887 goto exit;
3888 }
3889
3890 /* Move pointer to ahead of SETMCRATE<delimiter> */
3891 /* input value is in units of hundred kbps */
3892 value = value + 10;
3893 /* Convert the value from ascii to integer, decimal base */
3894 ret = kstrtouint(value, 10, &targetRate);
3895
Leo Chang1f98cbd2013-10-17 15:03:52 -07003896 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3897 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003898 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003899 hddLog(VOS_TRACE_LEVEL_ERROR,
3900 "%s: SETMCRATE indication alloc fail", __func__);
3901 ret = -EFAULT;
3902 goto exit;
3903 }
3904 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3905
3906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3907 "MC Target rate %d", targetRate);
3908 /* Ignore unicast */
3909 rateUpdate->ucastDataRate = -1;
3910 rateUpdate->mcastDataRate24GHz = targetRate;
3911 rateUpdate->mcastDataRate5GHz = targetRate;
3912 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3913 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3914 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3915 if (eHAL_STATUS_SUCCESS != status)
3916 {
3917 hddLog(VOS_TRACE_LEVEL_ERROR,
3918 "%s: SET_MC_RATE failed", __func__);
3919 vos_mem_free(rateUpdate);
3920 ret = -EFAULT;
3921 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003922 }
3923 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303924#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003925 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303926 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003927 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303928 }
3929#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003930#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003931 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3932 {
3933 tANI_U8 *value = command;
3934 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3935 tANI_U8 numChannels = 0;
3936 eHalStatus status = eHAL_STATUS_SUCCESS;
3937
3938 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3939 if (eHAL_STATUS_SUCCESS != status)
3940 {
3941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3942 "%s: Failed to parse channel list information", __func__);
3943 ret = -EINVAL;
3944 goto exit;
3945 }
3946
3947 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3948 {
3949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3950 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3951 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3952 ret = -EINVAL;
3953 goto exit;
3954 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003955 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003956 ChannelList,
3957 numChannels);
3958 if (eHAL_STATUS_SUCCESS != status)
3959 {
3960 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3961 "%s: Failed to update channel list information", __func__);
3962 ret = -EINVAL;
3963 goto exit;
3964 }
3965 }
3966 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3967 {
3968 tANI_U8 *value = command;
3969 char extra[128] = {0};
3970 int len = 0;
3971 tANI_U8 tid = 0;
3972 hdd_station_ctx_t *pHddStaCtx = NULL;
3973 tAniTrafStrmMetrics tsmMetrics;
3974 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3975
3976 /* if not associated, return error */
3977 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3978 {
3979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3980 ret = -EINVAL;
3981 goto exit;
3982 }
3983
3984 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3985 value = value + 12;
3986 /* Convert the value from ascii to integer */
3987 ret = kstrtou8(value, 10, &tid);
3988 if (ret < 0)
3989 {
3990 /* If the input value is greater than max value of datatype, then also
3991 kstrtou8 fails */
3992 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3993 "%s: kstrtou8 failed range [%d - %d]", __func__,
3994 TID_MIN_VALUE,
3995 TID_MAX_VALUE);
3996 ret = -EINVAL;
3997 goto exit;
3998 }
3999
4000 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4001 {
4002 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4003 "tid value %d is out of range"
4004 " (Min: %d Max: %d)", tid,
4005 TID_MIN_VALUE,
4006 TID_MAX_VALUE);
4007 ret = -EINVAL;
4008 goto exit;
4009 }
4010
4011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4012 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4013
4014 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4015 {
4016 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4017 "%s: failed to get tsm stats", __func__);
4018 ret = -EFAULT;
4019 goto exit;
4020 }
4021
4022 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4023 "UplinkPktQueueDly(%d)\n"
4024 "UplinkPktQueueDlyHist[0](%d)\n"
4025 "UplinkPktQueueDlyHist[1](%d)\n"
4026 "UplinkPktQueueDlyHist[2](%d)\n"
4027 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304028 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004029 "UplinkPktLoss(%d)\n"
4030 "UplinkPktCount(%d)\n"
4031 "RoamingCount(%d)\n"
4032 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4033 tsmMetrics.UplinkPktQueueDlyHist[0],
4034 tsmMetrics.UplinkPktQueueDlyHist[1],
4035 tsmMetrics.UplinkPktQueueDlyHist[2],
4036 tsmMetrics.UplinkPktQueueDlyHist[3],
4037 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4038 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4039
4040 /* Output TSM stats is of the format
4041 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4042 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004043 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004044 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4045 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4046 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4047 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4048 tsmMetrics.RoamingDly);
4049
4050 if (copy_to_user(priv_data.buf, &extra, len + 1))
4051 {
4052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4053 "%s: failed to copy data to user buffer", __func__);
4054 ret = -EFAULT;
4055 goto exit;
4056 }
4057 }
4058 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4059 {
4060 tANI_U8 *value = command;
4061 tANI_U8 *cckmIe = NULL;
4062 tANI_U8 cckmIeLen = 0;
4063 eHalStatus status = eHAL_STATUS_SUCCESS;
4064
4065 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4066 if (eHAL_STATUS_SUCCESS != status)
4067 {
4068 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4069 "%s: Failed to parse cckm ie data", __func__);
4070 ret = -EINVAL;
4071 goto exit;
4072 }
4073
4074 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4075 {
4076 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4077 "%s: CCKM Ie input length is more than max[%d]", __func__,
4078 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004079 vos_mem_free(cckmIe);
4080 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004081 ret = -EINVAL;
4082 goto exit;
4083 }
4084 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004085 vos_mem_free(cckmIe);
4086 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004087 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004088 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4089 {
4090 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004091 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004092 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004093
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004094 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004095 if (eHAL_STATUS_SUCCESS != status)
4096 {
4097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004098 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004099 ret = -EINVAL;
4100 goto exit;
4101 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004102 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4103 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4104 hdd_indicateEseBcnReportNoResults (pAdapter,
4105 eseBcnReq.bcnReq[0].measurementToken,
4106 0x02, //BIT(1) set for measurement done
4107 0); // no BSS
4108 goto exit;
4109 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004110
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004111 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4112 if (eHAL_STATUS_SUCCESS != status)
4113 {
4114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4115 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4116 ret = -EINVAL;
4117 goto exit;
4118 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004119 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004120#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304121 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4122 {
4123 eHalStatus status;
4124 char buf[32], len;
4125 long waitRet;
4126 bcnMissRateContext_t getBcnMissRateCtx;
4127
4128 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4129
4130 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4131 {
4132 hddLog(VOS_TRACE_LEVEL_WARN,
4133 FL("GETBCNMISSRATE: STA is not in connected state"));
4134 ret = -1;
4135 goto exit;
4136 }
4137
4138 init_completion(&(getBcnMissRateCtx.completion));
4139 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4140
4141 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4142 pAdapter->sessionId,
4143 (void *)getBcnMissRateCB,
4144 (void *)(&getBcnMissRateCtx));
4145 if( eHAL_STATUS_SUCCESS != status)
4146 {
4147 hddLog(VOS_TRACE_LEVEL_INFO,
4148 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4149 ret = -EINVAL;
4150 goto exit;
4151 }
4152
4153 waitRet = wait_for_completion_interruptible_timeout
4154 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4155 if(waitRet <= 0)
4156 {
4157 hddLog(VOS_TRACE_LEVEL_ERROR,
4158 FL("failed to wait on bcnMissRateComp %d"), ret);
4159
4160 //Make magic number to zero so that callback is not called.
4161 spin_lock(&hdd_context_lock);
4162 getBcnMissRateCtx.magic = 0x0;
4163 spin_unlock(&hdd_context_lock);
4164 ret = -EINVAL;
4165 goto exit;
4166 }
4167
4168 hddLog(VOS_TRACE_LEVEL_INFO,
4169 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4170
4171 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4172 if (copy_to_user(priv_data.buf, &buf, len + 1))
4173 {
4174 hddLog(VOS_TRACE_LEVEL_ERROR,
4175 "%s: failed to copy data to user buffer", __func__);
4176 ret = -EFAULT;
4177 goto exit;
4178 }
4179 ret = len;
4180 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304181#ifdef FEATURE_WLAN_TDLS
4182 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4183 tANI_U8 *value = command;
4184 int set_value;
4185 /* Move pointer to ahead of TDLSOFFCH*/
4186 value += 26;
4187 sscanf(value, "%d", &set_value);
4188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4189 "%s: Tdls offchannel offset:%d",
4190 __func__, set_value);
4191 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4192 if (ret < 0)
4193 {
4194 ret = -EINVAL;
4195 goto exit;
4196 }
4197
4198 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4199 tANI_U8 *value = command;
4200 int set_value;
4201 /* Move pointer to ahead of tdlsoffchnmode*/
4202 value += 18;
4203 sscanf(value, "%d", &set_value);
4204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4205 "%s: Tdls offchannel mode:%d",
4206 __func__, set_value);
4207 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4208 if (ret < 0)
4209 {
4210 ret = -EINVAL;
4211 goto exit;
4212 }
4213 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4214 tANI_U8 *value = command;
4215 int set_value;
4216 /* Move pointer to ahead of TDLSOFFCH*/
4217 value += 14;
4218 sscanf(value, "%d", &set_value);
4219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4220 "%s: Tdls offchannel num: %d",
4221 __func__, set_value);
4222 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4223 if (ret < 0)
4224 {
4225 ret = -EINVAL;
4226 goto exit;
4227 }
4228 }
4229#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304230 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4231 {
4232 eHalStatus status;
4233 char *buf = NULL;
4234 char len;
4235 long waitRet;
4236 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304237 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304238 tANI_U8 *ptr = command;
4239 int stats = *(ptr + 11) - '0';
4240
4241 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4242 if (!IS_FEATURE_FW_STATS_ENABLE)
4243 {
4244 hddLog(VOS_TRACE_LEVEL_INFO,
4245 FL("Get Firmware stats feature not supported"));
4246 ret = -EINVAL;
4247 goto exit;
4248 }
4249
4250 if (FW_STATS_MAX <= stats || 0 >= stats)
4251 {
4252 hddLog(VOS_TRACE_LEVEL_INFO,
4253 FL(" stats %d not supported"),stats);
4254 ret = -EINVAL;
4255 goto exit;
4256 }
4257
4258 init_completion(&(fwStatsCtx.completion));
4259 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4260 fwStatsCtx.pAdapter = pAdapter;
4261 fwStatsRsp->type = 0;
4262 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304263 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304264 if (eHAL_STATUS_SUCCESS != status)
4265 {
4266 hddLog(VOS_TRACE_LEVEL_ERROR,
4267 FL(" fail to post WDA cmd status = %d"), status);
4268 ret = -EINVAL;
4269 goto exit;
4270 }
4271 waitRet = wait_for_completion_timeout
4272 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4273 if (waitRet <= 0)
4274 {
4275 hddLog(VOS_TRACE_LEVEL_ERROR,
4276 FL("failed to wait on GwtFwstats"));
4277 //Make magic number to zero so that callback is not executed.
4278 spin_lock(&hdd_context_lock);
4279 fwStatsCtx.magic = 0x0;
4280 spin_unlock(&hdd_context_lock);
4281 ret = -EINVAL;
4282 goto exit;
4283 }
4284 if (fwStatsRsp->type)
4285 {
4286 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4287 if (!buf)
4288 {
4289 hddLog(VOS_TRACE_LEVEL_ERROR,
4290 FL(" failed to allocate memory"));
4291 ret = -ENOMEM;
4292 goto exit;
4293 }
4294 switch( fwStatsRsp->type )
4295 {
4296 case FW_UBSP_STATS:
4297 {
4298 len = snprintf(buf, FW_STATE_RSP_LEN,
4299 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304300 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4301 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304302 }
4303 break;
4304 default:
4305 {
4306 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4307 ret = -EFAULT;
4308 kfree(buf);
4309 goto exit;
4310 }
4311 }
4312 if (copy_to_user(priv_data.buf, buf, len + 1))
4313 {
4314 hddLog(VOS_TRACE_LEVEL_ERROR,
4315 FL(" failed to copy data to user buffer"));
4316 ret = -EFAULT;
4317 kfree(buf);
4318 goto exit;
4319 }
4320 ret = len;
4321 kfree(buf);
4322 }
4323 else
4324 {
4325 hddLog(VOS_TRACE_LEVEL_ERROR,
4326 FL("failed to fetch the stats"));
4327 ret = -EFAULT;
4328 goto exit;
4329 }
4330
4331 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004332 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304333 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4334 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4335 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304336 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4337 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004338 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004339 }
4340exit:
4341 if (command)
4342 {
4343 kfree(command);
4344 }
4345 return ret;
4346}
4347
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004348#ifdef CONFIG_COMPAT
4349static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4350{
4351 struct {
4352 compat_uptr_t buf;
4353 int used_len;
4354 int total_len;
4355 } compat_priv_data;
4356 hdd_priv_data_t priv_data;
4357 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004358
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004359 /*
4360 * Note that pAdapter and ifr have already been verified by caller,
4361 * and HDD context has also been validated
4362 */
4363 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4364 sizeof(compat_priv_data))) {
4365 ret = -EFAULT;
4366 goto exit;
4367 }
4368 priv_data.buf = compat_ptr(compat_priv_data.buf);
4369 priv_data.used_len = compat_priv_data.used_len;
4370 priv_data.total_len = compat_priv_data.total_len;
4371 ret = hdd_driver_command(pAdapter, &priv_data);
4372 exit:
4373 return ret;
4374}
4375#else /* CONFIG_COMPAT */
4376static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4377{
4378 /* will never be invoked */
4379 return 0;
4380}
4381#endif /* CONFIG_COMPAT */
4382
4383static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4384{
4385 hdd_priv_data_t priv_data;
4386 int ret = 0;
4387
4388 /*
4389 * Note that pAdapter and ifr have already been verified by caller,
4390 * and HDD context has also been validated
4391 */
4392 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4393 ret = -EFAULT;
4394 } else {
4395 ret = hdd_driver_command(pAdapter, &priv_data);
4396 }
4397 return ret;
4398}
4399
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304400int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004401{
4402 hdd_adapter_t *pAdapter;
4403 hdd_context_t *pHddCtx;
4404 int ret;
4405
4406 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4407 if (NULL == pAdapter) {
4408 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4409 "%s: HDD adapter context is Null", __func__);
4410 ret = -ENODEV;
4411 goto exit;
4412 }
4413 if (dev != pAdapter->dev) {
4414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4415 "%s: HDD adapter/dev inconsistency", __func__);
4416 ret = -ENODEV;
4417 goto exit;
4418 }
4419
4420 if ((!ifr) || (!ifr->ifr_data)) {
4421 ret = -EINVAL;
4422 goto exit;
4423 }
4424
4425 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4426 ret = wlan_hdd_validate_context(pHddCtx);
4427 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004428 ret = -EBUSY;
4429 goto exit;
4430 }
4431
4432 switch (cmd) {
4433 case (SIOCDEVPRIVATE + 1):
4434 if (is_compat_task())
4435 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4436 else
4437 ret = hdd_driver_ioctl(pAdapter, ifr);
4438 break;
4439 default:
4440 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4441 __func__, cmd);
4442 ret = -EINVAL;
4443 break;
4444 }
4445 exit:
4446 return ret;
4447}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004448
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304449int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4450{
4451 int ret;
4452
4453 vos_ssr_protect(__func__);
4454 ret = __hdd_ioctl(dev, ifr, cmd);
4455 vos_ssr_unprotect(__func__);
4456
4457 return ret;
4458}
4459
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004460#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004461/**---------------------------------------------------------------------------
4462
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004463 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004464
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004465 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004466 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4467 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4468 <space>Scan Mode N<space>Meas Duration N
4469 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4470 then take N.
4471 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4472 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4473 This function does not take care of removing duplicate channels from the list
4474
4475 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004476 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004477
4478 \return - 0 for success non-zero for failure
4479
4480 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004481static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4482 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004483{
4484 tANI_U8 *inPtr = pValue;
4485 int tempInt = 0;
4486 int j = 0, i = 0, v = 0;
4487 char buf[32];
4488
4489 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4490 /*no argument after the command*/
4491 if (NULL == inPtr)
4492 {
4493 return -EINVAL;
4494 }
4495 /*no space after the command*/
4496 else if (SPACE_ASCII_VALUE != *inPtr)
4497 {
4498 return -EINVAL;
4499 }
4500
4501 /*removing empty spaces*/
4502 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4503
4504 /*no argument followed by spaces*/
4505 if ('\0' == *inPtr) return -EINVAL;
4506
4507 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004508 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004509 if (1 != v) return -EINVAL;
4510
4511 v = kstrtos32(buf, 10, &tempInt);
4512 if ( v < 0) return -EINVAL;
4513
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004514 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004515
4516 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004517 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004518
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004519 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004520 {
4521 for (i = 0; i < 4; i++)
4522 {
4523 /*inPtr pointing to the beginning of first space after number of ie fields*/
4524 inPtr = strpbrk( inPtr, " " );
4525 /*no ie data after the number of ie fields argument*/
4526 if (NULL == inPtr) return -EINVAL;
4527
4528 /*removing empty space*/
4529 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4530
4531 /*no ie data after the number of ie fields argument and spaces*/
4532 if ( '\0' == *inPtr ) return -EINVAL;
4533
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004534 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004535 if (1 != v) return -EINVAL;
4536
4537 v = kstrtos32(buf, 10, &tempInt);
4538 if (v < 0) return -EINVAL;
4539
4540 switch (i)
4541 {
4542 case 0: /* Measurement token */
4543 if (tempInt <= 0)
4544 {
4545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4546 "Invalid Measurement Token(%d)", tempInt);
4547 return -EINVAL;
4548 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004549 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004550 break;
4551
4552 case 1: /* Channel number */
4553 if ((tempInt <= 0) ||
4554 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4555 {
4556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4557 "Invalid Channel Number(%d)", tempInt);
4558 return -EINVAL;
4559 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004560 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004561 break;
4562
4563 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004564 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004565 {
4566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4567 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4568 return -EINVAL;
4569 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004570 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004571 break;
4572
4573 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004574 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4575 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004576 {
4577 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4578 "Invalid Measurement Duration(%d)", tempInt);
4579 return -EINVAL;
4580 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004581 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004582 break;
4583 }
4584 }
4585 }
4586
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004587 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004588 {
4589 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304590 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004591 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004592 pEseBcnReq->bcnReq[j].measurementToken,
4593 pEseBcnReq->bcnReq[j].channel,
4594 pEseBcnReq->bcnReq[j].scanMode,
4595 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004596 }
4597
4598 return VOS_STATUS_SUCCESS;
4599}
4600
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004601static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4602{
4603 struct statsContext *pStatsContext = NULL;
4604 hdd_adapter_t *pAdapter = NULL;
4605
4606 if (NULL == pContext)
4607 {
4608 hddLog(VOS_TRACE_LEVEL_ERROR,
4609 "%s: Bad param, pContext [%p]",
4610 __func__, pContext);
4611 return;
4612 }
4613
Jeff Johnson72a40512013-12-19 10:14:15 -08004614 /* there is a race condition that exists between this callback
4615 function and the caller since the caller could time out either
4616 before or while this code is executing. we use a spinlock to
4617 serialize these actions */
4618 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004619
4620 pStatsContext = pContext;
4621 pAdapter = pStatsContext->pAdapter;
4622 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4623 {
4624 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004625 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004626 hddLog(VOS_TRACE_LEVEL_WARN,
4627 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4628 __func__, pAdapter, pStatsContext->magic);
4629 return;
4630 }
4631
Jeff Johnson72a40512013-12-19 10:14:15 -08004632 /* context is valid so caller is still waiting */
4633
4634 /* paranoia: invalidate the magic */
4635 pStatsContext->magic = 0;
4636
4637 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004638 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4639 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4640 tsmMetrics.UplinkPktQueueDlyHist,
4641 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4642 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4643 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4644 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4645 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4646 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4647 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4648
Jeff Johnson72a40512013-12-19 10:14:15 -08004649 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004650 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004651
4652 /* serialization is complete */
4653 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004654}
4655
4656
4657
4658static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4659 tAniTrafStrmMetrics* pTsmMetrics)
4660{
4661 hdd_station_ctx_t *pHddStaCtx = NULL;
4662 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004663 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004664 long lrc;
4665 struct statsContext context;
4666 hdd_context_t *pHddCtx = NULL;
4667
4668 if (NULL == pAdapter)
4669 {
4670 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4671 return VOS_STATUS_E_FAULT;
4672 }
4673
4674 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4675 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4676
4677 /* we are connected prepare our callback context */
4678 init_completion(&context.completion);
4679 context.pAdapter = pAdapter;
4680 context.magic = STATS_CONTEXT_MAGIC;
4681
4682 /* query tsm stats */
4683 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4684 pHddStaCtx->conn_info.staId[ 0 ],
4685 pHddStaCtx->conn_info.bssId,
4686 &context, pHddCtx->pvosContext, tid);
4687
4688 if (eHAL_STATUS_SUCCESS != hstatus)
4689 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004690 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4691 __func__);
4692 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004693 }
4694 else
4695 {
4696 /* request was sent -- wait for the response */
4697 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4698 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004699 if (lrc <= 0)
4700 {
4701 hddLog(VOS_TRACE_LEVEL_ERROR,
4702 "%s: SME %s while retrieving statistics",
4703 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004704 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004705 }
4706 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004707
Jeff Johnson72a40512013-12-19 10:14:15 -08004708 /* either we never sent a request, we sent a request and received a
4709 response or we sent a request and timed out. if we never sent a
4710 request or if we sent a request and got a response, we want to
4711 clear the magic out of paranoia. if we timed out there is a
4712 race condition such that the callback function could be
4713 executing at the same time we are. of primary concern is if the
4714 callback function had already verified the "magic" but had not
4715 yet set the completion variable when a timeout occurred. we
4716 serialize these activities by invalidating the magic while
4717 holding a shared spinlock which will cause us to block if the
4718 callback is currently executing */
4719 spin_lock(&hdd_context_lock);
4720 context.magic = 0;
4721 spin_unlock(&hdd_context_lock);
4722
4723 if (VOS_STATUS_SUCCESS == vstatus)
4724 {
4725 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4726 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4727 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4728 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4729 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4730 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4731 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4732 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4733 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4734 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4735 }
4736 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004737}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004738#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004739
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004740#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004741void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4742{
4743 eCsrBand band = -1;
4744 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4745 switch (band)
4746 {
4747 case eCSR_BAND_ALL:
4748 *pBand = WLAN_HDD_UI_BAND_AUTO;
4749 break;
4750
4751 case eCSR_BAND_24:
4752 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4753 break;
4754
4755 case eCSR_BAND_5G:
4756 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4757 break;
4758
4759 default:
4760 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4761 *pBand = -1;
4762 break;
4763 }
4764}
4765
4766/**---------------------------------------------------------------------------
4767
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004768 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4769
4770 This function parses the send action frame data passed in the format
4771 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4772
Srinivas Girigowda56076852013-08-20 14:00:50 -07004773 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004774 \param - pTargetApBssid Pointer to target Ap bssid
4775 \param - pChannel Pointer to the Target AP channel
4776 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4777 \param - pBuf Pointer to data
4778 \param - pBufLen Pointer to data length
4779
4780 \return - 0 for success non-zero for failure
4781
4782 --------------------------------------------------------------------------*/
4783VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4784 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4785{
4786 tANI_U8 *inPtr = pValue;
4787 tANI_U8 *dataEnd;
4788 int tempInt;
4789 int j = 0;
4790 int i = 0;
4791 int v = 0;
4792 tANI_U8 tempBuf[32];
4793 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004794 /* 12 hexa decimal digits, 5 ':' and '\0' */
4795 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004796
4797 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4798 /*no argument after the command*/
4799 if (NULL == inPtr)
4800 {
4801 return -EINVAL;
4802 }
4803
4804 /*no space after the command*/
4805 else if (SPACE_ASCII_VALUE != *inPtr)
4806 {
4807 return -EINVAL;
4808 }
4809
4810 /*removing empty spaces*/
4811 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4812
4813 /*no argument followed by spaces*/
4814 if ('\0' == *inPtr)
4815 {
4816 return -EINVAL;
4817 }
4818
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004819 v = sscanf(inPtr, "%17s", macAddress);
4820 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004821 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4823 "Invalid MAC address or All hex inputs are not read (%d)", v);
4824 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004825 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004826
4827 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4828 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4829 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4830 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4831 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4832 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004833
4834 /* point to the next argument */
4835 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4836 /*no argument after the command*/
4837 if (NULL == inPtr) return -EINVAL;
4838
4839 /*removing empty spaces*/
4840 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4841
4842 /*no argument followed by spaces*/
4843 if ('\0' == *inPtr)
4844 {
4845 return -EINVAL;
4846 }
4847
4848 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004849 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004850 if (1 != v) return -EINVAL;
4851
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004852 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304853 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304854 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004855
4856 *pChannel = tempInt;
4857
4858 /* point to the next argument */
4859 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4860 /*no argument after the command*/
4861 if (NULL == inPtr) return -EINVAL;
4862 /*removing empty spaces*/
4863 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4864
4865 /*no argument followed by spaces*/
4866 if ('\0' == *inPtr)
4867 {
4868 return -EINVAL;
4869 }
4870
4871 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004872 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004873 if (1 != v) return -EINVAL;
4874
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004875 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004876 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004877
4878 *pDwellTime = tempInt;
4879
4880 /* point to the next argument */
4881 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4882 /*no argument after the command*/
4883 if (NULL == inPtr) return -EINVAL;
4884 /*removing empty spaces*/
4885 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4886
4887 /*no argument followed by spaces*/
4888 if ('\0' == *inPtr)
4889 {
4890 return -EINVAL;
4891 }
4892
4893 /* find the length of data */
4894 dataEnd = inPtr;
4895 while(('\0' != *dataEnd) )
4896 {
4897 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004898 }
Kiet Lambe150c22013-11-21 16:30:32 +05304899 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004900 if ( *pBufLen <= 0) return -EINVAL;
4901
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004902 /* Allocate the number of bytes based on the number of input characters
4903 whether it is even or odd.
4904 if the number of input characters are even, then we need N/2 byte.
4905 if the number of input characters are odd, then we need do (N+1)/2 to
4906 compensate rounding off.
4907 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4908 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4909 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004910 if (NULL == *pBuf)
4911 {
4912 hddLog(VOS_TRACE_LEVEL_FATAL,
4913 "%s: vos_mem_alloc failed ", __func__);
4914 return -EINVAL;
4915 }
4916
4917 /* the buffer received from the upper layer is character buffer,
4918 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4919 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4920 and f0 in 3rd location */
4921 for (i = 0, j = 0; j < *pBufLen; j += 2)
4922 {
Kiet Lambe150c22013-11-21 16:30:32 +05304923 if( j+1 == *pBufLen)
4924 {
4925 tempByte = hdd_parse_hex(inPtr[j]);
4926 }
4927 else
4928 {
4929 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4930 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004931 (*pBuf)[i++] = tempByte;
4932 }
4933 *pBufLen = i;
4934 return VOS_STATUS_SUCCESS;
4935}
4936
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004937/**---------------------------------------------------------------------------
4938
Srinivas Girigowdade697412013-02-14 16:31:48 -08004939 \brief hdd_parse_channellist() - HDD Parse channel list
4940
4941 This function parses the channel list passed in the format
4942 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004943 if the Number of channels (N) does not match with the actual number of channels passed
4944 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4945 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4946 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4947 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004948
4949 \param - pValue Pointer to input channel list
4950 \param - ChannelList Pointer to local output array to record channel list
4951 \param - pNumChannels Pointer to number of roam scan channels
4952
4953 \return - 0 for success non-zero for failure
4954
4955 --------------------------------------------------------------------------*/
4956VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4957{
4958 tANI_U8 *inPtr = pValue;
4959 int tempInt;
4960 int j = 0;
4961 int v = 0;
4962 char buf[32];
4963
4964 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4965 /*no argument after the command*/
4966 if (NULL == inPtr)
4967 {
4968 return -EINVAL;
4969 }
4970
4971 /*no space after the command*/
4972 else if (SPACE_ASCII_VALUE != *inPtr)
4973 {
4974 return -EINVAL;
4975 }
4976
4977 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004978 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004979
4980 /*no argument followed by spaces*/
4981 if ('\0' == *inPtr)
4982 {
4983 return -EINVAL;
4984 }
4985
4986 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004987 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004988 if (1 != v) return -EINVAL;
4989
Srinivas Girigowdade697412013-02-14 16:31:48 -08004990 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004991 if ((v < 0) ||
4992 (tempInt <= 0) ||
4993 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4994 {
4995 return -EINVAL;
4996 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004997
4998 *pNumChannels = tempInt;
4999
5000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5001 "Number of channels are: %d", *pNumChannels);
5002
5003 for (j = 0; j < (*pNumChannels); j++)
5004 {
5005 /*inPtr pointing to the beginning of first space after number of channels*/
5006 inPtr = strpbrk( inPtr, " " );
5007 /*no channel list after the number of channels argument*/
5008 if (NULL == inPtr)
5009 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005010 if (0 != j)
5011 {
5012 *pNumChannels = j;
5013 return VOS_STATUS_SUCCESS;
5014 }
5015 else
5016 {
5017 return -EINVAL;
5018 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005019 }
5020
5021 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005022 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005023
5024 /*no channel list after the number of channels argument and spaces*/
5025 if ( '\0' == *inPtr )
5026 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005027 if (0 != j)
5028 {
5029 *pNumChannels = j;
5030 return VOS_STATUS_SUCCESS;
5031 }
5032 else
5033 {
5034 return -EINVAL;
5035 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005036 }
5037
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005038 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005039 if (1 != v) return -EINVAL;
5040
Srinivas Girigowdade697412013-02-14 16:31:48 -08005041 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005042 if ((v < 0) ||
5043 (tempInt <= 0) ||
5044 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5045 {
5046 return -EINVAL;
5047 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005048 pChannelList[j] = tempInt;
5049
5050 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5051 "Channel %d added to preferred channel list",
5052 pChannelList[j] );
5053 }
5054
Srinivas Girigowdade697412013-02-14 16:31:48 -08005055 return VOS_STATUS_SUCCESS;
5056}
5057
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005058
5059/**---------------------------------------------------------------------------
5060
5061 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5062
5063 This function parses the reasoc command data passed in the format
5064 REASSOC<space><bssid><space><channel>
5065
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005066 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005067 \param - pTargetApBssid Pointer to target Ap bssid
5068 \param - pChannel Pointer to the Target AP channel
5069
5070 \return - 0 for success non-zero for failure
5071
5072 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005073VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5074 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005075{
5076 tANI_U8 *inPtr = pValue;
5077 int tempInt;
5078 int v = 0;
5079 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005080 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005081 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005082
5083 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5084 /*no argument after the command*/
5085 if (NULL == inPtr)
5086 {
5087 return -EINVAL;
5088 }
5089
5090 /*no space after the command*/
5091 else if (SPACE_ASCII_VALUE != *inPtr)
5092 {
5093 return -EINVAL;
5094 }
5095
5096 /*removing empty spaces*/
5097 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5098
5099 /*no argument followed by spaces*/
5100 if ('\0' == *inPtr)
5101 {
5102 return -EINVAL;
5103 }
5104
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005105 v = sscanf(inPtr, "%17s", macAddress);
5106 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005107 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5109 "Invalid MAC address or All hex inputs are not read (%d)", v);
5110 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005111 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005112
5113 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5114 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5115 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5116 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5117 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5118 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005119
5120 /* point to the next argument */
5121 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5122 /*no argument after the command*/
5123 if (NULL == inPtr) return -EINVAL;
5124
5125 /*removing empty spaces*/
5126 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5127
5128 /*no argument followed by spaces*/
5129 if ('\0' == *inPtr)
5130 {
5131 return -EINVAL;
5132 }
5133
5134 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005135 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005136 if (1 != v) return -EINVAL;
5137
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005138 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005139 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305140 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005141 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5142 {
5143 return -EINVAL;
5144 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005145
5146 *pChannel = tempInt;
5147 return VOS_STATUS_SUCCESS;
5148}
5149
5150#endif
5151
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005152#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005153/**---------------------------------------------------------------------------
5154
5155 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5156
5157 This function parses the SETCCKM IE command
5158 SETCCKMIE<space><ie data>
5159
5160 \param - pValue Pointer to input data
5161 \param - pCckmIe Pointer to output cckm Ie
5162 \param - pCckmIeLen Pointer to output cckm ie length
5163
5164 \return - 0 for success non-zero for failure
5165
5166 --------------------------------------------------------------------------*/
5167VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5168 tANI_U8 *pCckmIeLen)
5169{
5170 tANI_U8 *inPtr = pValue;
5171 tANI_U8 *dataEnd;
5172 int j = 0;
5173 int i = 0;
5174 tANI_U8 tempByte = 0;
5175
5176 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5177 /*no argument after the command*/
5178 if (NULL == inPtr)
5179 {
5180 return -EINVAL;
5181 }
5182
5183 /*no space after the command*/
5184 else if (SPACE_ASCII_VALUE != *inPtr)
5185 {
5186 return -EINVAL;
5187 }
5188
5189 /*removing empty spaces*/
5190 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5191
5192 /*no argument followed by spaces*/
5193 if ('\0' == *inPtr)
5194 {
5195 return -EINVAL;
5196 }
5197
5198 /* find the length of data */
5199 dataEnd = inPtr;
5200 while(('\0' != *dataEnd) )
5201 {
5202 dataEnd++;
5203 ++(*pCckmIeLen);
5204 }
5205 if ( *pCckmIeLen <= 0) return -EINVAL;
5206
5207 /* Allocate the number of bytes based on the number of input characters
5208 whether it is even or odd.
5209 if the number of input characters are even, then we need N/2 byte.
5210 if the number of input characters are odd, then we need do (N+1)/2 to
5211 compensate rounding off.
5212 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5213 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5214 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5215 if (NULL == *pCckmIe)
5216 {
5217 hddLog(VOS_TRACE_LEVEL_FATAL,
5218 "%s: vos_mem_alloc failed ", __func__);
5219 return -EINVAL;
5220 }
5221 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5222 /* the buffer received from the upper layer is character buffer,
5223 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5224 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5225 and f0 in 3rd location */
5226 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5227 {
5228 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5229 (*pCckmIe)[i++] = tempByte;
5230 }
5231 *pCckmIeLen = i;
5232
5233 return VOS_STATUS_SUCCESS;
5234}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005235#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005236
Jeff Johnson295189b2012-06-20 16:38:30 -07005237/**---------------------------------------------------------------------------
5238
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005239 \brief hdd_is_valid_mac_address() - Validate MAC address
5240
5241 This function validates whether the given MAC address is valid or not
5242 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5243 where X is the hexa decimal digit character and separated by ':'
5244 This algorithm works even if MAC address is not separated by ':'
5245
5246 This code checks given input string mac contains exactly 12 hexadecimal digits.
5247 and a separator colon : appears in the input string only after
5248 an even number of hex digits.
5249
5250 \param - pMacAddr pointer to the input MAC address
5251 \return - 1 for valid and 0 for invalid
5252
5253 --------------------------------------------------------------------------*/
5254
5255v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5256{
5257 int xdigit = 0;
5258 int separator = 0;
5259 while (*pMacAddr)
5260 {
5261 if (isxdigit(*pMacAddr))
5262 {
5263 xdigit++;
5264 }
5265 else if (':' == *pMacAddr)
5266 {
5267 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5268 break;
5269
5270 ++separator;
5271 }
5272 else
5273 {
5274 separator = -1;
5275 /* Invalid MAC found */
5276 return 0;
5277 }
5278 ++pMacAddr;
5279 }
5280 return (xdigit == 12 && (separator == 5 || separator == 0));
5281}
5282
5283/**---------------------------------------------------------------------------
5284
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305285 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005286
5287 \param - dev Pointer to net_device structure
5288
5289 \return - 0 for success non-zero for failure
5290
5291 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305292int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005293{
5294 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5295 hdd_context_t *pHddCtx;
5296 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5297 VOS_STATUS status;
5298 v_BOOL_t in_standby = TRUE;
5299
5300 if (NULL == pAdapter)
5301 {
5302 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305303 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005304 return -ENODEV;
5305 }
5306
5307 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305308 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5309 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005310 if (NULL == pHddCtx)
5311 {
5312 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005313 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005314 return -ENODEV;
5315 }
5316
5317 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5318 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5319 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005320 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5321 {
5322 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305323 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005324 in_standby = FALSE;
5325 break;
5326 }
5327 else
5328 {
5329 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5330 pAdapterNode = pNext;
5331 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005332 }
5333
5334 if (TRUE == in_standby)
5335 {
5336 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5337 {
5338 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5339 "wlan out of power save", __func__);
5340 return -EINVAL;
5341 }
5342 }
5343
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005344 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005345 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5346 {
5347 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005348 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005349 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305350 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005351 netif_tx_start_all_queues(dev);
5352 }
5353
5354 return 0;
5355}
5356
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305357/**---------------------------------------------------------------------------
5358
5359 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5360
5361 This is called in response to ifconfig up
5362
5363 \param - dev Pointer to net_device structure
5364
5365 \return - 0 for success non-zero for failure
5366
5367 --------------------------------------------------------------------------*/
5368int hdd_open(struct net_device *dev)
5369{
5370 int ret;
5371
5372 vos_ssr_protect(__func__);
5373 ret = __hdd_open(dev);
5374 vos_ssr_unprotect(__func__);
5375
5376 return ret;
5377}
5378
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305379int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005380{
5381 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5382
5383 if(pAdapter == NULL) {
5384 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005385 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005386 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005387 }
5388
5389 netif_start_queue(dev);
5390
5391 return 0;
5392}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305393
5394int hdd_mon_open (struct net_device *dev)
5395{
5396 int ret;
5397
5398 vos_ssr_protect(__func__);
5399 ret = __hdd_mon_open(dev);
5400 vos_ssr_unprotect(__func__);
5401
5402 return ret;
5403}
5404
Jeff Johnson295189b2012-06-20 16:38:30 -07005405/**---------------------------------------------------------------------------
5406
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305407 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005408
5409 \param - dev Pointer to net_device structure
5410
5411 \return - 0 for success non-zero for failure
5412
5413 --------------------------------------------------------------------------*/
5414
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305415int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005416{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305417 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005418 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5419 hdd_context_t *pHddCtx;
5420 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5421 VOS_STATUS status;
5422 v_BOOL_t enter_standby = TRUE;
5423
5424 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005425 if (NULL == pAdapter)
5426 {
5427 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305428 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005429 return -ENODEV;
5430 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305431 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305432 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305433
5434 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5435 ret = wlan_hdd_validate_context(pHddCtx);
5436 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005437 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5439 "%s: HDD context is not valid!", __func__);
5440 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005441 }
5442
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305443 /* Nothing to be done if the interface is not opened */
5444 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5445 {
5446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5447 "%s: NETDEV Interface is not OPENED", __func__);
5448 return -ENODEV;
5449 }
5450
5451 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005452 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005453 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305454
5455 /* Disable TX on the interface, after this hard_start_xmit() will not
5456 * be called on that interface
5457 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305458 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005459 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305460
5461 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005462 netif_carrier_off(pAdapter->dev);
5463
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305464 /* The interface is marked as down for outside world (aka kernel)
5465 * But the driver is pretty much alive inside. The driver needs to
5466 * tear down the existing connection on the netdev (session)
5467 * cleanup the data pipes and wait until the control plane is stabilized
5468 * for this interface. The call also needs to wait until the above
5469 * mentioned actions are completed before returning to the caller.
5470 * Notice that the hdd_stop_adapter is requested not to close the session
5471 * That is intentional to be able to scan if it is a STA/P2P interface
5472 */
5473 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305474#ifdef FEATURE_WLAN_TDLS
5475 mutex_lock(&pHddCtx->tdls_lock);
5476#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305477 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305478 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305479#ifdef FEATURE_WLAN_TDLS
5480 mutex_unlock(&pHddCtx->tdls_lock);
5481#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005482 /* SoftAP ifaces should never go in power save mode
5483 making sure same here. */
5484 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5485 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005486 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005487 )
5488 {
5489 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305490 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5491 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005492 EXIT();
5493 return 0;
5494 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305495 /* Find if any iface is up. If any iface is up then can't put device to
5496 * sleep/power save mode
5497 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005498 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5499 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5500 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005501 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5502 {
5503 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305504 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005505 enter_standby = FALSE;
5506 break;
5507 }
5508 else
5509 {
5510 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5511 pAdapterNode = pNext;
5512 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005513 }
5514
5515 if (TRUE == enter_standby)
5516 {
5517 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5518 "entering standby", __func__);
5519 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5520 {
5521 /*log and return success*/
5522 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5523 "wlan in power save", __func__);
5524 }
5525 }
5526
5527 EXIT();
5528 return 0;
5529}
5530
5531/**---------------------------------------------------------------------------
5532
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305533 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005534
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305535 This is called in response to ifconfig down
5536
5537 \param - dev Pointer to net_device structure
5538
5539 \return - 0 for success non-zero for failure
5540-----------------------------------------------------------------------------*/
5541int hdd_stop (struct net_device *dev)
5542{
5543 int ret;
5544
5545 vos_ssr_protect(__func__);
5546 ret = __hdd_stop(dev);
5547 vos_ssr_unprotect(__func__);
5548
5549 return ret;
5550}
5551
5552/**---------------------------------------------------------------------------
5553
5554 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005555
5556 \param - dev Pointer to net_device structure
5557
5558 \return - void
5559
5560 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305561static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005562{
5563 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305564 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005565 ENTER();
5566
5567 do
5568 {
5569 if (NULL == pAdapter)
5570 {
5571 hddLog(VOS_TRACE_LEVEL_FATAL,
5572 "%s: NULL pAdapter", __func__);
5573 break;
5574 }
5575
5576 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5577 {
5578 hddLog(VOS_TRACE_LEVEL_FATAL,
5579 "%s: Invalid magic", __func__);
5580 break;
5581 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305582 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5583 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005584 {
5585 hddLog(VOS_TRACE_LEVEL_FATAL,
5586 "%s: NULL pHddCtx", __func__);
5587 break;
5588 }
5589
5590 if (dev != pAdapter->dev)
5591 {
5592 hddLog(VOS_TRACE_LEVEL_FATAL,
5593 "%s: Invalid device reference", __func__);
5594 /* we haven't validated all cases so let this go for now */
5595 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305596#ifdef FEATURE_WLAN_TDLS
5597 mutex_lock(&pHddCtx->tdls_lock);
5598#endif
c_hpothu002231a2015-02-05 14:58:51 +05305599 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305600#ifdef FEATURE_WLAN_TDLS
5601 mutex_unlock(&pHddCtx->tdls_lock);
5602#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005603
5604 /* after uninit our adapter structure will no longer be valid */
5605 pAdapter->dev = NULL;
5606 pAdapter->magic = 0;
5607 } while (0);
5608
5609 EXIT();
5610}
5611
5612/**---------------------------------------------------------------------------
5613
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305614 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5615
5616 This is called during the netdev unregister to uninitialize all data
5617associated with the device
5618
5619 \param - dev Pointer to net_device structure
5620
5621 \return - void
5622
5623 --------------------------------------------------------------------------*/
5624static void hdd_uninit (struct net_device *dev)
5625{
5626 vos_ssr_protect(__func__);
5627 __hdd_uninit(dev);
5628 vos_ssr_unprotect(__func__);
5629}
5630
5631/**---------------------------------------------------------------------------
5632
Jeff Johnson295189b2012-06-20 16:38:30 -07005633 \brief hdd_release_firmware() -
5634
5635 This function calls the release firmware API to free the firmware buffer.
5636
5637 \param - pFileName Pointer to the File Name.
5638 pCtx - Pointer to the adapter .
5639
5640
5641 \return - 0 for success, non zero for failure
5642
5643 --------------------------------------------------------------------------*/
5644
5645VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5646{
5647 VOS_STATUS status = VOS_STATUS_SUCCESS;
5648 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5649 ENTER();
5650
5651
5652 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5653
5654 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5655
5656 if(pHddCtx->fw) {
5657 release_firmware(pHddCtx->fw);
5658 pHddCtx->fw = NULL;
5659 }
5660 else
5661 status = VOS_STATUS_E_FAILURE;
5662 }
5663 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5664 if(pHddCtx->nv) {
5665 release_firmware(pHddCtx->nv);
5666 pHddCtx->nv = NULL;
5667 }
5668 else
5669 status = VOS_STATUS_E_FAILURE;
5670
5671 }
5672
5673 EXIT();
5674 return status;
5675}
5676
5677/**---------------------------------------------------------------------------
5678
5679 \brief hdd_request_firmware() -
5680
5681 This function reads the firmware file using the request firmware
5682 API and returns the the firmware data and the firmware file size.
5683
5684 \param - pfileName - Pointer to the file name.
5685 - pCtx - Pointer to the adapter .
5686 - ppfw_data - Pointer to the pointer of the firmware data.
5687 - pSize - Pointer to the file size.
5688
5689 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5690
5691 --------------------------------------------------------------------------*/
5692
5693
5694VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5695{
5696 int status;
5697 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5698 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5699 ENTER();
5700
5701 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5702
5703 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5704
5705 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5706 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5707 __func__, pfileName);
5708 retval = VOS_STATUS_E_FAILURE;
5709 }
5710
5711 else {
5712 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5713 *pSize = pHddCtx->fw->size;
5714 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5715 __func__, *pSize);
5716 }
5717 }
5718 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5719
5720 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5721
5722 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5723 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5724 __func__, pfileName);
5725 retval = VOS_STATUS_E_FAILURE;
5726 }
5727
5728 else {
5729 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5730 *pSize = pHddCtx->nv->size;
5731 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5732 __func__, *pSize);
5733 }
5734 }
5735
5736 EXIT();
5737 return retval;
5738}
5739/**---------------------------------------------------------------------------
5740 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5741
5742 This is the function invoked by SME to inform the result of a full power
5743 request issued by HDD
5744
5745 \param - callbackcontext - Pointer to cookie
5746 status - result of request
5747
5748 \return - None
5749
5750--------------------------------------------------------------------------*/
5751void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5752{
5753 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5754
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005755 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005756 if(&pHddCtx->full_pwr_comp_var)
5757 {
5758 complete(&pHddCtx->full_pwr_comp_var);
5759 }
5760}
5761
5762/**---------------------------------------------------------------------------
5763
5764 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5765
5766 This is the function invoked by SME to inform the result of BMPS
5767 request issued by HDD
5768
5769 \param - callbackcontext - Pointer to cookie
5770 status - result of request
5771
5772 \return - None
5773
5774--------------------------------------------------------------------------*/
5775void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5776{
5777
5778 struct completion *completion_var = (struct completion*) callbackContext;
5779
Arif Hussain6d2a3322013-11-17 19:50:10 -08005780 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005781 if(completion_var != NULL)
5782 {
5783 complete(completion_var);
5784 }
5785}
5786
5787/**---------------------------------------------------------------------------
5788
5789 \brief hdd_get_cfg_file_size() -
5790
5791 This function reads the configuration file using the request firmware
5792 API and returns the configuration file size.
5793
5794 \param - pCtx - Pointer to the adapter .
5795 - pFileName - Pointer to the file name.
5796 - pBufSize - Pointer to the buffer size.
5797
5798 \return - 0 for success, non zero for failure
5799
5800 --------------------------------------------------------------------------*/
5801
5802VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5803{
5804 int status;
5805 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5806
5807 ENTER();
5808
5809 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5810
5811 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5812 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5813 status = VOS_STATUS_E_FAILURE;
5814 }
5815 else {
5816 *pBufSize = pHddCtx->fw->size;
5817 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5818 release_firmware(pHddCtx->fw);
5819 pHddCtx->fw = NULL;
5820 }
5821
5822 EXIT();
5823 return VOS_STATUS_SUCCESS;
5824}
5825
5826/**---------------------------------------------------------------------------
5827
5828 \brief hdd_read_cfg_file() -
5829
5830 This function reads the configuration file using the request firmware
5831 API and returns the cfg data and the buffer size of the configuration file.
5832
5833 \param - pCtx - Pointer to the adapter .
5834 - pFileName - Pointer to the file name.
5835 - pBuffer - Pointer to the data buffer.
5836 - pBufSize - Pointer to the buffer size.
5837
5838 \return - 0 for success, non zero for failure
5839
5840 --------------------------------------------------------------------------*/
5841
5842VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5843 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5844{
5845 int status;
5846 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5847
5848 ENTER();
5849
5850 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5851
5852 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5853 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5854 return VOS_STATUS_E_FAILURE;
5855 }
5856 else {
5857 if(*pBufSize != pHddCtx->fw->size) {
5858 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5859 "file size", __func__);
5860 release_firmware(pHddCtx->fw);
5861 pHddCtx->fw = NULL;
5862 return VOS_STATUS_E_FAILURE;
5863 }
5864 else {
5865 if(pBuffer) {
5866 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5867 }
5868 release_firmware(pHddCtx->fw);
5869 pHddCtx->fw = NULL;
5870 }
5871 }
5872
5873 EXIT();
5874
5875 return VOS_STATUS_SUCCESS;
5876}
5877
5878/**---------------------------------------------------------------------------
5879
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305880 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07005881
5882 This function sets the user specified mac address using
5883 the command ifconfig wlanX hw ether <mac adress>.
5884
5885 \param - dev - Pointer to the net device.
5886 - addr - Pointer to the sockaddr.
5887 \return - 0 for success, non zero for failure
5888
5889 --------------------------------------------------------------------------*/
5890
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305891static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07005892{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305893 hdd_adapter_t *pAdapter;
5894 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005895 struct sockaddr *psta_mac_addr = addr;
5896 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305897 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005898
5899 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305900 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5901 if (NULL == pAdapter)
5902 {
5903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5904 "%s: Adapter is NULL",__func__);
5905 return -EINVAL;
5906 }
5907 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5908 ret = wlan_hdd_validate_context(pHddCtx);
5909 if (0 != ret)
5910 {
5911 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5912 "%s: HDD context is not valid",__func__);
5913 return ret;
5914 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005915
5916 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07005917 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5918
5919 EXIT();
5920 return halStatus;
5921}
5922
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305923/**---------------------------------------------------------------------------
5924
5925 \brief hdd_set_mac_address() -
5926
5927 Wrapper function to protect __hdd_set_mac_address() function from ssr
5928
5929 \param - dev - Pointer to the net device.
5930 - addr - Pointer to the sockaddr.
5931 \return - 0 for success, non zero for failure
5932
5933 --------------------------------------------------------------------------*/
5934static int hdd_set_mac_address(struct net_device *dev, void *addr)
5935{
5936 int ret;
5937
5938 vos_ssr_protect(__func__);
5939 ret = __hdd_set_mac_address(dev, addr);
5940 vos_ssr_unprotect(__func__);
5941
5942 return ret;
5943}
5944
Jeff Johnson295189b2012-06-20 16:38:30 -07005945tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5946{
5947 int i;
5948 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5949 {
Abhishek Singheb183782014-02-06 13:37:21 +05305950 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005951 break;
5952 }
5953
5954 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5955 return NULL;
5956
5957 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5958 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5959}
5960
5961void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5962{
5963 int i;
5964 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5965 {
5966 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5967 {
5968 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5969 break;
5970 }
5971 }
5972 return;
5973}
5974
5975#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5976 static struct net_device_ops wlan_drv_ops = {
5977 .ndo_open = hdd_open,
5978 .ndo_stop = hdd_stop,
5979 .ndo_uninit = hdd_uninit,
5980 .ndo_start_xmit = hdd_hard_start_xmit,
5981 .ndo_tx_timeout = hdd_tx_timeout,
5982 .ndo_get_stats = hdd_stats,
5983 .ndo_do_ioctl = hdd_ioctl,
5984 .ndo_set_mac_address = hdd_set_mac_address,
5985 .ndo_select_queue = hdd_select_queue,
5986#ifdef WLAN_FEATURE_PACKET_FILTERING
5987#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5988 .ndo_set_rx_mode = hdd_set_multicast_list,
5989#else
5990 .ndo_set_multicast_list = hdd_set_multicast_list,
5991#endif //LINUX_VERSION_CODE
5992#endif
5993 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005994 static struct net_device_ops wlan_mon_drv_ops = {
5995 .ndo_open = hdd_mon_open,
5996 .ndo_stop = hdd_stop,
5997 .ndo_uninit = hdd_uninit,
5998 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5999 .ndo_tx_timeout = hdd_tx_timeout,
6000 .ndo_get_stats = hdd_stats,
6001 .ndo_do_ioctl = hdd_ioctl,
6002 .ndo_set_mac_address = hdd_set_mac_address,
6003 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306004
Jeff Johnson295189b2012-06-20 16:38:30 -07006005#endif
6006
6007void hdd_set_station_ops( struct net_device *pWlanDev )
6008{
6009#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006010 pWlanDev->netdev_ops = &wlan_drv_ops;
6011#else
6012 pWlanDev->open = hdd_open;
6013 pWlanDev->stop = hdd_stop;
6014 pWlanDev->uninit = hdd_uninit;
6015 pWlanDev->hard_start_xmit = NULL;
6016 pWlanDev->tx_timeout = hdd_tx_timeout;
6017 pWlanDev->get_stats = hdd_stats;
6018 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006019 pWlanDev->set_mac_address = hdd_set_mac_address;
6020#endif
6021}
6022
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006023static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006024{
6025 struct net_device *pWlanDev = NULL;
6026 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006027 /*
6028 * cfg80211 initialization and registration....
6029 */
6030 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
6031
Jeff Johnson295189b2012-06-20 16:38:30 -07006032 if(pWlanDev != NULL)
6033 {
6034
6035 //Save the pointer to the net_device in the HDD adapter
6036 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6037
Jeff Johnson295189b2012-06-20 16:38:30 -07006038 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6039
6040 pAdapter->dev = pWlanDev;
6041 pAdapter->pHddCtx = pHddCtx;
6042 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306043 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006044
6045 init_completion(&pAdapter->session_open_comp_var);
6046 init_completion(&pAdapter->session_close_comp_var);
6047 init_completion(&pAdapter->disconnect_comp_var);
6048 init_completion(&pAdapter->linkup_event_var);
6049 init_completion(&pAdapter->cancel_rem_on_chan_var);
6050 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306051 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006052#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6053 init_completion(&pAdapter->offchannel_tx_event);
6054#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006055 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006056#ifdef FEATURE_WLAN_TDLS
6057 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006058 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006059 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306060 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006061#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006062 init_completion(&pHddCtx->mc_sus_event_var);
6063 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306064 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006065 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006066 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006067
Rajeev79dbe4c2013-10-05 11:03:42 +05306068#ifdef FEATURE_WLAN_BATCH_SCAN
6069 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6070 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6071 pAdapter->pBatchScanRsp = NULL;
6072 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006073 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006074 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306075 mutex_init(&pAdapter->hdd_batch_scan_lock);
6076#endif
6077
Jeff Johnson295189b2012-06-20 16:38:30 -07006078 pAdapter->isLinkUpSvcNeeded = FALSE;
6079 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6080 //Init the net_device structure
6081 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6082
6083 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6084 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6085 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6086 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6087
6088 hdd_set_station_ops( pAdapter->dev );
6089
6090 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006091 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6092 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6093 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006094 /* set pWlanDev's parent to underlying device */
6095 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006096
6097 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006098 }
6099
6100 return pAdapter;
6101}
6102
6103VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6104{
6105 struct net_device *pWlanDev = pAdapter->dev;
6106 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6107 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6108 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6109
6110 if( rtnl_lock_held )
6111 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006112 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006113 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6114 {
6115 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6116 return VOS_STATUS_E_FAILURE;
6117 }
6118 }
6119 if (register_netdevice(pWlanDev))
6120 {
6121 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6122 return VOS_STATUS_E_FAILURE;
6123 }
6124 }
6125 else
6126 {
6127 if(register_netdev(pWlanDev))
6128 {
6129 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6130 return VOS_STATUS_E_FAILURE;
6131 }
6132 }
6133 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6134
6135 return VOS_STATUS_SUCCESS;
6136}
6137
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006138static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006139{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006140 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006141
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006142 if (NULL == pAdapter)
6143 {
6144 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6145 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006146 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006147
6148 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6149 {
6150 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6151 return eHAL_STATUS_NOT_INITIALIZED;
6152 }
6153
6154 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6155
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006156#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006157 /* need to make sure all of our scheduled work has completed.
6158 * This callback is called from MC thread context, so it is safe to
6159 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006160 *
6161 * Even though this is called from MC thread context, if there is a faulty
6162 * work item in the system, that can hang this call forever. So flushing
6163 * this global work queue is not safe; and now we make sure that
6164 * individual work queues are stopped correctly. But the cancel work queue
6165 * is a GPL only API, so the proprietary version of the driver would still
6166 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006167 */
6168 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006169#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006170
6171 /* We can be blocked while waiting for scheduled work to be
6172 * flushed, and the adapter structure can potentially be freed, in
6173 * which case the magic will have been reset. So make sure the
6174 * magic is still good, and hence the adapter structure is still
6175 * valid, before signaling completion */
6176 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6177 {
6178 complete(&pAdapter->session_close_comp_var);
6179 }
6180
Jeff Johnson295189b2012-06-20 16:38:30 -07006181 return eHAL_STATUS_SUCCESS;
6182}
6183
6184VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6185{
6186 struct net_device *pWlanDev = pAdapter->dev;
6187 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6188 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6189 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6190 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306191 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006192
6193 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006194 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006195 //Open a SME session for future operation
6196 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006197 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006198 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6199 {
6200 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006201 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006202 halStatus, halStatus );
6203 status = VOS_STATUS_E_FAILURE;
6204 goto error_sme_open;
6205 }
6206
6207 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306208 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006209 &pAdapter->session_open_comp_var,
6210 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306211 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006212 {
6213 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306214 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006215 status = VOS_STATUS_E_FAILURE;
6216 goto error_sme_open;
6217 }
6218
6219 // Register wireless extensions
6220 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6221 {
6222 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006223 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006224 halStatus, halStatus );
6225 status = VOS_STATUS_E_FAILURE;
6226 goto error_register_wext;
6227 }
6228 //Safe to register the hard_start_xmit function again
6229#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6230 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6231#else
6232 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6233#endif
6234
6235 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306236 hddLog(VOS_TRACE_LEVEL_INFO,
6237 "%s: Set HDD connState to eConnectionState_NotConnected",
6238 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006239 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6240
6241 //Set the default operation channel
6242 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6243
6244 /* Make the default Auth Type as OPEN*/
6245 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6246
6247 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6248 {
6249 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006250 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006251 status, status );
6252 goto error_init_txrx;
6253 }
6254
6255 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6256
6257 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6258 {
6259 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006260 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006261 status, status );
6262 goto error_wmm_init;
6263 }
6264
6265 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6266
6267 return VOS_STATUS_SUCCESS;
6268
6269error_wmm_init:
6270 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6271 hdd_deinit_tx_rx(pAdapter);
6272error_init_txrx:
6273 hdd_UnregisterWext(pWlanDev);
6274error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006275 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006276 {
6277 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006278 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006279 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006280 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006281 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306282 unsigned long rc;
6283
Jeff Johnson295189b2012-06-20 16:38:30 -07006284 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306285 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006286 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006287 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306288 if (rc <= 0)
6289 hddLog(VOS_TRACE_LEVEL_ERROR,
6290 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006291 }
6292}
6293error_sme_open:
6294 return status;
6295}
6296
Jeff Johnson295189b2012-06-20 16:38:30 -07006297void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6298{
6299 hdd_cfg80211_state_t *cfgState;
6300
6301 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6302
6303 if( NULL != cfgState->buf )
6304 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306305 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006306 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6307 rc = wait_for_completion_interruptible_timeout(
6308 &pAdapter->tx_action_cnf_event,
6309 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306310 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006311 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306313 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6314 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006315 }
6316 }
6317 return;
6318}
Jeff Johnson295189b2012-06-20 16:38:30 -07006319
c_hpothu002231a2015-02-05 14:58:51 +05306320void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006321{
6322 ENTER();
6323 switch ( pAdapter->device_mode )
6324 {
6325 case WLAN_HDD_INFRA_STATION:
6326 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006327 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006328 {
6329 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6330 {
6331 hdd_deinit_tx_rx( pAdapter );
6332 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6333 }
6334
6335 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6336 {
6337 hdd_wmm_adapter_close( pAdapter );
6338 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6339 }
6340
Jeff Johnson295189b2012-06-20 16:38:30 -07006341 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006342 break;
6343 }
6344
6345 case WLAN_HDD_SOFTAP:
6346 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006347 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306348
6349 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6350 {
6351 hdd_wmm_adapter_close( pAdapter );
6352 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6353 }
6354
Jeff Johnson295189b2012-06-20 16:38:30 -07006355 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006356
c_hpothu002231a2015-02-05 14:58:51 +05306357 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006358 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006359 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07006360 break;
6361 }
6362
6363 case WLAN_HDD_MONITOR:
6364 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006365 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006366 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6367 {
6368 hdd_deinit_tx_rx( pAdapter );
6369 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6370 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006371 if(NULL != pAdapterforTx)
6372 {
6373 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
6374 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006375 break;
6376 }
6377
6378
6379 default:
6380 break;
6381 }
6382
6383 EXIT();
6384}
6385
6386void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6387{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006388 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306389
6390 ENTER();
6391 if (NULL == pAdapter)
6392 {
6393 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6394 "%s: HDD adapter is Null", __func__);
6395 return;
6396 }
6397
6398 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006399
Rajeev79dbe4c2013-10-05 11:03:42 +05306400#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306401 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6402 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006403 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306404 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6405 )
6406 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006407 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306408 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006409 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6410 {
6411 hdd_deinit_batch_scan(pAdapter);
6412 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306413 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006414 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306415#endif
6416
Jeff Johnson295189b2012-06-20 16:38:30 -07006417 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6418 if( rtnl_held )
6419 {
6420 unregister_netdevice(pWlanDev);
6421 }
6422 else
6423 {
6424 unregister_netdev(pWlanDev);
6425 }
6426 // note that the pAdapter is no longer valid at this point
6427 // since the memory has been reclaimed
6428 }
6429
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306430 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006431}
6432
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006433void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6434{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306435 VOS_STATUS status;
6436 hdd_adapter_t *pAdapter = NULL;
6437 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006438
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306439 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006440
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306441 /*loop through all adapters.*/
6442 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006443 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306444 pAdapter = pAdapterNode->pAdapter;
6445 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6446 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006447
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306448 { // we skip this registration for modes other than STA and P2P client modes.
6449 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6450 pAdapterNode = pNext;
6451 continue;
6452 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006453
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306454 //Apply Dynamic DTIM For P2P
6455 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6456 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6457 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6458 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6459 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6460 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6461 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6462 (eConnectionState_Associated ==
6463 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6464 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6465 {
6466 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006467
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306468 powerRequest.uIgnoreDTIM = 1;
6469 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6470
6471 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6472 {
6473 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6474 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6475 }
6476 else
6477 {
6478 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6479 }
6480
6481 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6482 * specified during Enter/Exit BMPS when LCD off*/
6483 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6484 NULL, eANI_BOOLEAN_FALSE);
6485 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6486 NULL, eANI_BOOLEAN_FALSE);
6487
6488 /* switch to the DTIM specified in cfg.ini */
6489 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6490 "Switch to DTIM %d", powerRequest.uListenInterval);
6491 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6492 break;
6493
6494 }
6495
6496 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6497 pAdapterNode = pNext;
6498 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006499}
6500
6501void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6502{
6503 /*Switch back to DTIM 1*/
6504 tSirSetPowerParamsReq powerRequest = { 0 };
6505
6506 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6507 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006508 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006509
6510 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6511 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6512 NULL, eANI_BOOLEAN_FALSE);
6513 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6514 NULL, eANI_BOOLEAN_FALSE);
6515
6516 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6517 "Switch to DTIM%d",powerRequest.uListenInterval);
6518 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6519
6520}
6521
Jeff Johnson295189b2012-06-20 16:38:30 -07006522VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6523{
6524 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306525 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6526 {
6527 hddLog( LOGE, FL("Wlan Unload in progress"));
6528 return VOS_STATUS_E_PERM;
6529 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006530 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6531 {
6532 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6533 }
6534
6535 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6536 {
6537 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6538 }
6539
6540 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6541 {
6542 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6543 }
6544
6545 return status;
6546}
6547
6548VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6549{
6550 hdd_adapter_t *pAdapter = NULL;
6551 eHalStatus halStatus;
6552 VOS_STATUS status = VOS_STATUS_E_INVAL;
6553 v_BOOL_t disableBmps = FALSE;
6554 v_BOOL_t disableImps = FALSE;
6555
6556 switch(session_type)
6557 {
6558 case WLAN_HDD_INFRA_STATION:
6559 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006560 case WLAN_HDD_P2P_CLIENT:
6561 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006562 //Exit BMPS -> Is Sta/P2P Client is already connected
6563 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6564 if((NULL != pAdapter)&&
6565 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6566 {
6567 disableBmps = TRUE;
6568 }
6569
6570 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6571 if((NULL != pAdapter)&&
6572 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6573 {
6574 disableBmps = TRUE;
6575 }
6576
6577 //Exit both Bmps and Imps incase of Go/SAP Mode
6578 if((WLAN_HDD_SOFTAP == session_type) ||
6579 (WLAN_HDD_P2P_GO == session_type))
6580 {
6581 disableBmps = TRUE;
6582 disableImps = TRUE;
6583 }
6584
6585 if(TRUE == disableImps)
6586 {
6587 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6588 {
6589 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6590 }
6591 }
6592
6593 if(TRUE == disableBmps)
6594 {
6595 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6596 {
6597 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6598
6599 if(eHAL_STATUS_SUCCESS != halStatus)
6600 {
6601 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006602 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006603 VOS_ASSERT(0);
6604 return status;
6605 }
6606 }
6607
6608 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6609 {
6610 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6611
6612 if(eHAL_STATUS_SUCCESS != halStatus)
6613 {
6614 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006615 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006616 VOS_ASSERT(0);
6617 return status;
6618 }
6619 }
6620 }
6621
6622 if((TRUE == disableBmps) ||
6623 (TRUE == disableImps))
6624 {
6625 /* Now, get the chip into Full Power now */
6626 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6627 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6628 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6629
6630 if(halStatus != eHAL_STATUS_SUCCESS)
6631 {
6632 if(halStatus == eHAL_STATUS_PMC_PENDING)
6633 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306634 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006635 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306636 ret = wait_for_completion_interruptible_timeout(
6637 &pHddCtx->full_pwr_comp_var,
6638 msecs_to_jiffies(1000));
6639 if (ret <= 0)
6640 {
6641 hddLog(VOS_TRACE_LEVEL_ERROR,
6642 "%s: wait on full_pwr_comp_var failed %ld",
6643 __func__, ret);
6644 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006645 }
6646 else
6647 {
6648 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006649 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006650 VOS_ASSERT(0);
6651 return status;
6652 }
6653 }
6654
6655 status = VOS_STATUS_SUCCESS;
6656 }
6657
6658 break;
6659 }
6660 return status;
6661}
6662
6663hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006664 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006665 tANI_U8 rtnl_held )
6666{
6667 hdd_adapter_t *pAdapter = NULL;
6668 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6669 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6670 VOS_STATUS exitbmpsStatus;
6671
Arif Hussain6d2a3322013-11-17 19:50:10 -08006672 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006673
Nirav Shah436658f2014-02-28 17:05:45 +05306674 if(macAddr == NULL)
6675 {
6676 /* Not received valid macAddr */
6677 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6678 "%s:Unable to add virtual intf: Not able to get"
6679 "valid mac address",__func__);
6680 return NULL;
6681 }
6682
Jeff Johnson295189b2012-06-20 16:38:30 -07006683 //Disable BMPS incase of Concurrency
6684 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6685
6686 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6687 {
6688 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306689 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006690 VOS_ASSERT(0);
6691 return NULL;
6692 }
6693
6694 switch(session_type)
6695 {
6696 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006697 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006698 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006699 {
6700 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6701
6702 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306703 {
6704 hddLog(VOS_TRACE_LEVEL_FATAL,
6705 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006706 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306707 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006708
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306709#ifdef FEATURE_WLAN_TDLS
6710 /* A Mutex Lock is introduced while changing/initializing the mode to
6711 * protect the concurrent access for the Adapters by TDLS module.
6712 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306713 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306714#endif
6715
Jeff Johnsone7245742012-09-05 17:12:55 -07006716 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6717 NL80211_IFTYPE_P2P_CLIENT:
6718 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006719
Jeff Johnson295189b2012-06-20 16:38:30 -07006720 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306721#ifdef FEATURE_WLAN_TDLS
6722 mutex_unlock(&pHddCtx->tdls_lock);
6723#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306724
6725 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006726 if( VOS_STATUS_SUCCESS != status )
6727 goto err_free_netdev;
6728
6729 status = hdd_register_interface( pAdapter, rtnl_held );
6730 if( VOS_STATUS_SUCCESS != status )
6731 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306732#ifdef FEATURE_WLAN_TDLS
6733 mutex_lock(&pHddCtx->tdls_lock);
6734#endif
c_hpothu002231a2015-02-05 14:58:51 +05306735 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306736#ifdef FEATURE_WLAN_TDLS
6737 mutex_unlock(&pHddCtx->tdls_lock);
6738#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006739 goto err_free_netdev;
6740 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306741
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306742 // Workqueue which gets scheduled in IPv4 notification callback.
6743 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6744
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306745#ifdef WLAN_NS_OFFLOAD
6746 // Workqueue which gets scheduled in IPv6 notification callback.
6747 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6748#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006749 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306750 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006751 netif_tx_disable(pAdapter->dev);
6752 //netif_tx_disable(pWlanDev);
6753 netif_carrier_off(pAdapter->dev);
6754
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306755 if (WLAN_HDD_P2P_CLIENT == session_type ||
6756 WLAN_HDD_P2P_DEVICE == session_type)
6757 {
6758 /* Initialize the work queue to defer the
6759 * back to back RoC request */
6760 INIT_DELAYED_WORK(&pAdapter->roc_work,
6761 hdd_p2p_roc_work_queue);
6762 }
6763
Jeff Johnson295189b2012-06-20 16:38:30 -07006764 break;
6765 }
6766
Jeff Johnson295189b2012-06-20 16:38:30 -07006767 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006768 case WLAN_HDD_SOFTAP:
6769 {
6770 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6771 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306772 {
6773 hddLog(VOS_TRACE_LEVEL_FATAL,
6774 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006775 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306776 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006777
Jeff Johnson295189b2012-06-20 16:38:30 -07006778 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6779 NL80211_IFTYPE_AP:
6780 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006781 pAdapter->device_mode = session_type;
6782
6783 status = hdd_init_ap_mode(pAdapter);
6784 if( VOS_STATUS_SUCCESS != status )
6785 goto err_free_netdev;
6786
6787 status = hdd_register_hostapd( pAdapter, rtnl_held );
6788 if( VOS_STATUS_SUCCESS != status )
6789 {
c_hpothu002231a2015-02-05 14:58:51 +05306790 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006791 goto err_free_netdev;
6792 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306793 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006794 netif_tx_disable(pAdapter->dev);
6795 netif_carrier_off(pAdapter->dev);
6796
6797 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306798
6799 if (WLAN_HDD_P2P_GO == session_type)
6800 {
6801 /* Initialize the work queue to
6802 * defer the back to back RoC request */
6803 INIT_DELAYED_WORK(&pAdapter->roc_work,
6804 hdd_p2p_roc_work_queue);
6805 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006806 break;
6807 }
6808 case WLAN_HDD_MONITOR:
6809 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006810 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6811 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306812 {
6813 hddLog(VOS_TRACE_LEVEL_FATAL,
6814 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006815 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306816 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006817
6818 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6819 pAdapter->device_mode = session_type;
6820 status = hdd_register_interface( pAdapter, rtnl_held );
6821#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6822 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6823#else
6824 pAdapter->dev->open = hdd_mon_open;
6825 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6826#endif
6827 hdd_init_tx_rx( pAdapter );
6828 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6829 //Set adapter to be used for data tx. It will use either GO or softap.
6830 pAdapter->sessionCtx.monitor.pAdapterForTx =
6831 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006832 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6833 {
6834 pAdapter->sessionCtx.monitor.pAdapterForTx =
6835 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6836 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006837 /* This workqueue will be used to transmit management packet over
6838 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006839 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6840 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6841 return NULL;
6842 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006843
Jeff Johnson295189b2012-06-20 16:38:30 -07006844 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6845 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006846 }
6847 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006848 case WLAN_HDD_FTM:
6849 {
6850 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6851
6852 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306853 {
6854 hddLog(VOS_TRACE_LEVEL_FATAL,
6855 FL("failed to allocate adapter for session %d"), session_type);
6856 return NULL;
6857 }
6858
Jeff Johnson295189b2012-06-20 16:38:30 -07006859 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6860 * message while loading driver in FTM mode. */
6861 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6862 pAdapter->device_mode = session_type;
6863 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306864
6865 hdd_init_tx_rx( pAdapter );
6866
6867 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306868 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306869 netif_tx_disable(pAdapter->dev);
6870 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006871 }
6872 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006873 default:
6874 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306875 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6876 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006877 VOS_ASSERT(0);
6878 return NULL;
6879 }
6880 }
6881
Jeff Johnson295189b2012-06-20 16:38:30 -07006882 if( VOS_STATUS_SUCCESS == status )
6883 {
6884 //Add it to the hdd's session list.
6885 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6886 if( NULL == pHddAdapterNode )
6887 {
6888 status = VOS_STATUS_E_NOMEM;
6889 }
6890 else
6891 {
6892 pHddAdapterNode->pAdapter = pAdapter;
6893 status = hdd_add_adapter_back ( pHddCtx,
6894 pHddAdapterNode );
6895 }
6896 }
6897
6898 if( VOS_STATUS_SUCCESS != status )
6899 {
6900 if( NULL != pAdapter )
6901 {
6902 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6903 pAdapter = NULL;
6904 }
6905 if( NULL != pHddAdapterNode )
6906 {
6907 vos_mem_free( pHddAdapterNode );
6908 }
6909
6910 goto resume_bmps;
6911 }
6912
6913 if(VOS_STATUS_SUCCESS == status)
6914 {
6915 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6916
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006917 //Initialize the WoWL service
6918 if(!hdd_init_wowl(pAdapter))
6919 {
6920 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6921 goto err_free_netdev;
6922 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006923 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006924 return pAdapter;
6925
6926err_free_netdev:
6927 free_netdev(pAdapter->dev);
6928 wlan_hdd_release_intf_addr( pHddCtx,
6929 pAdapter->macAddressCurrent.bytes );
6930
6931resume_bmps:
6932 //If bmps disabled enable it
6933 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6934 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306935 if (pHddCtx->hdd_wlan_suspended)
6936 {
6937 hdd_set_pwrparams(pHddCtx);
6938 }
6939 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006940 }
6941 return NULL;
6942}
6943
6944VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6945 tANI_U8 rtnl_held )
6946{
6947 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6948 VOS_STATUS status;
6949
6950 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6951 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306952 {
6953 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6954 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006955 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306956 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006957
6958 while ( pCurrent->pAdapter != pAdapter )
6959 {
6960 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6961 if( VOS_STATUS_SUCCESS != status )
6962 break;
6963
6964 pCurrent = pNext;
6965 }
6966 pAdapterNode = pCurrent;
6967 if( VOS_STATUS_SUCCESS == status )
6968 {
6969 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6970 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306971
6972#ifdef FEATURE_WLAN_TDLS
6973
6974 /* A Mutex Lock is introduced while changing/initializing the mode to
6975 * protect the concurrent access for the Adapters by TDLS module.
6976 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306977 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306978#endif
6979
Jeff Johnson295189b2012-06-20 16:38:30 -07006980 hdd_remove_adapter( pHddCtx, pAdapterNode );
6981 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006982 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006983
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306984#ifdef FEATURE_WLAN_TDLS
6985 mutex_unlock(&pHddCtx->tdls_lock);
6986#endif
6987
Jeff Johnson295189b2012-06-20 16:38:30 -07006988
6989 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05306990 if ((!vos_concurrent_open_sessions_running()) &&
6991 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
6992 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006993 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306994 if (pHddCtx->hdd_wlan_suspended)
6995 {
6996 hdd_set_pwrparams(pHddCtx);
6997 }
6998 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006999 }
7000
7001 return VOS_STATUS_SUCCESS;
7002 }
7003
7004 return VOS_STATUS_E_FAILURE;
7005}
7006
7007VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7008{
7009 hdd_adapter_list_node_t *pHddAdapterNode;
7010 VOS_STATUS status;
7011
7012 ENTER();
7013
7014 do
7015 {
7016 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7017 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7018 {
7019 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7020 vos_mem_free( pHddAdapterNode );
7021 }
7022 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7023
7024 EXIT();
7025
7026 return VOS_STATUS_SUCCESS;
7027}
7028
7029void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7030{
7031 v_U8_t addIE[1] = {0};
7032
7033 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7034 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7035 eANI_BOOLEAN_FALSE) )
7036 {
7037 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007038 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007039 }
7040
7041 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7042 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7043 eANI_BOOLEAN_FALSE) )
7044 {
7045 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007046 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007047 }
7048
7049 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7050 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7051 eANI_BOOLEAN_FALSE) )
7052 {
7053 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007054 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007055 }
7056}
7057
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307058VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7059 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007060{
7061 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7062 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307063 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007064 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307065 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307066 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007067
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307068 if (pHddCtx->isLogpInProgress) {
7069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7070 "%s:LOGP in Progress. Ignore!!!",__func__);
7071 return VOS_STATUS_E_FAILURE;
7072 }
7073
Jeff Johnson295189b2012-06-20 16:38:30 -07007074 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307075
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307076 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007077 switch(pAdapter->device_mode)
7078 {
7079 case WLAN_HDD_INFRA_STATION:
7080 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007081 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307082 {
7083 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7084 if( hdd_connIsConnected(pstation) ||
7085 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007086 {
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307087#ifdef FEATURE_WLAN_TDLS
7088 mutex_lock(&pHddCtx->tdls_lock);
7089 wlan_hdd_tdls_exit(pAdapter);
7090 mutex_unlock(&pHddCtx->tdls_lock);
7091#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007092 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7093 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7094 pAdapter->sessionId,
7095 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7096 else
7097 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7098 pAdapter->sessionId,
7099 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7100 //success implies disconnect command got queued up successfully
7101 if(halStatus == eHAL_STATUS_SUCCESS)
7102 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307103 ret = wait_for_completion_interruptible_timeout(
7104 &pAdapter->disconnect_comp_var,
7105 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7106 if (ret <= 0)
7107 {
7108 hddLog(VOS_TRACE_LEVEL_ERROR,
7109 "%s: wait on disconnect_comp_var failed %ld",
7110 __func__, ret);
7111 }
7112 }
7113 else
7114 {
7115 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7116 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007117 }
7118 memset(&wrqu, '\0', sizeof(wrqu));
7119 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7120 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7121 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7122 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307123 else if(pstation->conn_info.connState ==
7124 eConnectionState_Disconnecting)
7125 {
7126 ret = wait_for_completion_interruptible_timeout(
7127 &pAdapter->disconnect_comp_var,
7128 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7129 if (ret <= 0)
7130 {
7131 hddLog(VOS_TRACE_LEVEL_ERROR,
7132 FL("wait on disconnect_comp_var failed %ld"), ret);
7133 }
7134 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307135 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007136 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307137 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307138 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007139 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307140 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7141 {
7142 while (pAdapter->is_roc_inprogress)
7143 {
7144 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7145 "%s: ROC in progress for session %d!!!",
7146 __func__, pAdapter->sessionId);
7147 // waiting for ROC to expire
7148 msleep(500);
7149 /* In GO present case , if retry exceeds 3,
7150 it means something went wrong. */
7151 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7152 {
7153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7154 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307155 if (eHAL_STATUS_SUCCESS !=
7156 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7157 pAdapter->sessionId ))
7158 {
7159 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7160 FL("Failed to Cancel Remain on Channel"));
7161 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307162 wait_for_completion_interruptible_timeout(
7163 &pAdapter->cancel_rem_on_chan_var,
7164 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7165 break;
7166 }
7167 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307168#ifdef WLAN_OPEN_SOURCE
7169 cancel_delayed_work_sync(&pAdapter->roc_work);
7170#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307171 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307172#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05307173#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307174 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
7175#endif
7176#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307177
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05307178#ifdef WLAN_OPEN_SOURCE
7179 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
7180#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307181
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307182 /* It is possible that the caller of this function does not
7183 * wish to close the session
7184 */
7185 if (VOS_TRUE == bCloseSession &&
7186 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007187 {
7188 INIT_COMPLETION(pAdapter->session_close_comp_var);
7189 if (eHAL_STATUS_SUCCESS ==
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307190 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
7191 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007192 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307193 unsigned long ret;
7194
Jeff Johnson295189b2012-06-20 16:38:30 -07007195 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307196 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307197 &pAdapter->session_close_comp_var,
7198 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307199 if ( 0 >= ret)
7200 {
7201 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307202 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307203 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007204 }
7205 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307206 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007207 break;
7208
7209 case WLAN_HDD_SOFTAP:
7210 case WLAN_HDD_P2P_GO:
7211 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307212 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7213 while (pAdapter->is_roc_inprogress) {
7214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7215 "%s: ROC in progress for session %d!!!",
7216 __func__, pAdapter->sessionId);
7217 msleep(500);
7218 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7220 "%s: ROC completion is not received.!!!", __func__);
7221 WLANSAP_CancelRemainOnChannel(
7222 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7223 wait_for_completion_interruptible_timeout(
7224 &pAdapter->cancel_rem_on_chan_var,
7225 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7226 break;
7227 }
7228 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307229
7230#ifdef WLAN_OPEN_SOURCE
7231 cancel_delayed_work_sync(&pAdapter->roc_work);
7232#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307233 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007234 mutex_lock(&pHddCtx->sap_lock);
7235 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7236 {
7237 VOS_STATUS status;
7238 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7239
7240 //Stop Bss.
7241 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7242 if (VOS_IS_STATUS_SUCCESS(status))
7243 {
7244 hdd_hostapd_state_t *pHostapdState =
7245 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7246
7247 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7248
7249 if (!VOS_IS_STATUS_SUCCESS(status))
7250 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307251 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7252 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007253 }
7254 }
7255 else
7256 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007257 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007258 }
7259 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307260 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007261
7262 if (eHAL_STATUS_FAILURE ==
7263 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7264 0, NULL, eANI_BOOLEAN_FALSE))
7265 {
7266 hddLog(LOGE,
7267 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007268 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007269 }
7270
7271 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7272 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7273 eANI_BOOLEAN_FALSE) )
7274 {
7275 hddLog(LOGE,
7276 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7277 }
7278
7279 // Reset WNI_CFG_PROBE_RSP Flags
7280 wlan_hdd_reset_prob_rspies(pAdapter);
7281 kfree(pAdapter->sessionCtx.ap.beacon);
7282 pAdapter->sessionCtx.ap.beacon = NULL;
7283 }
7284 mutex_unlock(&pHddCtx->sap_lock);
7285 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007286
Jeff Johnson295189b2012-06-20 16:38:30 -07007287 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007288#ifdef WLAN_OPEN_SOURCE
7289 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
7290#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007291 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007292
Jeff Johnson295189b2012-06-20 16:38:30 -07007293 default:
7294 break;
7295 }
7296
7297 EXIT();
7298 return VOS_STATUS_SUCCESS;
7299}
7300
7301VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7302{
7303 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7304 VOS_STATUS status;
7305 hdd_adapter_t *pAdapter;
7306
7307 ENTER();
7308
7309 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7310
7311 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7312 {
7313 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007314
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307315 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007316
7317 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7318 pAdapterNode = pNext;
7319 }
7320
7321 EXIT();
7322
7323 return VOS_STATUS_SUCCESS;
7324}
7325
Rajeev Kumarf999e582014-01-09 17:33:29 -08007326
7327#ifdef FEATURE_WLAN_BATCH_SCAN
7328/**---------------------------------------------------------------------------
7329
7330 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7331 structures
7332
7333 \param - pAdapter Pointer to HDD adapter
7334
7335 \return - None
7336
7337 --------------------------------------------------------------------------*/
7338void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7339{
7340 tHddBatchScanRsp *pNode;
7341 tHddBatchScanRsp *pPrev;
7342
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307343 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007344 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307345 hddLog(VOS_TRACE_LEVEL_ERROR,
7346 "%s: Adapter context is Null", __func__);
7347 return;
7348 }
7349
7350 pNode = pAdapter->pBatchScanRsp;
7351 while (pNode)
7352 {
7353 pPrev = pNode;
7354 pNode = pNode->pNext;
7355 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007356 }
7357
7358 pAdapter->pBatchScanRsp = NULL;
7359 pAdapter->numScanList = 0;
7360 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7361 pAdapter->prev_batch_id = 0;
7362
7363 return;
7364}
7365#endif
7366
7367
Jeff Johnson295189b2012-06-20 16:38:30 -07007368VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7369{
7370 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7371 VOS_STATUS status;
7372 hdd_adapter_t *pAdapter;
7373
7374 ENTER();
7375
7376 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7377
7378 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7379 {
7380 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307381 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007382 netif_tx_disable(pAdapter->dev);
7383 netif_carrier_off(pAdapter->dev);
7384
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007385 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7386
Jeff Johnson295189b2012-06-20 16:38:30 -07007387 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307388
7389 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7390
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307391 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7392 {
7393 hdd_wmm_adapter_close( pAdapter );
7394 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7395 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007396
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307397 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7398 {
7399 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7400 }
7401
Rajeev Kumarf999e582014-01-09 17:33:29 -08007402#ifdef FEATURE_WLAN_BATCH_SCAN
7403 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7404 {
7405 hdd_deinit_batch_scan(pAdapter);
7406 }
7407#endif
7408
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307409#ifdef FEATURE_WLAN_TDLS
7410 mutex_lock(&pHddCtx->tdls_lock);
7411 wlan_hdd_tdls_exit(pAdapter);
7412 mutex_unlock(&pHddCtx->tdls_lock);
7413#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007414 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7415 pAdapterNode = pNext;
7416 }
7417
7418 EXIT();
7419
7420 return VOS_STATUS_SUCCESS;
7421}
7422
7423VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7424{
7425 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7426 VOS_STATUS status;
7427 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307428 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007429
7430 ENTER();
7431
7432 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7433
7434 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7435 {
7436 pAdapter = pAdapterNode->pAdapter;
7437
Kumar Anand82c009f2014-05-29 00:29:42 -07007438 hdd_wmm_init( pAdapter );
7439
Jeff Johnson295189b2012-06-20 16:38:30 -07007440 switch(pAdapter->device_mode)
7441 {
7442 case WLAN_HDD_INFRA_STATION:
7443 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007444 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307445
7446 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7447
Jeff Johnson295189b2012-06-20 16:38:30 -07007448 hdd_init_station_mode(pAdapter);
7449 /* Open the gates for HDD to receive Wext commands */
7450 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007451 pHddCtx->scan_info.mScanPending = FALSE;
7452 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007453
7454 //Trigger the initial scan
7455 hdd_wlan_initial_scan(pAdapter);
7456
7457 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307458 if (eConnectionState_Associated == connState ||
7459 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007460 {
7461 union iwreq_data wrqu;
7462 memset(&wrqu, '\0', sizeof(wrqu));
7463 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7464 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7465 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007466 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007467
Jeff Johnson295189b2012-06-20 16:38:30 -07007468 /* indicate disconnected event to nl80211 */
7469 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7470 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007471 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307472 else if (eConnectionState_Connecting == connState)
7473 {
7474 /*
7475 * Indicate connect failure to supplicant if we were in the
7476 * process of connecting
7477 */
7478 cfg80211_connect_result(pAdapter->dev, NULL,
7479 NULL, 0, NULL, 0,
7480 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7481 GFP_KERNEL);
7482 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007483 break;
7484
7485 case WLAN_HDD_SOFTAP:
7486 /* softAP can handle SSR */
7487 break;
7488
7489 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007490 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007491 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007492 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007493 break;
7494
7495 case WLAN_HDD_MONITOR:
7496 /* monitor interface start */
7497 break;
7498 default:
7499 break;
7500 }
7501
7502 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7503 pAdapterNode = pNext;
7504 }
7505
7506 EXIT();
7507
7508 return VOS_STATUS_SUCCESS;
7509}
7510
7511VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7512{
7513 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7514 hdd_adapter_t *pAdapter;
7515 VOS_STATUS status;
7516 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307517 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007518
7519 ENTER();
7520
7521 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7522
7523 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7524 {
7525 pAdapter = pAdapterNode->pAdapter;
7526
7527 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7528 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7529 {
7530 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7531 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7532
Abhishek Singhf4669da2014-05-26 15:07:49 +05307533 hddLog(VOS_TRACE_LEVEL_INFO,
7534 "%s: Set HDD connState to eConnectionState_NotConnected",
7535 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007536 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7537 init_completion(&pAdapter->disconnect_comp_var);
7538 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7539 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7540
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307541 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007542 &pAdapter->disconnect_comp_var,
7543 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307544 if (0 >= ret)
7545 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7546 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007547
7548 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7549 pHddCtx->isAmpAllowed = VOS_FALSE;
7550 sme_RoamConnect(pHddCtx->hHal,
7551 pAdapter->sessionId, &(pWextState->roamProfile),
7552 &roamId);
7553 }
7554
7555 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7556 pAdapterNode = pNext;
7557 }
7558
7559 EXIT();
7560
7561 return VOS_STATUS_SUCCESS;
7562}
7563
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007564void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7565{
7566 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7567 VOS_STATUS status;
7568 hdd_adapter_t *pAdapter;
7569 hdd_station_ctx_t *pHddStaCtx;
7570 hdd_ap_ctx_t *pHddApCtx;
7571 hdd_hostapd_state_t * pHostapdState;
7572 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7573 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7574 const char *p2pMode = "DEV";
7575 const char *ccMode = "Standalone";
7576 int n;
7577
7578 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7579 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7580 {
7581 pAdapter = pAdapterNode->pAdapter;
7582 switch (pAdapter->device_mode) {
7583 case WLAN_HDD_INFRA_STATION:
7584 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7585 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7586 staChannel = pHddStaCtx->conn_info.operationChannel;
7587 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7588 }
7589 break;
7590 case WLAN_HDD_P2P_CLIENT:
7591 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7592 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7593 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7594 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7595 p2pMode = "CLI";
7596 }
7597 break;
7598 case WLAN_HDD_P2P_GO:
7599 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7600 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7601 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7602 p2pChannel = pHddApCtx->operatingChannel;
7603 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7604 }
7605 p2pMode = "GO";
7606 break;
7607 case WLAN_HDD_SOFTAP:
7608 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7609 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7610 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7611 apChannel = pHddApCtx->operatingChannel;
7612 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7613 }
7614 break;
7615 default:
7616 break;
7617 }
7618 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7619 pAdapterNode = pNext;
7620 }
7621 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7622 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7623 }
7624 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7625 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7626 if (p2pChannel > 0) {
7627 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7628 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7629 }
7630 if (apChannel > 0) {
7631 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7632 apChannel, MAC_ADDR_ARRAY(apBssid));
7633 }
7634
7635 if (p2pChannel > 0 && apChannel > 0) {
7636 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7637 }
7638}
7639
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007640bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007641{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007642 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007643}
7644
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007645/* Once SSR is disabled then it cannot be set. */
7646void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007647{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007648 if (HDD_SSR_DISABLED == isSsrRequired)
7649 return;
7650
Jeff Johnson295189b2012-06-20 16:38:30 -07007651 isSsrRequired = value;
7652}
7653
7654VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7655 hdd_adapter_list_node_t** ppAdapterNode)
7656{
7657 VOS_STATUS status;
7658 spin_lock(&pHddCtx->hddAdapters.lock);
7659 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7660 (hdd_list_node_t**) ppAdapterNode );
7661 spin_unlock(&pHddCtx->hddAdapters.lock);
7662 return status;
7663}
7664
7665VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7666 hdd_adapter_list_node_t* pAdapterNode,
7667 hdd_adapter_list_node_t** pNextAdapterNode)
7668{
7669 VOS_STATUS status;
7670 spin_lock(&pHddCtx->hddAdapters.lock);
7671 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7672 (hdd_list_node_t*) pAdapterNode,
7673 (hdd_list_node_t**)pNextAdapterNode );
7674
7675 spin_unlock(&pHddCtx->hddAdapters.lock);
7676 return status;
7677}
7678
7679VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7680 hdd_adapter_list_node_t* pAdapterNode)
7681{
7682 VOS_STATUS status;
7683 spin_lock(&pHddCtx->hddAdapters.lock);
7684 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7685 &pAdapterNode->node );
7686 spin_unlock(&pHddCtx->hddAdapters.lock);
7687 return status;
7688}
7689
7690VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7691 hdd_adapter_list_node_t** ppAdapterNode)
7692{
7693 VOS_STATUS status;
7694 spin_lock(&pHddCtx->hddAdapters.lock);
7695 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7696 (hdd_list_node_t**) ppAdapterNode );
7697 spin_unlock(&pHddCtx->hddAdapters.lock);
7698 return status;
7699}
7700
7701VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7702 hdd_adapter_list_node_t* pAdapterNode)
7703{
7704 VOS_STATUS status;
7705 spin_lock(&pHddCtx->hddAdapters.lock);
7706 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7707 (hdd_list_node_t*) pAdapterNode );
7708 spin_unlock(&pHddCtx->hddAdapters.lock);
7709 return status;
7710}
7711
7712VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7713 hdd_adapter_list_node_t* pAdapterNode)
7714{
7715 VOS_STATUS status;
7716 spin_lock(&pHddCtx->hddAdapters.lock);
7717 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7718 (hdd_list_node_t*) pAdapterNode );
7719 spin_unlock(&pHddCtx->hddAdapters.lock);
7720 return status;
7721}
7722
7723hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7724 tSirMacAddr macAddr )
7725{
7726 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7727 hdd_adapter_t *pAdapter;
7728 VOS_STATUS status;
7729
7730 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7731
7732 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7733 {
7734 pAdapter = pAdapterNode->pAdapter;
7735
7736 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7737 macAddr, sizeof(tSirMacAddr) ) )
7738 {
7739 return pAdapter;
7740 }
7741 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7742 pAdapterNode = pNext;
7743 }
7744
7745 return NULL;
7746
7747}
7748
7749hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7750{
7751 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7752 hdd_adapter_t *pAdapter;
7753 VOS_STATUS status;
7754
7755 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7756
7757 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7758 {
7759 pAdapter = pAdapterNode->pAdapter;
7760
7761 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7762 IFNAMSIZ ) )
7763 {
7764 return pAdapter;
7765 }
7766 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7767 pAdapterNode = pNext;
7768 }
7769
7770 return NULL;
7771
7772}
7773
7774hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7775{
7776 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7777 hdd_adapter_t *pAdapter;
7778 VOS_STATUS status;
7779
7780 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7781
7782 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7783 {
7784 pAdapter = pAdapterNode->pAdapter;
7785
7786 if( pAdapter && (mode == pAdapter->device_mode) )
7787 {
7788 return pAdapter;
7789 }
7790 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7791 pAdapterNode = pNext;
7792 }
7793
7794 return NULL;
7795
7796}
7797
7798//Remove this function later
7799hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7800{
7801 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7802 hdd_adapter_t *pAdapter;
7803 VOS_STATUS status;
7804
7805 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7806
7807 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7808 {
7809 pAdapter = pAdapterNode->pAdapter;
7810
7811 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7812 {
7813 return pAdapter;
7814 }
7815
7816 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7817 pAdapterNode = pNext;
7818 }
7819
7820 return NULL;
7821
7822}
7823
Jeff Johnson295189b2012-06-20 16:38:30 -07007824/**---------------------------------------------------------------------------
7825
7826 \brief hdd_set_monitor_tx_adapter() -
7827
7828 This API initializes the adapter to be used while transmitting on monitor
7829 adapter.
7830
7831 \param - pHddCtx - Pointer to the HDD context.
7832 pAdapter - Adapter that will used for TX. This can be NULL.
7833 \return - None.
7834 --------------------------------------------------------------------------*/
7835void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7836{
7837 hdd_adapter_t *pMonAdapter;
7838
7839 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7840
7841 if( NULL != pMonAdapter )
7842 {
7843 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7844 }
7845}
Jeff Johnson295189b2012-06-20 16:38:30 -07007846/**---------------------------------------------------------------------------
7847
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307848 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007849
7850 This API returns the operating channel of the requested device mode
7851
7852 \param - pHddCtx - Pointer to the HDD context.
7853 - mode - Device mode for which operating channel is required
7854 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7855 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7856 \return - channel number. "0" id the requested device is not found OR it is not connected.
7857 --------------------------------------------------------------------------*/
7858v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7859{
7860 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7861 VOS_STATUS status;
7862 hdd_adapter_t *pAdapter;
7863 v_U8_t operatingChannel = 0;
7864
7865 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7866
7867 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7868 {
7869 pAdapter = pAdapterNode->pAdapter;
7870
7871 if( mode == pAdapter->device_mode )
7872 {
7873 switch(pAdapter->device_mode)
7874 {
7875 case WLAN_HDD_INFRA_STATION:
7876 case WLAN_HDD_P2P_CLIENT:
7877 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7878 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7879 break;
7880 case WLAN_HDD_SOFTAP:
7881 case WLAN_HDD_P2P_GO:
7882 /*softap connection info */
7883 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7884 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7885 break;
7886 default:
7887 break;
7888 }
7889
7890 break; //Found the device of interest. break the loop
7891 }
7892
7893 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7894 pAdapterNode = pNext;
7895 }
7896 return operatingChannel;
7897}
7898
7899#ifdef WLAN_FEATURE_PACKET_FILTERING
7900/**---------------------------------------------------------------------------
7901
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307902 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007903
7904 This used to set the multicast address list.
7905
7906 \param - dev - Pointer to the WLAN device.
7907 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307908 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07007909
7910 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307911static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007912{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307913 hdd_adapter_t *pAdapter;
7914 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007915 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307916 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007917 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307918
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307919 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307920 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007921 {
7922 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307923 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007924 return;
7925 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307926 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7927 ret = wlan_hdd_validate_context(pHddCtx);
7928 if (0 != ret)
7929 {
7930 hddLog(VOS_TRACE_LEVEL_ERROR,
7931 "%s: HDD context is not valid",__func__);
7932 return;
7933 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007934 if (dev->flags & IFF_ALLMULTI)
7935 {
7936 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007937 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307938 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007939 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307940 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007941 {
7942 mc_count = netdev_mc_count(dev);
7943 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007944 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007945 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7946 {
7947 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007948 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307949 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007950 return;
7951 }
7952
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307953 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007954
7955 netdev_for_each_mc_addr(ha, dev) {
7956 if (i == mc_count)
7957 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307958 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7959 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007960 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307961 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307962 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007963 i++;
7964 }
7965 }
7966 return;
7967}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307968
7969static void hdd_set_multicast_list(struct net_device *dev)
7970{
7971 vos_ssr_protect(__func__);
7972 __hdd_set_multicast_list(dev);
7973 vos_ssr_unprotect(__func__);
7974}
Jeff Johnson295189b2012-06-20 16:38:30 -07007975#endif
7976
7977/**---------------------------------------------------------------------------
7978
7979 \brief hdd_select_queue() -
7980
7981 This function is registered with the Linux OS for network
7982 core to decide which queue to use first.
7983
7984 \param - dev - Pointer to the WLAN device.
7985 - skb - Pointer to OS packet (sk_buff).
7986 \return - ac, Queue Index/access category corresponding to UP in IP header
7987
7988 --------------------------------------------------------------------------*/
7989v_U16_t hdd_select_queue(struct net_device *dev,
7990 struct sk_buff *skb)
7991{
7992 return hdd_wmm_select_queue(dev, skb);
7993}
7994
7995
7996/**---------------------------------------------------------------------------
7997
7998 \brief hdd_wlan_initial_scan() -
7999
8000 This function triggers the initial scan
8001
8002 \param - pAdapter - Pointer to the HDD adapter.
8003
8004 --------------------------------------------------------------------------*/
8005void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8006{
8007 tCsrScanRequest scanReq;
8008 tCsrChannelInfo channelInfo;
8009 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008010 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008011 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8012
8013 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8014 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8015 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8016
8017 if(sme_Is11dSupported(pHddCtx->hHal))
8018 {
8019 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8020 if ( HAL_STATUS_SUCCESS( halStatus ) )
8021 {
8022 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8023 if( !scanReq.ChannelInfo.ChannelList )
8024 {
8025 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8026 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008027 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008028 return;
8029 }
8030 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8031 channelInfo.numOfChannels);
8032 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8033 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008034 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008035 }
8036
8037 scanReq.scanType = eSIR_PASSIVE_SCAN;
8038 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8039 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8040 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8041 }
8042 else
8043 {
8044 scanReq.scanType = eSIR_ACTIVE_SCAN;
8045 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8046 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8047 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8048 }
8049
8050 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8051 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8052 {
8053 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8054 __func__, halStatus );
8055 }
8056
8057 if(sme_Is11dSupported(pHddCtx->hHal))
8058 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8059}
8060
Jeff Johnson295189b2012-06-20 16:38:30 -07008061/**---------------------------------------------------------------------------
8062
8063 \brief hdd_full_power_callback() - HDD full power callback function
8064
8065 This is the function invoked by SME to inform the result of a full power
8066 request issued by HDD
8067
8068 \param - callbackcontext - Pointer to cookie
8069 \param - status - result of request
8070
8071 \return - None
8072
8073 --------------------------------------------------------------------------*/
8074static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8075{
Jeff Johnson72a40512013-12-19 10:14:15 -08008076 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008077
8078 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308079 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008080
8081 if (NULL == callbackContext)
8082 {
8083 hddLog(VOS_TRACE_LEVEL_ERROR,
8084 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008085 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008086 return;
8087 }
8088
Jeff Johnson72a40512013-12-19 10:14:15 -08008089 /* there is a race condition that exists between this callback
8090 function and the caller since the caller could time out either
8091 before or while this code is executing. we use a spinlock to
8092 serialize these actions */
8093 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008094
8095 if (POWER_CONTEXT_MAGIC != pContext->magic)
8096 {
8097 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008098 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008099 hddLog(VOS_TRACE_LEVEL_WARN,
8100 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008101 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008102 return;
8103 }
8104
Jeff Johnson72a40512013-12-19 10:14:15 -08008105 /* context is valid so caller is still waiting */
8106
8107 /* paranoia: invalidate the magic */
8108 pContext->magic = 0;
8109
8110 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008111 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008112
8113 /* serialization is complete */
8114 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008115}
8116
8117/**---------------------------------------------------------------------------
8118
8119 \brief hdd_wlan_exit() - HDD WLAN exit function
8120
8121 This is the driver exit point (invoked during rmmod)
8122
8123 \param - pHddCtx - Pointer to the HDD Context
8124
8125 \return - None
8126
8127 --------------------------------------------------------------------------*/
8128void hdd_wlan_exit(hdd_context_t *pHddCtx)
8129{
8130 eHalStatus halStatus;
8131 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8132 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308133 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008134 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008135 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008136 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308137 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008138
8139 ENTER();
8140
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308141#ifdef WLAN_NS_OFFLOAD
8142 hddLog(LOGE, FL("Unregister IPv6 notifier"));
8143 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8144#endif
8145 hddLog(LOGE, FL("Unregister IPv4 notifier"));
8146 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8147
Jeff Johnson88ba7742013-02-27 14:36:02 -08008148 if (VOS_FTM_MODE != hdd_get_conparam())
8149 {
Katya Nigamdc373382015-02-25 18:52:19 +05308150 /* This will issue a dump command which will clean up
8151 BTQM queues and unblock MC thread */
8152 WLANTL_TLDebugMessage(WLANTL_DEBUG_FW_CLEANUP);
8153
Jeff Johnson88ba7742013-02-27 14:36:02 -08008154 // Unloading, restart logic is no more required.
8155 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008156
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308157#ifdef FEATURE_WLAN_TDLS
8158 /* At the time of driver unloading; if tdls connection is present;
8159 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8160 * wlan_hdd_tdls_find_peer always checks for valid context;
8161 * as load/unload in progress there can be a race condition.
8162 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8163 * when tdls state is enabled.
8164 * As soon as driver set load/unload flag; tdls flag also needs
8165 * to be disabled so that hdd_rx_packet_cbk won't call
8166 * wlan_hdd_tdls_find_peer.
8167 */
8168 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8169#endif
8170
c_hpothu5ab05e92014-06-13 17:34:05 +05308171 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8172 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008173 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308174 pAdapter = pAdapterNode->pAdapter;
8175 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008176 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308177 /* Disable TX on the interface, after this hard_start_xmit() will
8178 * not be called on that interface
8179 */
8180 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8181 netif_tx_disable(pAdapter->dev);
8182
8183 /* Mark the interface status as "down" for outside world */
8184 netif_carrier_off(pAdapter->dev);
8185
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308186 /* DeInit the adapter. This ensures that all data packets
8187 * are freed.
8188 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308189#ifdef FEATURE_WLAN_TDLS
8190 mutex_lock(&pHddCtx->tdls_lock);
8191#endif
c_hpothu002231a2015-02-05 14:58:51 +05308192 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308193#ifdef FEATURE_WLAN_TDLS
8194 mutex_unlock(&pHddCtx->tdls_lock);
8195#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308196
c_hpothu5ab05e92014-06-13 17:34:05 +05308197 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8198 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8199 {
8200 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8201 hdd_UnregisterWext(pAdapter->dev);
8202 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308203
Jeff Johnson295189b2012-06-20 16:38:30 -07008204 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308205 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8206 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008207 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308208 // Cancel any outstanding scan requests. We are about to close all
8209 // of our adapters, but an adapter structure is what SME passes back
8210 // to our callback function. Hence if there are any outstanding scan
8211 // requests then there is a race condition between when the adapter
8212 // is closed and when the callback is invoked.We try to resolve that
8213 // race condition here by canceling any outstanding scans before we
8214 // close the adapters.
8215 // Note that the scans may be cancelled in an asynchronous manner,
8216 // so ideally there needs to be some kind of synchronization. Rather
8217 // than introduce a new synchronization here, we will utilize the
8218 // fact that we are about to Request Full Power, and since that is
8219 // synchronized, the expectation is that by the time Request Full
8220 // Power has completed all scans will be cancelled.
8221 if (pHddCtx->scan_info.mScanPending)
8222 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308223 if(NULL != pAdapter)
8224 {
8225 hddLog(VOS_TRACE_LEVEL_INFO,
8226 FL("abort scan mode: %d sessionId: %d"),
8227 pAdapter->device_mode,
8228 pAdapter->sessionId);
8229 }
8230 hdd_abort_mac_scan(pHddCtx,
8231 pHddCtx->scan_info.sessionId,
8232 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308233 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008234 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308235 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008236 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308237 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308238 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8239 {
8240 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8241 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8242 "%s: in middle of FTM START", __func__);
8243 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8244 msecs_to_jiffies(20000));
8245 if(!lrc)
8246 {
8247 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8248 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8249 }
8250 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008251 wlan_hdd_ftm_close(pHddCtx);
8252 goto free_hdd_ctx;
8253 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308254
Jeff Johnson295189b2012-06-20 16:38:30 -07008255 /* DeRegister with platform driver as client for Suspend/Resume */
8256 vosStatus = hddDeregisterPmOps(pHddCtx);
8257 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8258 {
8259 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8260 VOS_ASSERT(0);
8261 }
8262
8263 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8264 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8265 {
8266 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8267 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008268
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008269 //Stop the traffic monitor timer
8270 if ( VOS_TIMER_STATE_RUNNING ==
8271 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8272 {
8273 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8274 }
8275
8276 // Destroy the traffic monitor timer
8277 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8278 &pHddCtx->tx_rx_trafficTmr)))
8279 {
8280 hddLog(VOS_TRACE_LEVEL_ERROR,
8281 "%s: Cannot deallocate Traffic monitor timer", __func__);
8282 }
8283
Jeff Johnson295189b2012-06-20 16:38:30 -07008284 //Disable IMPS/BMPS as we do not want the device to enter any power
8285 //save mode during shutdown
8286 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8287 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8288 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8289
8290 //Ensure that device is in full power as we will touch H/W during vos_Stop
8291 init_completion(&powerContext.completion);
8292 powerContext.magic = POWER_CONTEXT_MAGIC;
8293
8294 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8295 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8296
8297 if (eHAL_STATUS_SUCCESS != halStatus)
8298 {
8299 if (eHAL_STATUS_PMC_PENDING == halStatus)
8300 {
8301 /* request was sent -- wait for the response */
8302 lrc = wait_for_completion_interruptible_timeout(
8303 &powerContext.completion,
8304 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008305 if (lrc <= 0)
8306 {
8307 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008308 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008309 }
8310 }
8311 else
8312 {
8313 hddLog(VOS_TRACE_LEVEL_ERROR,
8314 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008315 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008316 /* continue -- need to clean up as much as possible */
8317 }
8318 }
8319
Jeff Johnson72a40512013-12-19 10:14:15 -08008320 /* either we never sent a request, we sent a request and received a
8321 response or we sent a request and timed out. if we never sent a
8322 request or if we sent a request and got a response, we want to
8323 clear the magic out of paranoia. if we timed out there is a
8324 race condition such that the callback function could be
8325 executing at the same time we are. of primary concern is if the
8326 callback function had already verified the "magic" but had not
8327 yet set the completion variable when a timeout occurred. we
8328 serialize these activities by invalidating the magic while
8329 holding a shared spinlock which will cause us to block if the
8330 callback is currently executing */
8331 spin_lock(&hdd_context_lock);
8332 powerContext.magic = 0;
8333 spin_unlock(&hdd_context_lock);
8334
Yue Ma0d4891e2013-08-06 17:01:45 -07008335 hdd_debugfs_exit(pHddCtx);
8336
Jeff Johnson295189b2012-06-20 16:38:30 -07008337 // Unregister the Net Device Notifier
8338 unregister_netdevice_notifier(&hdd_netdev_notifier);
8339
Jeff Johnson295189b2012-06-20 16:38:30 -07008340 hdd_stop_all_adapters( pHddCtx );
8341
Jeff Johnson295189b2012-06-20 16:38:30 -07008342#ifdef WLAN_BTAMP_FEATURE
8343 vosStatus = WLANBAP_Stop(pVosContext);
8344 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8345 {
8346 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8347 "%s: Failed to stop BAP",__func__);
8348 }
8349#endif //WLAN_BTAMP_FEATURE
8350
8351 //Stop all the modules
8352 vosStatus = vos_stop( pVosContext );
8353 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8354 {
8355 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8356 "%s: Failed to stop VOSS",__func__);
8357 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8358 }
8359
Jeff Johnson295189b2012-06-20 16:38:30 -07008360 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008361 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008362
8363 //Close the scheduler before calling vos_close to make sure no thread is
8364 // scheduled after the each module close is called i.e after all the data
8365 // structures are freed.
8366 vosStatus = vos_sched_close( pVosContext );
8367 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8368 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8369 "%s: Failed to close VOSS Scheduler",__func__);
8370 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8371 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008372#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008373#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8374 /* Destroy the wake lock */
8375 wake_lock_destroy(&pHddCtx->rx_wake_lock);
8376#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008377 /* Destroy the wake lock */
8378 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008379#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008380
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308381#ifdef CONFIG_ENABLE_LINUX_REG
8382 vosStatus = vos_nv_close();
8383 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8384 {
8385 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8386 "%s: Failed to close NV", __func__);
8387 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8388 }
8389#endif
8390
Jeff Johnson295189b2012-06-20 16:38:30 -07008391 //Close VOSS
8392 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8393 vos_close(pVosContext);
8394
Jeff Johnson295189b2012-06-20 16:38:30 -07008395 //Close Watchdog
8396 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8397 vos_watchdog_close(pVosContext);
8398
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308399 //Clean up HDD Nlink Service
8400 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308401
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308402#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308403 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308404 {
8405 wlan_logging_sock_deactivate_svc();
8406 }
8407#endif
8408
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308409#ifdef WLAN_KD_READY_NOTIFIER
8410 nl_srv_exit(pHddCtx->ptt_pid);
8411#else
8412 nl_srv_exit();
8413#endif /* WLAN_KD_READY_NOTIFIER */
8414
8415
Jeff Johnson295189b2012-06-20 16:38:30 -07008416 hdd_close_all_adapters( pHddCtx );
8417
Jeff Johnson295189b2012-06-20 16:38:30 -07008418 /* free the power on lock from platform driver */
8419 if (free_riva_power_on_lock("wlan"))
8420 {
8421 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8422 __func__);
8423 }
8424
Jeff Johnson88ba7742013-02-27 14:36:02 -08008425free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308426
8427 //Free up dynamically allocated members inside HDD Adapter
8428 if (pHddCtx->cfg_ini)
8429 {
8430 kfree(pHddCtx->cfg_ini);
8431 pHddCtx->cfg_ini= NULL;
8432 }
8433
Leo Changf04ddad2013-09-18 13:46:38 -07008434 /* FTM mode, WIPHY did not registered
8435 If un-register here, system crash will happen */
8436 if (VOS_FTM_MODE != hdd_get_conparam())
8437 {
8438 wiphy_unregister(wiphy) ;
8439 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008440 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008441 if (hdd_is_ssr_required())
8442 {
8443 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008444 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008445 msleep(5000);
8446 }
8447 hdd_set_ssr_required (VOS_FALSE);
8448}
8449
8450
8451/**---------------------------------------------------------------------------
8452
8453 \brief hdd_update_config_from_nv() - Function to update the contents of
8454 the running configuration with parameters taken from NV storage
8455
8456 \param - pHddCtx - Pointer to the HDD global context
8457
8458 \return - VOS_STATUS_SUCCESS if successful
8459
8460 --------------------------------------------------------------------------*/
8461static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8462{
Jeff Johnson295189b2012-06-20 16:38:30 -07008463 v_BOOL_t itemIsValid = VOS_FALSE;
8464 VOS_STATUS status;
8465 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8466 v_U8_t macLoop;
8467
8468 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8469 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8470 if(status != VOS_STATUS_SUCCESS)
8471 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008472 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008473 return VOS_STATUS_E_FAILURE;
8474 }
8475
8476 if (itemIsValid == VOS_TRUE)
8477 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008478 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008479 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8480 VOS_MAX_CONCURRENCY_PERSONA);
8481 if(status != VOS_STATUS_SUCCESS)
8482 {
8483 /* Get MAC from NV fail, not update CFG info
8484 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008485 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008486 return VOS_STATUS_E_FAILURE;
8487 }
8488
8489 /* If first MAC is not valid, treat all others are not valid
8490 * Then all MACs will be got from ini file */
8491 if(vos_is_macaddr_zero(&macFromNV[0]))
8492 {
8493 /* MAC address in NV file is not configured yet */
8494 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8495 return VOS_STATUS_E_INVAL;
8496 }
8497
8498 /* Get MAC address from NV, update CFG info */
8499 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8500 {
8501 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8502 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308503 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008504 /* This MAC is not valid, skip it
8505 * This MAC will be got from ini file */
8506 }
8507 else
8508 {
8509 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8510 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8511 VOS_MAC_ADDR_SIZE);
8512 }
8513 }
8514 }
8515 else
8516 {
8517 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8518 return VOS_STATUS_E_FAILURE;
8519 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008520
Jeff Johnson295189b2012-06-20 16:38:30 -07008521
8522 return VOS_STATUS_SUCCESS;
8523}
8524
8525/**---------------------------------------------------------------------------
8526
8527 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8528
8529 \param - pAdapter - Pointer to the HDD
8530
8531 \return - None
8532
8533 --------------------------------------------------------------------------*/
8534VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8535{
8536 eHalStatus halStatus;
8537 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308538 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008539
Jeff Johnson295189b2012-06-20 16:38:30 -07008540
8541 // Send ready indication to the HDD. This will kick off the MAC
8542 // into a 'running' state and should kick off an initial scan.
8543 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8544 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8545 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308546 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008547 "code %08d [x%08x]",__func__, halStatus, halStatus );
8548 return VOS_STATUS_E_FAILURE;
8549 }
8550
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308551 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008552 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8553 // And RIVA will crash
8554 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8555 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308556 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8557 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8558
8559
Jeff Johnson295189b2012-06-20 16:38:30 -07008560 return VOS_STATUS_SUCCESS;
8561}
8562
Jeff Johnson295189b2012-06-20 16:38:30 -07008563/* wake lock APIs for HDD */
8564void hdd_prevent_suspend(void)
8565{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008566#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008567 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008568#else
8569 wcnss_prevent_suspend();
8570#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008571}
8572
8573void hdd_allow_suspend(void)
8574{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008575#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008576 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008577#else
8578 wcnss_allow_suspend();
8579#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008580}
8581
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308582void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008583{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008584#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008585 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008586#else
8587 /* Do nothing as there is no API in wcnss for timeout*/
8588#endif
8589}
8590
Jeff Johnson295189b2012-06-20 16:38:30 -07008591/**---------------------------------------------------------------------------
8592
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008593 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8594 information between Host and Riva
8595
8596 This function gets reported version of FW
8597 It also finds the version of Riva headers used to compile the host
8598 It compares the above two and prints a warning if they are different
8599 It gets the SW and HW version string
8600 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8601 indicating the features they support through a bitmap
8602
8603 \param - pHddCtx - Pointer to HDD context
8604
8605 \return - void
8606
8607 --------------------------------------------------------------------------*/
8608
8609void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8610{
8611
8612 tSirVersionType versionCompiled;
8613 tSirVersionType versionReported;
8614 tSirVersionString versionString;
8615 tANI_U8 fwFeatCapsMsgSupported = 0;
8616 VOS_STATUS vstatus;
8617
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008618 memset(&versionCompiled, 0, sizeof(versionCompiled));
8619 memset(&versionReported, 0, sizeof(versionReported));
8620
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008621 /* retrieve and display WCNSS version information */
8622 do {
8623
8624 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8625 &versionCompiled);
8626 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8627 {
8628 hddLog(VOS_TRACE_LEVEL_FATAL,
8629 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008630 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008631 break;
8632 }
8633
8634 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8635 &versionReported);
8636 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8637 {
8638 hddLog(VOS_TRACE_LEVEL_FATAL,
8639 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008640 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008641 break;
8642 }
8643
8644 if ((versionCompiled.major != versionReported.major) ||
8645 (versionCompiled.minor != versionReported.minor) ||
8646 (versionCompiled.version != versionReported.version) ||
8647 (versionCompiled.revision != versionReported.revision))
8648 {
8649 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8650 "Host expected %u.%u.%u.%u\n",
8651 WLAN_MODULE_NAME,
8652 (int)versionReported.major,
8653 (int)versionReported.minor,
8654 (int)versionReported.version,
8655 (int)versionReported.revision,
8656 (int)versionCompiled.major,
8657 (int)versionCompiled.minor,
8658 (int)versionCompiled.version,
8659 (int)versionCompiled.revision);
8660 }
8661 else
8662 {
8663 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8664 WLAN_MODULE_NAME,
8665 (int)versionReported.major,
8666 (int)versionReported.minor,
8667 (int)versionReported.version,
8668 (int)versionReported.revision);
8669 }
8670
8671 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8672 versionString,
8673 sizeof(versionString));
8674 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8675 {
8676 hddLog(VOS_TRACE_LEVEL_FATAL,
8677 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008678 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008679 break;
8680 }
8681
8682 pr_info("%s: WCNSS software version %s\n",
8683 WLAN_MODULE_NAME, versionString);
8684
8685 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8686 versionString,
8687 sizeof(versionString));
8688 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8689 {
8690 hddLog(VOS_TRACE_LEVEL_FATAL,
8691 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008692 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008693 break;
8694 }
8695
8696 pr_info("%s: WCNSS hardware version %s\n",
8697 WLAN_MODULE_NAME, versionString);
8698
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008699 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8700 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008701 send the message only if it the riva is 1.1
8702 minor numbers for different riva branches:
8703 0 -> (1.0)Mainline Build
8704 1 -> (1.1)Mainline Build
8705 2->(1.04) Stability Build
8706 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008707 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008708 ((versionReported.minor>=1) && (versionReported.version>=1)))
8709 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8710 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008711
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008712 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008713 {
8714#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8715 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8716 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8717#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008718 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8719 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8720 {
8721 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8722 }
8723
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008724 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008725 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008726
8727 } while (0);
8728
8729}
Neelansh Mittaledafed22014-09-04 18:54:39 +05308730void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
8731{
8732 struct sk_buff *skb;
8733 struct nlmsghdr *nlh;
8734 tAniMsgHdr *ani_hdr;
8735
8736 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
8737
8738 if(skb == NULL) {
8739 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8740 "%s: alloc_skb failed", __func__);
8741 return;
8742 }
8743
8744 nlh = (struct nlmsghdr *)skb->data;
8745 nlh->nlmsg_pid = 0; /* from kernel */
8746 nlh->nlmsg_flags = 0;
8747 nlh->nlmsg_seq = 0;
8748 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
8749
8750 ani_hdr = NLMSG_DATA(nlh);
8751 ani_hdr->type = type;
8752
8753 switch(type) {
8754 case WLAN_SVC_SAP_RESTART_IND:
8755 ani_hdr->length = 0;
8756 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
8757 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
8758 break;
8759 default:
8760 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8761 "Attempt to send unknown nlink message %d", type);
8762 kfree_skb(skb);
8763 return;
8764 }
8765
8766 nl_srv_bcast(skb);
8767
8768 return;
8769}
8770
8771
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008772
8773/**---------------------------------------------------------------------------
8774
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308775 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8776
8777 \param - pHddCtx - Pointer to the hdd context
8778
8779 \return - true if hardware supports 5GHz
8780
8781 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308782boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308783{
8784 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8785 * then hardware support 5Ghz.
8786 */
8787 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8788 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308789 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308790 return true;
8791 }
8792 else
8793 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308794 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308795 __func__);
8796 return false;
8797 }
8798}
8799
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308800/**---------------------------------------------------------------------------
8801
8802 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8803 generate function
8804
8805 This is generate the random mac address for WLAN interface
8806
8807 \param - pHddCtx - Pointer to HDD context
8808 idx - Start interface index to get auto
8809 generated mac addr.
8810 mac_addr - Mac address
8811
8812 \return - 0 for success, < 0 for failure
8813
8814 --------------------------------------------------------------------------*/
8815
8816static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8817 int idx, v_MACADDR_t mac_addr)
8818{
8819 int i;
8820 unsigned int serialno;
8821 serialno = wcnss_get_serial_number();
8822
8823 if (0 != serialno)
8824 {
8825 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8826 bytes of the serial number that can be used to generate
8827 the other 3 bytes of the MAC address. Mask off all but
8828 the lower 3 bytes (this will also make sure we don't
8829 overflow in the next step) */
8830 serialno &= 0x00FFFFFF;
8831
8832 /* we need a unique address for each session */
8833 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8834
8835 /* autogen other Mac addresses */
8836 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8837 {
8838 /* start with the entire default address */
8839 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8840 /* then replace the lower 3 bytes */
8841 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8842 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8843 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8844
8845 serialno++;
8846 hddLog(VOS_TRACE_LEVEL_ERROR,
8847 "%s: Derived Mac Addr: "
8848 MAC_ADDRESS_STR, __func__,
8849 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8850 }
8851
8852 }
8853 else
8854 {
8855 hddLog(LOGE, FL("Failed to Get Serial NO"));
8856 return -1;
8857 }
8858 return 0;
8859}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308860
8861/**---------------------------------------------------------------------------
8862
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308863 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8864 completed to flush out the scan results
8865
8866 11d scan is done during driver load and is a passive scan on all
8867 channels supported by the device, 11d scans may find some APs on
8868 frequencies which are forbidden to be used in the regulatory domain
8869 the device is operating in. If these APs are notified to the supplicant
8870 it may try to connect to these APs, thus flush out all the scan results
8871 which are present in SME after 11d scan is done.
8872
8873 \return - eHalStatus
8874
8875 --------------------------------------------------------------------------*/
8876static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8877 tANI_U32 scanId, eCsrScanStatus status)
8878{
8879 ENTER();
8880
8881 sme_ScanFlushResult(halHandle, 0);
8882
8883 EXIT();
8884
8885 return eHAL_STATUS_SUCCESS;
8886}
8887
8888/**---------------------------------------------------------------------------
8889
Jeff Johnson295189b2012-06-20 16:38:30 -07008890 \brief hdd_wlan_startup() - HDD init function
8891
8892 This is the driver startup code executed once a WLAN device has been detected
8893
8894 \param - dev - Pointer to the underlying device
8895
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008896 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008897
8898 --------------------------------------------------------------------------*/
8899
8900int hdd_wlan_startup(struct device *dev )
8901{
8902 VOS_STATUS status;
8903 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008904 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008905 hdd_context_t *pHddCtx = NULL;
8906 v_CONTEXT_t pVosContext= NULL;
8907#ifdef WLAN_BTAMP_FEATURE
8908 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8909 WLANBAP_ConfigType btAmpConfig;
8910 hdd_config_t *pConfig;
8911#endif
8912 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008913 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308914 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008915
8916 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008917 /*
8918 * cfg80211: wiphy allocation
8919 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308920 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008921
8922 if(wiphy == NULL)
8923 {
8924 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008925 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008926 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008927 pHddCtx = wiphy_priv(wiphy);
8928
Jeff Johnson295189b2012-06-20 16:38:30 -07008929 //Initialize the adapter context to zeros.
8930 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8931
Jeff Johnson295189b2012-06-20 16:38:30 -07008932 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008933 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308934 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008935
8936 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8937
8938 /*Get vos context here bcoz vos_open requires it*/
8939 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8940
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008941 if(pVosContext == NULL)
8942 {
8943 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8944 goto err_free_hdd_context;
8945 }
8946
Jeff Johnson295189b2012-06-20 16:38:30 -07008947 //Save the Global VOSS context in adapter context for future.
8948 pHddCtx->pvosContext = pVosContext;
8949
8950 //Save the adapter context in global context for future.
8951 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8952
Jeff Johnson295189b2012-06-20 16:38:30 -07008953 pHddCtx->parent_dev = dev;
8954
8955 init_completion(&pHddCtx->full_pwr_comp_var);
8956 init_completion(&pHddCtx->standby_comp_var);
8957 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008958 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008959 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308960 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308961 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008962
8963#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008964 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008965#else
8966 init_completion(&pHddCtx->driver_crda_req);
8967#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008968
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308969 spin_lock_init(&pHddCtx->schedScan_lock);
8970
Jeff Johnson295189b2012-06-20 16:38:30 -07008971 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8972
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308973#ifdef FEATURE_WLAN_TDLS
8974 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8975 * invoked by other instances also) to protect the concurrent
8976 * access for the Adapters by TDLS module.
8977 */
8978 mutex_init(&pHddCtx->tdls_lock);
8979#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05308980 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05308981 mutex_init(&pHddCtx->wmmLock);
8982
Agarwal Ashish1f422872014-07-22 00:11:55 +05308983 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308984
Agarwal Ashish1f422872014-07-22 00:11:55 +05308985 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008986 // Load all config first as TL config is needed during vos_open
8987 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8988 if(pHddCtx->cfg_ini == NULL)
8989 {
8990 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8991 goto err_free_hdd_context;
8992 }
8993
8994 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8995
8996 // Read and parse the qcom_cfg.ini file
8997 status = hdd_parse_config_ini( pHddCtx );
8998 if ( VOS_STATUS_SUCCESS != status )
8999 {
9000 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9001 __func__, WLAN_INI_FILE);
9002 goto err_config;
9003 }
Arif Hussaind5218912013-12-05 01:10:55 -08009004#ifdef MEMORY_DEBUG
9005 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9006 vos_mem_init();
9007
9008 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9009 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9010#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009011
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309012 /* INI has been read, initialise the configuredMcastBcastFilter with
9013 * INI value as this will serve as the default value
9014 */
9015 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9016 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9017 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309018
9019 if (false == hdd_is_5g_supported(pHddCtx))
9020 {
9021 //5Ghz is not supported.
9022 if (1 != pHddCtx->cfg_ini->nBandCapability)
9023 {
9024 hddLog(VOS_TRACE_LEVEL_INFO,
9025 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9026 pHddCtx->cfg_ini->nBandCapability = 1;
9027 }
9028 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309029
9030 /* If SNR Monitoring is enabled, FW has to parse all beacons
9031 * for calcaluting and storing the average SNR, so set Nth beacon
9032 * filter to 1 to enable FW to parse all the beaocons
9033 */
9034 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9035 {
9036 /* The log level is deliberately set to WARN as overriding
9037 * nthBeaconFilter to 1 will increase power cosumption and this
9038 * might just prove helpful to detect the power issue.
9039 */
9040 hddLog(VOS_TRACE_LEVEL_WARN,
9041 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9042 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9043 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009044 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309045 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009046 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009047 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009048 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009049 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9050 {
9051 hddLog(VOS_TRACE_LEVEL_FATAL,
9052 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9053 goto err_config;
9054 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009055 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009056
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009057 // Update VOS trace levels based upon the cfg.ini
9058 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9059 pHddCtx->cfg_ini->vosTraceEnableBAP);
9060 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9061 pHddCtx->cfg_ini->vosTraceEnableTL);
9062 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9063 pHddCtx->cfg_ini->vosTraceEnableWDI);
9064 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9065 pHddCtx->cfg_ini->vosTraceEnableHDD);
9066 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9067 pHddCtx->cfg_ini->vosTraceEnableSME);
9068 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9069 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309070 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9071 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009072 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9073 pHddCtx->cfg_ini->vosTraceEnableWDA);
9074 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9075 pHddCtx->cfg_ini->vosTraceEnableSYS);
9076 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9077 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009078 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9079 pHddCtx->cfg_ini->vosTraceEnableSAP);
9080 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9081 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009082
Jeff Johnson295189b2012-06-20 16:38:30 -07009083 // Update WDI trace levels based upon the cfg.ini
9084 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9085 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9086 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9087 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9088 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9089 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9090 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9091 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009092
Jeff Johnson88ba7742013-02-27 14:36:02 -08009093 if (VOS_FTM_MODE == hdd_get_conparam())
9094 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009095 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9096 {
9097 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9098 goto err_free_hdd_context;
9099 }
9100 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05309101
9102 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009103 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009104 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009105
Jeff Johnson88ba7742013-02-27 14:36:02 -08009106 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009107 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9108 {
9109 status = vos_watchdog_open(pVosContext,
9110 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9111
9112 if(!VOS_IS_STATUS_SUCCESS( status ))
9113 {
9114 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309115 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009116 }
9117 }
9118
9119 pHddCtx->isLogpInProgress = FALSE;
9120 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9121
Amar Singhala49cbc52013-10-08 18:37:44 -07009122#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009123 /* initialize the NV module. This is required so that
9124 we can initialize the channel information in wiphy
9125 from the NV.bin data. The channel information in
9126 wiphy needs to be initialized before wiphy registration */
9127
9128 status = vos_nv_open();
9129 if (!VOS_IS_STATUS_SUCCESS(status))
9130 {
9131 /* NV module cannot be initialized */
9132 hddLog( VOS_TRACE_LEVEL_FATAL,
9133 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309134 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009135 }
9136
9137 status = vos_init_wiphy_from_nv_bin();
9138 if (!VOS_IS_STATUS_SUCCESS(status))
9139 {
9140 /* NV module cannot be initialized */
9141 hddLog( VOS_TRACE_LEVEL_FATAL,
9142 "%s: vos_init_wiphy failed", __func__);
9143 goto err_vos_nv_close;
9144 }
9145
Amar Singhala49cbc52013-10-08 18:37:44 -07009146#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309147 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309148 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009149 if ( !VOS_IS_STATUS_SUCCESS( status ))
9150 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009151 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309152 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009153 }
9154
Jeff Johnson295189b2012-06-20 16:38:30 -07009155 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9156
9157 if ( NULL == pHddCtx->hHal )
9158 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009159 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009160 goto err_vosclose;
9161 }
9162
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009163 status = vos_preStart( pHddCtx->pvosContext );
9164 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9165 {
9166 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309167 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009168 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009169
Arif Hussaineaf68602013-12-30 23:10:44 -08009170 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9171 {
9172 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9173 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9174 __func__, enable_dfs_chan_scan);
9175 }
9176 if (0 == enable_11d || 1 == enable_11d)
9177 {
9178 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9179 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9180 __func__, enable_11d);
9181 }
9182
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009183 /* Note that the vos_preStart() sequence triggers the cfg download.
9184 The cfg download must occur before we update the SME config
9185 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009186 status = hdd_set_sme_config( pHddCtx );
9187
9188 if ( VOS_STATUS_SUCCESS != status )
9189 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009190 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309191 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009192 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009193
Jeff Johnson295189b2012-06-20 16:38:30 -07009194 /* In the integrated architecture we update the configuration from
9195 the INI file and from NV before vOSS has been started so that
9196 the final contents are available to send down to the cCPU */
9197
9198 // Apply the cfg.ini to cfg.dat
9199 if (FALSE == hdd_update_config_dat(pHddCtx))
9200 {
9201 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309202 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009203 }
9204
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309205 // Get mac addr from platform driver
9206 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9207
9208 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009209 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309210 /* Store the mac addr for first interface */
9211 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9212
9213 hddLog(VOS_TRACE_LEVEL_ERROR,
9214 "%s: WLAN Mac Addr: "
9215 MAC_ADDRESS_STR, __func__,
9216 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9217
9218 /* Here, passing Arg2 as 1 because we do not want to change the
9219 last 3 bytes (means non OUI bytes) of first interface mac
9220 addr.
9221 */
9222 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9223 {
9224 hddLog(VOS_TRACE_LEVEL_ERROR,
9225 "%s: Failed to generate wlan interface mac addr "
9226 "using MAC from ini file ", __func__);
9227 }
9228 }
9229 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9230 {
9231 // Apply the NV to cfg.dat
9232 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009233#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9234 /* There was not a valid set of MAC Addresses in NV. See if the
9235 default addresses were modified by the cfg.ini settings. If so,
9236 we'll use them, but if not, we'll autogenerate a set of MAC
9237 addresses based upon the device serial number */
9238
9239 static const v_MACADDR_t default_address =
9240 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009241
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309242 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9243 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009244 {
9245 /* cfg.ini has the default address, invoke autogen logic */
9246
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309247 /* Here, passing Arg2 as 0 because we want to change the
9248 last 3 bytes (means non OUI bytes) of all the interfaces
9249 mac addr.
9250 */
9251 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9252 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009253 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309254 hddLog(VOS_TRACE_LEVEL_ERROR,
9255 "%s: Failed to generate wlan interface mac addr "
9256 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9257 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009258 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009259 }
9260 else
9261#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9262 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009263 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009264 "%s: Invalid MAC address in NV, using MAC from ini file "
9265 MAC_ADDRESS_STR, __func__,
9266 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9267 }
9268 }
9269 {
9270 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309271
9272 /* Set the MAC Address Currently this is used by HAL to
9273 * add self sta. Remove this once self sta is added as
9274 * part of session open.
9275 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009276 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9277 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9278 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309279
Jeff Johnson295189b2012-06-20 16:38:30 -07009280 if (!HAL_STATUS_SUCCESS( halStatus ))
9281 {
9282 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9283 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309284 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009285 }
9286 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009287
9288 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9289 Note: Firmware image will be read and downloaded inside vos_start API */
9290 status = vos_start( pHddCtx->pvosContext );
9291 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9292 {
9293 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309294 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009295 }
9296
Leo Chang6cec3e22014-01-21 15:33:49 -08009297#ifdef FEATURE_WLAN_CH_AVOID
9298 /* Plug in avoid channel notification callback
9299 * This should happen before ADD_SELF_STA
9300 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309301
9302 /* check the Channel Avoidance is enabled */
9303 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9304 {
9305 sme_AddChAvoidCallback(pHddCtx->hHal,
9306 hdd_hostapd_ch_avoid_cb);
9307 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009308#endif /* FEATURE_WLAN_CH_AVOID */
9309
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009310 /* Exchange capability info between Host and FW and also get versioning info from FW */
9311 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009312
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309313#ifdef CONFIG_ENABLE_LINUX_REG
9314 status = wlan_hdd_init_channels(pHddCtx);
9315 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9316 {
9317 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9318 __func__);
9319 goto err_vosstop;
9320 }
9321#endif
9322
Jeff Johnson295189b2012-06-20 16:38:30 -07009323 status = hdd_post_voss_start_config( pHddCtx );
9324 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9325 {
9326 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9327 __func__);
9328 goto err_vosstop;
9329 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009330
9331#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309332 wlan_hdd_cfg80211_update_reg_info( wiphy );
9333
9334 /* registration of wiphy dev with cfg80211 */
9335 if (0 > wlan_hdd_cfg80211_register(wiphy))
9336 {
9337 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9338 goto err_vosstop;
9339 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009340#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009341
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309342#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309343 /* registration of wiphy dev with cfg80211 */
9344 if (0 > wlan_hdd_cfg80211_register(wiphy))
9345 {
9346 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9347 goto err_vosstop;
9348 }
9349
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309350 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309351 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9352 {
9353 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9354 __func__);
9355 goto err_unregister_wiphy;
9356 }
9357#endif
9358
c_hpothu4a298be2014-12-22 21:12:51 +05309359 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9360
Jeff Johnson295189b2012-06-20 16:38:30 -07009361 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9362 {
9363 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9364 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9365 }
9366 else
9367 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009368 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9369 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9370 if (pAdapter != NULL)
9371 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309372 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009373 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309374 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9375 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9376 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009377
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309378 /* Generate the P2P Device Address. This consists of the device's
9379 * primary MAC address with the locally administered bit set.
9380 */
9381 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009382 }
9383 else
9384 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309385 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9386 if (p2p_dev_addr != NULL)
9387 {
9388 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9389 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9390 }
9391 else
9392 {
9393 hddLog(VOS_TRACE_LEVEL_FATAL,
9394 "%s: Failed to allocate mac_address for p2p_device",
9395 __func__);
9396 goto err_close_adapter;
9397 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009398 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009399
9400 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9401 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9402 if ( NULL == pP2pAdapter )
9403 {
9404 hddLog(VOS_TRACE_LEVEL_FATAL,
9405 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009406 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009407 goto err_close_adapter;
9408 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009409 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009410 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009411
9412 if( pAdapter == NULL )
9413 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009414 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9415 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009416 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009417
Arif Hussain66559122013-11-21 10:11:40 -08009418 if (country_code)
9419 {
9420 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009421 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009422 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9423#ifndef CONFIG_ENABLE_LINUX_REG
9424 hdd_checkandupdate_phymode(pAdapter, country_code);
9425#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009426 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9427 (void *)(tSmeChangeCountryCallback)
9428 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009429 country_code,
9430 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309431 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009432 if (eHAL_STATUS_SUCCESS == ret)
9433 {
Arif Hussaincb607082013-12-20 11:57:42 -08009434 ret = wait_for_completion_interruptible_timeout(
9435 &pAdapter->change_country_code,
9436 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9437
9438 if (0 >= ret)
9439 {
9440 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9441 "%s: SME while setting country code timed out", __func__);
9442 }
Arif Hussain66559122013-11-21 10:11:40 -08009443 }
9444 else
9445 {
Arif Hussaincb607082013-12-20 11:57:42 -08009446 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9447 "%s: SME Change Country code from module param fail ret=%d",
9448 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009449 }
9450 }
9451
Jeff Johnson295189b2012-06-20 16:38:30 -07009452#ifdef WLAN_BTAMP_FEATURE
9453 vStatus = WLANBAP_Open(pVosContext);
9454 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9455 {
9456 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9457 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009458 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009459 }
9460
9461 vStatus = BSL_Init(pVosContext);
9462 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9463 {
9464 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9465 "%s: Failed to Init BSL",__func__);
9466 goto err_bap_close;
9467 }
9468 vStatus = WLANBAP_Start(pVosContext);
9469 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9470 {
9471 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9472 "%s: Failed to start TL",__func__);
9473 goto err_bap_close;
9474 }
9475
9476 pConfig = pHddCtx->cfg_ini;
9477 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9478 status = WLANBAP_SetConfig(&btAmpConfig);
9479
9480#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009481
Mihir Shete9c238772014-10-15 14:35:16 +05309482 /*
9483 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9484 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9485 * which is greater than 0xf. So the below check is safe to make
9486 * sure that there is no entry for UapsdMask in the ini
9487 */
9488 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9489 {
9490 if(IS_DYNAMIC_WMM_PS_ENABLED)
9491 {
9492 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9493 __func__);
9494 pHddCtx->cfg_ini->UapsdMask =
9495 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
9496 }
9497 else
9498 {
9499 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
9500 __func__);
9501 pHddCtx->cfg_ini->UapsdMask =
9502 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
9503 }
9504 }
9505
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07009506#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
9507 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
9508 {
9509 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
9510 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
9511 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
9512 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
9513 }
9514#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009515
Agarwal Ashish4b87f922014-06-18 03:03:21 +05309516 wlan_hdd_tdls_init(pHddCtx);
9517
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309518 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
9519
Jeff Johnson295189b2012-06-20 16:38:30 -07009520 /* Register with platform driver as client for Suspend/Resume */
9521 status = hddRegisterPmOps(pHddCtx);
9522 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9523 {
9524 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
9525#ifdef WLAN_BTAMP_FEATURE
9526 goto err_bap_stop;
9527#else
Jeff Johnsone7245742012-09-05 17:12:55 -07009528 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009529#endif //WLAN_BTAMP_FEATURE
9530 }
9531
Yue Ma0d4891e2013-08-06 17:01:45 -07009532 /* Open debugfs interface */
9533 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
9534 {
9535 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9536 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07009537 }
9538
Jeff Johnson295189b2012-06-20 16:38:30 -07009539 /* Register TM level change handler function to the platform */
9540 status = hddDevTmRegisterNotifyCallback(pHddCtx);
9541 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9542 {
9543 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
9544 goto err_unregister_pmops;
9545 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009546
9547 /* register for riva power on lock to platform driver */
9548 if (req_riva_power_on_lock("wlan"))
9549 {
9550 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9551 __func__);
9552 goto err_unregister_pmops;
9553 }
9554
Jeff Johnson295189b2012-06-20 16:38:30 -07009555 // register net device notifier for device change notification
9556 ret = register_netdevice_notifier(&hdd_netdev_notifier);
9557
9558 if(ret < 0)
9559 {
9560 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
9561 goto err_free_power_on_lock;
9562 }
9563
9564 //Initialize the nlink service
9565 if(nl_srv_init() != 0)
9566 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309567 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009568 goto err_reg_netdev;
9569 }
9570
Leo Chang4ce1cc52013-10-21 18:27:15 -07009571#ifdef WLAN_KD_READY_NOTIFIER
9572 pHddCtx->kd_nl_init = 1;
9573#endif /* WLAN_KD_READY_NOTIFIER */
9574
Jeff Johnson295189b2012-06-20 16:38:30 -07009575 //Initialize the BTC service
9576 if(btc_activate_service(pHddCtx) != 0)
9577 {
9578 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
9579 goto err_nl_srv;
9580 }
9581
9582#ifdef PTT_SOCK_SVC_ENABLE
9583 //Initialize the PTT service
9584 if(ptt_sock_activate_svc(pHddCtx) != 0)
9585 {
9586 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
9587 goto err_nl_srv;
9588 }
9589#endif
9590
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309591#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9592 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
9593 {
Deepthi Gowri78083a32014-11-04 12:55:51 +05309594 if(wlan_logging_sock_activate_svc(
9595 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
9596 pHddCtx->cfg_ini->wlanLoggingNumBuf))
9597 {
9598 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
9599 " failed", __func__);
9600 goto err_nl_srv;
9601 }
9602 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
9603 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +05309604 if (!pHddCtx->cfg_ini->gEnableDebugLog)
9605 pHddCtx->cfg_ini->gEnableDebugLog =
9606 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309607 }
9608#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009609 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009610 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009611 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07009612 /* Action frame registered in one adapter which will
9613 * applicable to all interfaces
9614 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309615 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009616 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009617
9618 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +05309619 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009620
Jeff Johnson295189b2012-06-20 16:38:30 -07009621
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009622#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07009623#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
9624 /* Initialize the wake lcok */
9625 wake_lock_init(&pHddCtx->rx_wake_lock,
9626 WAKE_LOCK_SUSPEND,
9627 "qcom_rx_wakelock");
9628#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08009629 /* Initialize the wake lcok */
9630 wake_lock_init(&pHddCtx->sap_wake_lock,
9631 WAKE_LOCK_SUSPEND,
9632 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009633#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009634
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009635 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
9636 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07009637
Katya Nigam5c306ea2014-06-19 15:39:54 +05309638 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009639 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9640 hdd_allow_suspend();
Katya Nigam5c306ea2014-06-19 15:39:54 +05309641
9642#ifdef FEATURE_WLAN_SCAN_PNO
9643 /*SME must send channel update configuration to RIVA*/
9644 sme_UpdateChannelConfig(pHddCtx->hHal);
9645#endif
Abhishek Singhf644b272014-08-21 02:59:39 +05309646 /* Send the update default channel list to the FW*/
9647 sme_UpdateChannelList(pHddCtx->hHal);
Abhishek Singha306a442013-11-07 18:39:01 +05309648#ifndef CONFIG_ENABLE_LINUX_REG
9649 /*updating wiphy so that regulatory user hints can be processed*/
9650 if (wiphy)
9651 {
9652 regulatory_hint(wiphy, "00");
9653 }
9654#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009655 // Initialize the restart logic
9656 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05309657
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07009658 //Register the traffic monitor timer now
9659 if ( pHddCtx->cfg_ini->dynSplitscan)
9660 {
9661 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
9662 VOS_TIMER_TYPE_SW,
9663 hdd_tx_rx_pkt_cnt_stat_timer_handler,
9664 (void *)pHddCtx);
9665 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05309666#ifdef WLAN_FEATURE_EXTSCAN
9667 sme_EXTScanRegisterCallback(pHddCtx->hHal,
9668 wlan_hdd_cfg80211_extscan_callback,
9669 pHddCtx);
9670#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309671
9672#ifdef WLAN_NS_OFFLOAD
9673 // Register IPv6 notifier to notify if any change in IP
9674 // So that we can reconfigure the offload parameters
9675 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
9676 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
9677 if (ret)
9678 {
9679 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
9680 }
9681 else
9682 {
9683 hddLog(LOGE, FL("Registered IPv6 notifier"));
9684 }
9685#endif
9686
9687 // Register IPv4 notifier to notify if any change in IP
9688 // So that we can reconfigure the offload parameters
9689 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
9690 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
9691 if (ret)
9692 {
9693 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
9694 }
9695 else
9696 {
9697 hddLog(LOGE, FL("Registered IPv4 notifier"));
9698 }
9699
Jeff Johnson295189b2012-06-20 16:38:30 -07009700 goto success;
9701
9702err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07009703#ifdef WLAN_KD_READY_NOTIFIER
9704 nl_srv_exit(pHddCtx->ptt_pid);
9705#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009706 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07009707#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07009708err_reg_netdev:
9709 unregister_netdevice_notifier(&hdd_netdev_notifier);
9710
9711err_free_power_on_lock:
9712 free_riva_power_on_lock("wlan");
9713
9714err_unregister_pmops:
9715 hddDevTmUnregisterNotifyCallback(pHddCtx);
9716 hddDeregisterPmOps(pHddCtx);
9717
Yue Ma0d4891e2013-08-06 17:01:45 -07009718 hdd_debugfs_exit(pHddCtx);
9719
Jeff Johnson295189b2012-06-20 16:38:30 -07009720#ifdef WLAN_BTAMP_FEATURE
9721err_bap_stop:
9722 WLANBAP_Stop(pVosContext);
9723#endif
9724
9725#ifdef WLAN_BTAMP_FEATURE
9726err_bap_close:
9727 WLANBAP_Close(pVosContext);
9728#endif
9729
Jeff Johnson295189b2012-06-20 16:38:30 -07009730err_close_adapter:
9731 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309732#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309733err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309734#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309735 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009736err_vosstop:
9737 vos_stop(pVosContext);
9738
Amar Singhala49cbc52013-10-08 18:37:44 -07009739err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07009740 status = vos_sched_close( pVosContext );
9741 if (!VOS_IS_STATUS_SUCCESS(status)) {
9742 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9743 "%s: Failed to close VOSS Scheduler", __func__);
9744 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9745 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009746 vos_close(pVosContext );
9747
Amar Singhal0a402232013-10-11 20:57:16 -07009748err_vos_nv_close:
9749
c_hpothue6a36282014-03-19 12:27:38 +05309750#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009751 vos_nv_close();
9752
c_hpothu70f8d812014-03-22 22:59:23 +05309753#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009754
9755err_wdclose:
9756 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9757 vos_watchdog_close(pVosContext);
9758
Jeff Johnson295189b2012-06-20 16:38:30 -07009759err_config:
9760 kfree(pHddCtx->cfg_ini);
9761 pHddCtx->cfg_ini= NULL;
9762
9763err_free_hdd_context:
9764 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009765 wiphy_free(wiphy) ;
9766 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009767 VOS_BUG(1);
9768
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009769 if (hdd_is_ssr_required())
9770 {
9771 /* WDI timeout had happened during load, so SSR is needed here */
9772 subsystem_restart("wcnss");
9773 msleep(5000);
9774 }
9775 hdd_set_ssr_required (VOS_FALSE);
9776
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009777 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009778
9779success:
9780 EXIT();
9781 return 0;
9782}
9783
9784/**---------------------------------------------------------------------------
9785
Jeff Johnson32d95a32012-09-10 13:15:23 -07009786 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009787
Jeff Johnson32d95a32012-09-10 13:15:23 -07009788 This is the driver entry point - called in different timeline depending
9789 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009790
9791 \param - None
9792
9793 \return - 0 for success, non zero for failure
9794
9795 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009796static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009797{
9798 VOS_STATUS status;
9799 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009800 struct device *dev = NULL;
9801 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009802#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9803 int max_retries = 0;
9804#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05309805#ifdef HAVE_CBC_DONE
9806 int max_cbc_retries = 0;
9807#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009808
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309809#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9810 wlan_logging_sock_init_svc();
9811#endif
9812
Jeff Johnson295189b2012-06-20 16:38:30 -07009813 ENTER();
9814
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009815#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009816 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009817#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009818
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309819 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009820 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9821 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9822
Jeff Johnson295189b2012-06-20 16:38:30 -07009823#ifdef ANI_BUS_TYPE_PCI
9824
9825 dev = wcnss_wlan_get_device();
9826
9827#endif // ANI_BUS_TYPE_PCI
9828
9829#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009830
9831#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9832 /* wait until WCNSS driver downloads NV */
9833 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9834 msleep(1000);
9835 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05309836
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009837 if (max_retries >= 5) {
9838 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309839#ifdef WLAN_OPEN_SOURCE
9840 wake_lock_destroy(&wlan_wake_lock);
9841#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309842
9843#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9844 wlan_logging_sock_deinit_svc();
9845#endif
9846
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009847 return -ENODEV;
9848 }
9849#endif
9850
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05309851#ifdef HAVE_CBC_DONE
9852 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
9853 msleep(1000);
9854 }
9855 if (max_cbc_retries >= 10) {
9856 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
9857 }
9858#endif
9859
Jeff Johnson295189b2012-06-20 16:38:30 -07009860 dev = wcnss_wlan_get_device();
9861#endif // ANI_BUS_TYPE_PLATFORM
9862
9863
9864 do {
9865 if (NULL == dev) {
9866 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9867 ret_status = -1;
9868 break;
9869 }
9870
Jeff Johnson295189b2012-06-20 16:38:30 -07009871#ifdef TIMER_MANAGER
9872 vos_timer_manager_init();
9873#endif
9874
9875 /* Preopen VOSS so that it is ready to start at least SAL */
9876 status = vos_preOpen(&pVosContext);
9877
9878 if (!VOS_IS_STATUS_SUCCESS(status))
9879 {
9880 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9881 ret_status = -1;
9882 break;
9883 }
9884
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009885#ifndef MODULE
9886 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9887 */
9888 hdd_set_conparam((v_UINT_t)con_mode);
9889#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009890
9891 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009892 if (hdd_wlan_startup(dev))
9893 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009894 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009895 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009896 vos_preClose( &pVosContext );
9897 ret_status = -1;
9898 break;
9899 }
9900
Jeff Johnson295189b2012-06-20 16:38:30 -07009901 } while (0);
9902
9903 if (0 != ret_status)
9904 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009905#ifdef TIMER_MANAGER
9906 vos_timer_exit();
9907#endif
9908#ifdef MEMORY_DEBUG
9909 vos_mem_exit();
9910#endif
9911
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009912#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009913 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009914#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309915
9916#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9917 wlan_logging_sock_deinit_svc();
9918#endif
9919
Jeff Johnson295189b2012-06-20 16:38:30 -07009920 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9921 }
9922 else
9923 {
9924 //Send WLAN UP indication to Nlink Service
9925 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9926
9927 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009928 }
9929
9930 EXIT();
9931
9932 return ret_status;
9933}
9934
Jeff Johnson32d95a32012-09-10 13:15:23 -07009935/**---------------------------------------------------------------------------
9936
9937 \brief hdd_module_init() - Init Function
9938
9939 This is the driver entry point (invoked when module is loaded using insmod)
9940
9941 \param - None
9942
9943 \return - 0 for success, non zero for failure
9944
9945 --------------------------------------------------------------------------*/
9946#ifdef MODULE
9947static int __init hdd_module_init ( void)
9948{
9949 return hdd_driver_init();
9950}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009951#else /* #ifdef MODULE */
9952static int __init hdd_module_init ( void)
9953{
9954 /* Driver initialization is delayed to fwpath_changed_handler */
9955 return 0;
9956}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009957#endif /* #ifdef MODULE */
9958
Jeff Johnson295189b2012-06-20 16:38:30 -07009959
9960/**---------------------------------------------------------------------------
9961
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009962 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009963
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009964 This is the driver exit point (invoked when module is unloaded using rmmod
9965 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009966
9967 \param - None
9968
9969 \return - None
9970
9971 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009972static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009973{
9974 hdd_context_t *pHddCtx = NULL;
9975 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +05309976 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309977 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009978
9979 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9980
9981 //Get the global vos context
9982 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9983
9984 if(!pVosContext)
9985 {
9986 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
9987 goto done;
9988 }
9989
9990 //Get the HDD context.
9991 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
9992
9993 if(!pHddCtx)
9994 {
9995 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
9996 }
9997 else
9998 {
Siddharth Bhal3c29dca2015-02-19 00:41:40 +05309999 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10000 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10001 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10002 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010004 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010005 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10006 msecs_to_jiffies(30000));
10007 if(!rc)
10008 {
10009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10010 "%s:SSR timedout, fatal error", __func__);
10011 VOS_BUG(0);
10012 }
10013 }
10014
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053010015 rtnl_lock();
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010016 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10017 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053010018 rtnl_unlock();
Jeff Johnson295189b2012-06-20 16:38:30 -070010019
c_hpothu8adb97b2014-12-08 19:38:20 +053010020 /* Driver Need to send country code 00 in below condition
10021 * 1) If gCountryCodePriority is set to 1; and last country
10022 * code set is through 11d. This needs to be done in case
10023 * when NV country code is 00.
10024 * This Needs to be done as when kernel store last country
10025 * code and if stored country code is not through 11d,
10026 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10027 * in next load/unload as soon as we get any country through
10028 * 11d. In sme_HandleChangeCountryCodeByUser
10029 * pMsg->countryCode will be last countryCode and
10030 * pMac->scan.countryCode11d will be country through 11d so
10031 * due to mismatch driver will disable 11d.
10032 *
10033 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010034
c_hpothu8adb97b2014-12-08 19:38:20 +053010035 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010036 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010037 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010038 {
10039 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010040 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010041 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10042 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010043
c_hpothu8adb97b2014-12-08 19:38:20 +053010044 //Do all the cleanup before deregistering the driver
10045 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010046 }
10047
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 vos_preClose( &pVosContext );
10049
10050#ifdef TIMER_MANAGER
10051 vos_timer_exit();
10052#endif
10053#ifdef MEMORY_DEBUG
10054 vos_mem_exit();
10055#endif
10056
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010057#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10058 wlan_logging_sock_deinit_svc();
10059#endif
10060
Jeff Johnson295189b2012-06-20 16:38:30 -070010061done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -080010062#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -070010063 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070010064#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010065
Jeff Johnson295189b2012-06-20 16:38:30 -070010066 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10067}
10068
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010069/**---------------------------------------------------------------------------
10070
10071 \brief hdd_module_exit() - Exit function
10072
10073 This is the driver exit point (invoked when module is unloaded using rmmod)
10074
10075 \param - None
10076
10077 \return - None
10078
10079 --------------------------------------------------------------------------*/
10080static void __exit hdd_module_exit(void)
10081{
10082 hdd_driver_exit();
10083}
10084
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010085#ifdef MODULE
10086static int fwpath_changed_handler(const char *kmessage,
10087 struct kernel_param *kp)
10088{
Jeff Johnson76052702013-04-16 13:55:05 -070010089 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010090}
10091
10092static int con_mode_handler(const char *kmessage,
10093 struct kernel_param *kp)
10094{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010095 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010096}
10097#else /* #ifdef MODULE */
10098/**---------------------------------------------------------------------------
10099
Jeff Johnson76052702013-04-16 13:55:05 -070010100 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010101
Jeff Johnson76052702013-04-16 13:55:05 -070010102 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010103 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010104 - invoked when module parameter fwpath is modified from userspace to signal
10105 initializing the WLAN driver or when con_mode is modified from userspace
10106 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010107
10108 \return - 0 for success, non zero for failure
10109
10110 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010111static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010112{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010113 int ret_status;
10114
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010115 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010116 ret_status = hdd_driver_init();
10117 wlan_hdd_inited = ret_status ? 0 : 1;
10118 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010119 }
10120
10121 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010122
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010123 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010124
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010125 ret_status = hdd_driver_init();
10126 wlan_hdd_inited = ret_status ? 0 : 1;
10127 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010128}
10129
Jeff Johnson295189b2012-06-20 16:38:30 -070010130/**---------------------------------------------------------------------------
10131
Jeff Johnson76052702013-04-16 13:55:05 -070010132 \brief fwpath_changed_handler() - Handler Function
10133
10134 Handle changes to the fwpath parameter
10135
10136 \return - 0 for success, non zero for failure
10137
10138 --------------------------------------------------------------------------*/
10139static int fwpath_changed_handler(const char *kmessage,
10140 struct kernel_param *kp)
10141{
10142 int ret;
10143
10144 ret = param_set_copystring(kmessage, kp);
10145 if (0 == ret)
10146 ret = kickstart_driver();
10147 return ret;
10148}
10149
10150/**---------------------------------------------------------------------------
10151
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010152 \brief con_mode_handler() -
10153
10154 Handler function for module param con_mode when it is changed by userspace
10155 Dynamically linked - do nothing
10156 Statically linked - exit and init driver, as in rmmod and insmod
10157
Jeff Johnson76052702013-04-16 13:55:05 -070010158 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010159
Jeff Johnson76052702013-04-16 13:55:05 -070010160 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010161
10162 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010163static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010164{
Jeff Johnson76052702013-04-16 13:55:05 -070010165 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010166
Jeff Johnson76052702013-04-16 13:55:05 -070010167 ret = param_set_int(kmessage, kp);
10168 if (0 == ret)
10169 ret = kickstart_driver();
10170 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010171}
10172#endif /* #ifdef MODULE */
10173
10174/**---------------------------------------------------------------------------
10175
Jeff Johnson295189b2012-06-20 16:38:30 -070010176 \brief hdd_get_conparam() -
10177
10178 This is the driver exit point (invoked when module is unloaded using rmmod)
10179
10180 \param - None
10181
10182 \return - tVOS_CON_MODE
10183
10184 --------------------------------------------------------------------------*/
10185tVOS_CON_MODE hdd_get_conparam ( void )
10186{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010187#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010188 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010189#else
10190 return (tVOS_CON_MODE)curr_con_mode;
10191#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010192}
10193void hdd_set_conparam ( v_UINT_t newParam )
10194{
10195 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010196#ifndef MODULE
10197 curr_con_mode = con_mode;
10198#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010199}
10200/**---------------------------------------------------------------------------
10201
10202 \brief hdd_softap_sta_deauth() - function
10203
10204 This to take counter measure to handle deauth req from HDD
10205
10206 \param - pAdapter - Pointer to the HDD
10207
10208 \param - enable - boolean value
10209
10210 \return - None
10211
10212 --------------------------------------------------------------------------*/
10213
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010214VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10215 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010216{
Jeff Johnson295189b2012-06-20 16:38:30 -070010217 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010218 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010219
10220 ENTER();
10221
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010222 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10223 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010224
10225 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010226 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010227 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010228
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010229 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010230
10231 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010232 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010233}
10234
10235/**---------------------------------------------------------------------------
10236
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010237 \brief hdd_del_all_sta() - function
10238
10239 This function removes all the stations associated on stopping AP/P2P GO.
10240
10241 \param - pAdapter - Pointer to the HDD
10242
10243 \return - None
10244
10245 --------------------------------------------------------------------------*/
10246
10247int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10248{
10249 v_U16_t i;
10250 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010251 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10252 ptSapContext pSapCtx = NULL;
10253 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10254 if(pSapCtx == NULL){
10255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10256 FL("psapCtx is NULL"));
10257 return 1;
10258 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010259 ENTER();
10260
10261 hddLog(VOS_TRACE_LEVEL_INFO,
10262 "%s: Delete all STAs associated.",__func__);
10263 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10264 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10265 )
10266 {
10267 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10268 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010269 if ((pSapCtx->aStaInfo[i].isUsed) &&
10270 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010271 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010272 struct tagCsrDelStaParams delStaParams;
10273
10274 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010275 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010276 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10277 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010278 &delStaParams);
10279 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010280 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010281 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010282 }
10283 }
10284 }
10285
10286 EXIT();
10287 return 0;
10288}
10289
10290/**---------------------------------------------------------------------------
10291
Jeff Johnson295189b2012-06-20 16:38:30 -070010292 \brief hdd_softap_sta_disassoc() - function
10293
10294 This to take counter measure to handle deauth req from HDD
10295
10296 \param - pAdapter - Pointer to the HDD
10297
10298 \param - enable - boolean value
10299
10300 \return - None
10301
10302 --------------------------------------------------------------------------*/
10303
10304void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10305{
10306 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10307
10308 ENTER();
10309
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010310 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010311
10312 //Ignore request to disassoc bcmc station
10313 if( pDestMacAddress[0] & 0x1 )
10314 return;
10315
10316 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10317}
10318
10319void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10320{
10321 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10322
10323 ENTER();
10324
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010325 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010326
10327 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10328}
10329
Jeff Johnson295189b2012-06-20 16:38:30 -070010330/**---------------------------------------------------------------------------
10331 *
10332 * \brief hdd_get__concurrency_mode() -
10333 *
10334 *
10335 * \param - None
10336 *
10337 * \return - CONCURRENCY MODE
10338 *
10339 * --------------------------------------------------------------------------*/
10340tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10341{
10342 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10343 hdd_context_t *pHddCtx;
10344
10345 if (NULL != pVosContext)
10346 {
10347 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10348 if (NULL != pHddCtx)
10349 {
10350 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10351 }
10352 }
10353
10354 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010355 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010356 return VOS_STA;
10357}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010358v_BOOL_t
10359wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10360{
10361 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010362
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010363 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10364 if (pAdapter == NULL)
10365 {
10366 hddLog(VOS_TRACE_LEVEL_INFO,
10367 FL("GO doesn't exist"));
10368 return TRUE;
10369 }
10370 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10371 {
10372 hddLog(VOS_TRACE_LEVEL_INFO,
10373 FL("GO started"));
10374 return TRUE;
10375 }
10376 else
10377 /* wait till GO changes its interface to p2p device */
10378 hddLog(VOS_TRACE_LEVEL_INFO,
10379 FL("Del_bss called, avoid apps suspend"));
10380 return FALSE;
10381
10382}
Jeff Johnson295189b2012-06-20 16:38:30 -070010383/* Decide whether to allow/not the apps power collapse.
10384 * Allow apps power collapse if we are in connected state.
10385 * if not, allow only if we are in IMPS */
10386v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10387{
10388 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010389 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010390 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010391 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10392 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10393 hdd_adapter_t *pAdapter = NULL;
10394 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010395 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010396
Jeff Johnson295189b2012-06-20 16:38:30 -070010397 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10398 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010399
Yathish9f22e662012-12-10 14:21:35 -080010400 concurrent_state = hdd_get_concurrency_mode();
10401
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010402 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10403 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10404 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010405#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010406
Yathish9f22e662012-12-10 14:21:35 -080010407 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010408 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010409 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10410 return TRUE;
10411#endif
10412
Jeff Johnson295189b2012-06-20 16:38:30 -070010413 /*loop through all adapters. TBD fix for Concurrency */
10414 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10415 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10416 {
10417 pAdapter = pAdapterNode->pAdapter;
10418 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10419 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10420 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010421 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010422 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010423 && pmcState != STOPPED && pmcState != STANDBY &&
10424 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010425 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10426 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010427 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010428 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010429 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10430 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010431 return FALSE;
10432 }
10433 }
10434 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10435 pAdapterNode = pNext;
10436 }
10437 return TRUE;
10438}
10439
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010440/* Decides whether to send suspend notification to Riva
10441 * if any adapter is in BMPS; then it is required */
10442v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10443{
10444 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10445 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10446
10447 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10448 {
10449 return TRUE;
10450 }
10451 return FALSE;
10452}
10453
Jeff Johnson295189b2012-06-20 16:38:30 -070010454void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10455{
10456 switch(mode)
10457 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010458 case VOS_STA_MODE:
10459 case VOS_P2P_CLIENT_MODE:
10460 case VOS_P2P_GO_MODE:
10461 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010462 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010463 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010464 break;
10465 default:
10466 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010467 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010468 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10469 "Number of open sessions for mode %d = %d"),
10470 pHddCtx->concurrency_mode, mode,
10471 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010472}
10473
10474
10475void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10476{
10477 switch(mode)
10478 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010479 case VOS_STA_MODE:
10480 case VOS_P2P_CLIENT_MODE:
10481 case VOS_P2P_GO_MODE:
10482 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053010483 pHddCtx->no_of_open_sessions[mode]--;
10484 if (!(pHddCtx->no_of_open_sessions[mode]))
10485 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070010486 break;
10487 default:
10488 break;
10489 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010490 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10491 "Number of open sessions for mode %d = %d"),
10492 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
10493
10494}
10495/**---------------------------------------------------------------------------
10496 *
10497 * \brief wlan_hdd_incr_active_session()
10498 *
10499 * This function increments the number of active sessions
10500 * maintained per device mode
10501 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
10502 * Incase of SAP/P2P GO upon bss start it is incremented
10503 *
10504 * \param pHddCtx - HDD Context
10505 * \param mode - device mode
10506 *
10507 * \return - None
10508 *
10509 * --------------------------------------------------------------------------*/
10510void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10511{
10512 switch (mode) {
10513 case VOS_STA_MODE:
10514 case VOS_P2P_CLIENT_MODE:
10515 case VOS_P2P_GO_MODE:
10516 case VOS_STA_SAP_MODE:
10517 pHddCtx->no_of_active_sessions[mode]++;
10518 break;
10519 default:
10520 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10521 break;
10522 }
10523 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10524 mode,
10525 pHddCtx->no_of_active_sessions[mode]);
10526}
10527
10528/**---------------------------------------------------------------------------
10529 *
10530 * \brief wlan_hdd_decr_active_session()
10531 *
10532 * This function decrements the number of active sessions
10533 * maintained per device mode
10534 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
10535 * Incase of SAP/P2P GO upon bss stop it is decremented
10536 *
10537 * \param pHddCtx - HDD Context
10538 * \param mode - device mode
10539 *
10540 * \return - None
10541 *
10542 * --------------------------------------------------------------------------*/
10543void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10544{
10545 switch (mode) {
10546 case VOS_STA_MODE:
10547 case VOS_P2P_CLIENT_MODE:
10548 case VOS_P2P_GO_MODE:
10549 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053010550 if (pHddCtx->no_of_active_sessions[mode] > 0)
10551 pHddCtx->no_of_active_sessions[mode]--;
10552 else
10553 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
10554 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053010555 break;
10556 default:
10557 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10558 break;
10559 }
10560 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10561 mode,
10562 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010563}
10564
Jeff Johnsone7245742012-09-05 17:12:55 -070010565/**---------------------------------------------------------------------------
10566 *
10567 * \brief wlan_hdd_restart_init
10568 *
10569 * This function initalizes restart timer/flag. An internal function.
10570 *
10571 * \param - pHddCtx
10572 *
10573 * \return - None
10574 *
10575 * --------------------------------------------------------------------------*/
10576
10577static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
10578{
10579 /* Initialize */
10580 pHddCtx->hdd_restart_retries = 0;
10581 atomic_set(&pHddCtx->isRestartInProgress, 0);
10582 vos_timer_init(&pHddCtx->hdd_restart_timer,
10583 VOS_TIMER_TYPE_SW,
10584 wlan_hdd_restart_timer_cb,
10585 pHddCtx);
10586}
10587/**---------------------------------------------------------------------------
10588 *
10589 * \brief wlan_hdd_restart_deinit
10590 *
10591 * This function cleans up the resources used. An internal function.
10592 *
10593 * \param - pHddCtx
10594 *
10595 * \return - None
10596 *
10597 * --------------------------------------------------------------------------*/
10598
10599static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
10600{
10601
10602 VOS_STATUS vos_status;
10603 /* Block any further calls */
10604 atomic_set(&pHddCtx->isRestartInProgress, 1);
10605 /* Cleanup */
10606 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
10607 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010608 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010609 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
10610 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010611 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010612
10613}
10614
10615/**---------------------------------------------------------------------------
10616 *
10617 * \brief wlan_hdd_framework_restart
10618 *
10619 * This function uses a cfg80211 API to start a framework initiated WLAN
10620 * driver module unload/load.
10621 *
10622 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
10623 *
10624 *
10625 * \param - pHddCtx
10626 *
10627 * \return - VOS_STATUS_SUCCESS: Success
10628 * VOS_STATUS_E_EMPTY: Adapter is Empty
10629 * VOS_STATUS_E_NOMEM: No memory
10630
10631 * --------------------------------------------------------------------------*/
10632
10633static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
10634{
10635 VOS_STATUS status = VOS_STATUS_SUCCESS;
10636 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010637 int len = (sizeof (struct ieee80211_mgmt));
10638 struct ieee80211_mgmt *mgmt = NULL;
10639
10640 /* Prepare the DEAUTH managment frame with reason code */
10641 mgmt = kzalloc(len, GFP_KERNEL);
10642 if(mgmt == NULL)
10643 {
10644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10645 "%s: memory allocation failed (%d bytes)", __func__, len);
10646 return VOS_STATUS_E_NOMEM;
10647 }
10648 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070010649
10650 /* Iterate over all adapters/devices */
10651 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10652 do
10653 {
10654 if( (status == VOS_STATUS_SUCCESS) &&
10655 pAdapterNode &&
10656 pAdapterNode->pAdapter)
10657 {
10658 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10659 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
10660 pAdapterNode->pAdapter->dev->name,
10661 pAdapterNode->pAdapter->device_mode,
10662 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010663 /*
10664 * CFG80211 event to restart the driver
10665 *
10666 * 'cfg80211_send_unprot_deauth' sends a
10667 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
10668 * of SME(Linux Kernel) state machine.
10669 *
10670 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
10671 * the driver.
10672 *
10673 */
10674
10675 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070010676 }
10677 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10678 pAdapterNode = pNext;
10679 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
10680
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010681
10682 /* Free the allocated management frame */
10683 kfree(mgmt);
10684
Jeff Johnsone7245742012-09-05 17:12:55 -070010685 /* Retry until we unload or reach max count */
10686 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
10687 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
10688
10689 return status;
10690
10691}
10692/**---------------------------------------------------------------------------
10693 *
10694 * \brief wlan_hdd_restart_timer_cb
10695 *
10696 * Restart timer callback. An internal function.
10697 *
10698 * \param - User data:
10699 *
10700 * \return - None
10701 *
10702 * --------------------------------------------------------------------------*/
10703
10704void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
10705{
10706 hdd_context_t *pHddCtx = usrDataForCallback;
10707 wlan_hdd_framework_restart(pHddCtx);
10708 return;
10709
10710}
10711
10712
10713/**---------------------------------------------------------------------------
10714 *
10715 * \brief wlan_hdd_restart_driver
10716 *
10717 * This function sends an event to supplicant to restart the WLAN driver.
10718 *
10719 * This function is called from vos_wlanRestart.
10720 *
10721 * \param - pHddCtx
10722 *
10723 * \return - VOS_STATUS_SUCCESS: Success
10724 * VOS_STATUS_E_EMPTY: Adapter is Empty
10725 * VOS_STATUS_E_ALREADY: Request already in progress
10726
10727 * --------------------------------------------------------------------------*/
10728VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
10729{
10730 VOS_STATUS status = VOS_STATUS_SUCCESS;
10731
10732 /* A tight check to make sure reentrancy */
10733 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
10734 {
Mihir Shetefd528652014-06-23 19:07:50 +053010735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070010736 "%s: WLAN restart is already in progress", __func__);
10737
10738 return VOS_STATUS_E_ALREADY;
10739 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070010740 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080010741#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070010742 wcnss_reset_intr();
10743#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010744
Jeff Johnsone7245742012-09-05 17:12:55 -070010745 return status;
10746}
10747
Mihir Shetee1093ba2014-01-21 20:13:32 +053010748/**---------------------------------------------------------------------------
10749 *
10750 * \brief wlan_hdd_init_channels
10751 *
10752 * This function is used to initialize the channel list in CSR
10753 *
10754 * This function is called from hdd_wlan_startup
10755 *
10756 * \param - pHddCtx: HDD context
10757 *
10758 * \return - VOS_STATUS_SUCCESS: Success
10759 * VOS_STATUS_E_FAULT: Failure reported by SME
10760
10761 * --------------------------------------------------------------------------*/
10762static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
10763{
10764 eHalStatus status;
10765
10766 status = sme_InitChannels(pHddCtx->hHal);
10767 if (HAL_STATUS_SUCCESS(status))
10768 {
10769 return VOS_STATUS_SUCCESS;
10770 }
10771 else
10772 {
10773 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
10774 __func__, status);
10775 return VOS_STATUS_E_FAULT;
10776 }
10777}
10778
Mihir Shete04206452014-11-20 17:50:58 +053010779#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010780VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010781{
10782 eHalStatus status;
10783
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010784 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010785 if (HAL_STATUS_SUCCESS(status))
10786 {
10787 return VOS_STATUS_SUCCESS;
10788 }
10789 else
10790 {
10791 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
10792 __func__, status);
10793 return VOS_STATUS_E_FAULT;
10794 }
10795}
Mihir Shete04206452014-11-20 17:50:58 +053010796#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070010797/*
10798 * API to find if there is any STA or P2P-Client is connected
10799 */
10800VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
10801{
10802 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
10803}
Jeff Johnsone7245742012-09-05 17:12:55 -070010804
Agarwal Ashish57e84372014-12-05 18:26:53 +053010805/*
10806 * API to find if there is any session connected
10807 */
10808VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
10809{
10810 return sme_is_any_session_connected(pHddCtx->hHal);
10811}
10812
10813
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010814int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
10815{
10816 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10817 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053010818 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053010819 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010820
10821 pScanInfo = &pHddCtx->scan_info;
10822 if (pScanInfo->mScanPending)
10823 {
c_hpothua3d45d52015-01-05 14:11:17 +053010824 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
10825 eCSR_SCAN_ABORT_DEFAULT);
10826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10827 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010828
c_hpothua3d45d52015-01-05 14:11:17 +053010829 /* If there is active scan command lets wait for the completion else
10830 * there is no need to wait as scan command might be in the SME pending
10831 * command list.
10832 */
10833 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
10834 {
10835 INIT_COMPLETION(pScanInfo->abortscan_event_var);
10836 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010837 &pScanInfo->abortscan_event_var,
10838 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053010839 if (0 >= status)
10840 {
10841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053010842 "%s: Timeout or Interrupt occurred while waiting for abort"
10843 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053010844 return -ETIMEDOUT;
10845 }
10846 }
10847 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
10848 {
10849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10850 FL("hdd_abort_mac_scan failed"));
10851 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010852 }
10853 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053010854 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010855}
10856
c_hpothu225aa7c2014-10-22 17:45:13 +053010857VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
10858{
10859 hdd_adapter_t *pAdapter;
10860 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10861 VOS_STATUS vosStatus;
10862
10863 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10864 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
10865 {
10866 pAdapter = pAdapterNode->pAdapter;
10867 if (NULL != pAdapter)
10868 {
10869 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
10870 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
10871 WLAN_HDD_P2P_GO == pAdapter->device_mode)
10872 {
10873 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
10874 pAdapter->device_mode);
10875 if (VOS_STATUS_SUCCESS !=
10876 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
10877 {
10878 hddLog(LOGE, FL("failed to abort ROC"));
10879 return VOS_STATUS_E_FAILURE;
10880 }
10881 }
10882 }
10883 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10884 pAdapterNode = pNext;
10885 }
10886 return VOS_STATUS_SUCCESS;
10887}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053010888
Mihir Shete0be28772015-02-17 18:42:14 +053010889hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
10890{
10891 hdd_adapter_t *pAdapter;
10892 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10893 hdd_cfg80211_state_t *cfgState;
10894 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
10895 VOS_STATUS vosStatus;
10896
10897 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
10898 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
10899 {
10900 pAdapter = pAdapterNode->pAdapter;
10901 if (NULL != pAdapter)
10902 {
10903 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
10904 pRemainChanCtx = cfgState->remain_on_chan_ctx;
10905 if (pRemainChanCtx)
10906 break;
10907 }
10908 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
10909 pAdapterNode = pNext;
10910 }
10911 return pRemainChanCtx;
10912}
10913
Jeff Johnson295189b2012-06-20 16:38:30 -070010914//Register the module init/exit functions
10915module_init(hdd_module_init);
10916module_exit(hdd_module_exit);
10917
10918MODULE_LICENSE("Dual BSD/GPL");
10919MODULE_AUTHOR("Qualcomm Atheros, Inc.");
10920MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
10921
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010922module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
10923 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010924
Jeff Johnson76052702013-04-16 13:55:05 -070010925module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010926 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080010927
10928module_param(enable_dfs_chan_scan, int,
10929 S_IRUSR | S_IRGRP | S_IROTH);
10930
10931module_param(enable_11d, int,
10932 S_IRUSR | S_IRGRP | S_IROTH);
10933
10934module_param(country_code, charp,
10935 S_IRUSR | S_IRGRP | S_IROTH);