blob: 9060b912ff7c743ea6f97d4e928cdfe4c22a7a20 [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{
463 ENTER();
464
465 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
466 {
467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
468 "%s: HDD context is Null", __func__);
469 return -ENODEV;
470 }
471
472 if (pHddCtx->isLogpInProgress)
473 {
474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu8adb97b2014-12-08 19:38:20 +0530475 "%s: LOGP %s. Ignore!!", __func__,
476 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
477 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530478 return -EAGAIN;
479 }
480
Mihir Shete18156292014-03-11 15:38:30 +0530481 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530482 {
483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
484 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
485 return -EAGAIN;
486 }
487 return 0;
488}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700489#ifdef CONFIG_ENABLE_LINUX_REG
490void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
491{
492 hdd_adapter_t *pAdapter = NULL;
493 hdd_station_ctx_t *pHddStaCtx = NULL;
494 eCsrPhyMode phyMode;
495 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530496
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700497 if (NULL == pHddCtx)
498 {
499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
500 "HDD Context is null !!");
501 return ;
502 }
503
504 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
505 if (NULL == pAdapter)
506 {
507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
508 "pAdapter is null !!");
509 return ;
510 }
511
512 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
513 if (NULL == pHddStaCtx)
514 {
515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
516 "pHddStaCtx is null !!");
517 return ;
518 }
519
520 cfg_param = pHddCtx->cfg_ini;
521 if (NULL == cfg_param)
522 {
523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
524 "cfg_params not available !!");
525 return ;
526 }
527
528 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
529
530 if (!pHddCtx->isVHT80Allowed)
531 {
532 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
533 (eCSR_DOT11_MODE_11ac == phyMode) ||
534 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
535 {
536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
537 "Setting phymode to 11n!!");
538 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
539 }
540 }
541 else
542 {
543 /*New country Supports 11ac as well resetting value back from .ini*/
544 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
545 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
546 return ;
547 }
548
549 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
550 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
551 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
552 {
553 VOS_STATUS vosStatus;
554
555 // need to issue a disconnect to CSR.
556 INIT_COMPLETION(pAdapter->disconnect_comp_var);
557 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
558 pAdapter->sessionId,
559 eCSR_DISCONNECT_REASON_UNSPECIFIED );
560
561 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530562 {
563 long ret;
564
565 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700566 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530567 if (0 >= ret)
568 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
569 ret);
570 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700571
572 }
573}
574#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530575void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
576{
577 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
578 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
579 hdd_config_t *cfg_param;
580 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530581 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530582
583 if (NULL == pHddCtx)
584 {
585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
586 "HDD Context is null !!");
587 return ;
588 }
589
590 cfg_param = pHddCtx->cfg_ini;
591
592 if (NULL == cfg_param)
593 {
594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
595 "cfg_params not available !!");
596 return ;
597 }
598
599 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
600
601 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
602 {
603 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
604 (eCSR_DOT11_MODE_11ac == phyMode) ||
605 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
606 {
607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
608 "Setting phymode to 11n!!");
609 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
610 }
611 }
612 else
613 {
614 /*New country Supports 11ac as well resetting value back from .ini*/
615 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
616 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
617 return ;
618 }
619
620 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
621 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
622 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
623 {
624 VOS_STATUS vosStatus;
625
626 // need to issue a disconnect to CSR.
627 INIT_COMPLETION(pAdapter->disconnect_comp_var);
628 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
629 pAdapter->sessionId,
630 eCSR_DISCONNECT_REASON_UNSPECIFIED );
631
632 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530633 {
634 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530635 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530636 if (ret <= 0)
637 {
638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
639 "wait on disconnect_comp_var is failed %ld", ret);
640 }
641 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530642
643 }
644}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700645#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530646
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700647void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
648{
649 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
650 hdd_config_t *cfg_param;
651
652 if (NULL == pHddCtx)
653 {
654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
655 "HDD Context is null !!");
656 return ;
657 }
658
659 cfg_param = pHddCtx->cfg_ini;
660
661 if (NULL == cfg_param)
662 {
663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
664 "cfg_params not available !!");
665 return ;
666 }
667
Agarwal Ashish738843c2014-09-25 12:27:56 +0530668 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
669 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700670 {
671 /*New country doesn't support DFS */
672 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
673 }
674 else
675 {
676 /*New country Supports DFS as well resetting value back from .ini*/
677 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
678 }
679
680}
681
Rajeev79dbe4c2013-10-05 11:03:42 +0530682#ifdef FEATURE_WLAN_BATCH_SCAN
683
684/**---------------------------------------------------------------------------
685
686 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
687 input string
688
689 This function extracts assigned integer from string in below format:
690 "STRING=10" : extracts integer 10 from this string
691
692 \param - pInPtr Pointer to input string
693 \param - base Base for string to int conversion(10 for decimal 16 for hex)
694 \param - pOutPtr Pointer to variable in which extracted integer needs to be
695 assigned
696 \param - pLastArg to tell whether it is last arguement in input string or
697 not
698
699 \return - NULL for failure cases
700 pointer to next arguement in input string for success cases
701 --------------------------------------------------------------------------*/
702static tANI_U8 *
703hdd_extract_assigned_int_from_str
704(
705 tANI_U8 *pInPtr,
706 tANI_U8 base,
707 tANI_U32 *pOutPtr,
708 tANI_U8 *pLastArg
709)
710{
711 int tempInt;
712 int v = 0;
713 char buf[32];
714 int val = 0;
715 *pLastArg = FALSE;
716
717 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
718 if (NULL == pInPtr)
719 {
720 return NULL;
721 }
722
723 pInPtr++;
724
725 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
726
727 val = sscanf(pInPtr, "%32s ", buf);
728 if (val < 0 && val > strlen(pInPtr))
729 {
730 return NULL;
731 }
732 pInPtr += val;
733 v = kstrtos32(buf, base, &tempInt);
734 if (v < 0)
735 {
736 return NULL;
737 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800738 if (tempInt < 0)
739 {
740 tempInt = 0;
741 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530742 *pOutPtr = tempInt;
743
744 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
745 if (NULL == pInPtr)
746 {
747 *pLastArg = TRUE;
748 return NULL;
749 }
750 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
751
752 return pInPtr;
753}
754
755/**---------------------------------------------------------------------------
756
757 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
758 input string
759
760 This function extracts assigned character from string in below format:
761 "STRING=A" : extracts char 'A' from this string
762
763 \param - pInPtr Pointer to input string
764 \param - pOutPtr Pointer to variable in which extracted char needs to be
765 assigned
766 \param - pLastArg to tell whether it is last arguement in input string or
767 not
768
769 \return - NULL for failure cases
770 pointer to next arguement in input string for success cases
771 --------------------------------------------------------------------------*/
772static tANI_U8 *
773hdd_extract_assigned_char_from_str
774(
775 tANI_U8 *pInPtr,
776 tANI_U8 *pOutPtr,
777 tANI_U8 *pLastArg
778)
779{
780 *pLastArg = FALSE;
781
782 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
783 if (NULL == pInPtr)
784 {
785 return NULL;
786 }
787
788 pInPtr++;
789
790 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
791
792 *pOutPtr = *pInPtr;
793
794 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
795 if (NULL == pInPtr)
796 {
797 *pLastArg = TRUE;
798 return NULL;
799 }
800 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
801
802 return pInPtr;
803}
804
805
806/**---------------------------------------------------------------------------
807
808 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
809
810 This function parses set batch scan command in below format:
811 WLS_BATCHING_SET <space> followed by below arguements
812 "SCANFREQ=XX" : Optional defaults to 30 sec
813 "MSCAN=XX" : Required number of scans to attempt to batch
814 "BESTN=XX" : Best Network (RSSI) defaults to 16
815 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
816 A. implies only 5 GHz , B. implies only 2.4GHz
817 "RTT=X" : optional defaults to 0
818 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
819 error
820
821 For example input commands:
822 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
823 translated into set batch scan with following parameters:
824 a) Frequence 60 seconds
825 b) Batch 10 scans together
826 c) Best RSSI to be 20
827 d) 5GHz band only
828 e) RTT is equal to 0
829
830 \param - pValue Pointer to input channel list
831 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
832
833 \return - 0 for success non-zero for failure
834
835 --------------------------------------------------------------------------*/
836static int
837hdd_parse_set_batchscan_command
838(
839 tANI_U8 *pValue,
840 tSirSetBatchScanReq *pHddSetBatchScanReq
841)
842{
843 tANI_U8 *inPtr = pValue;
844 tANI_U8 val = 0;
845 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800846 tANI_U32 nScanFreq;
847 tANI_U32 nMscan;
848 tANI_U32 nBestN;
849 tANI_U8 ucRfBand;
850 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800851 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530852
853 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800854 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
855 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
856 nRtt = 0;
857 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530858
859 /*go to space after WLS_BATCHING_SET command*/
860 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
861 /*no argument after the command*/
862 if (NULL == inPtr)
863 {
864 return -EINVAL;
865 }
866
867 /*no space after the command*/
868 else if (SPACE_ASCII_VALUE != *inPtr)
869 {
870 return -EINVAL;
871 }
872
873 /*removing empty spaces*/
874 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
875
876 /*no argument followed by spaces*/
877 if ('\0' == *inPtr)
878 {
879 return -EINVAL;
880 }
881
882 /*check and parse SCANFREQ*/
883 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
884 {
885 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800886 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800887
Rajeev Kumarc933d982013-11-18 20:04:20 -0800888 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800889 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800890 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800891 }
892
Rajeev79dbe4c2013-10-05 11:03:42 +0530893 if ( (NULL == inPtr) || (TRUE == lastArg))
894 {
895 return -EINVAL;
896 }
897 }
898
899 /*check and parse MSCAN*/
900 if ((strncmp(inPtr, "MSCAN", 5) == 0))
901 {
902 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800903 &nMscan, &lastArg);
904
905 if (0 == nMscan)
906 {
907 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
908 "invalid MSCAN=%d", nMscan);
909 return -EINVAL;
910 }
911
Rajeev79dbe4c2013-10-05 11:03:42 +0530912 if (TRUE == lastArg)
913 {
914 goto done;
915 }
916 else if (NULL == inPtr)
917 {
918 return -EINVAL;
919 }
920 }
921 else
922 {
923 return -EINVAL;
924 }
925
926 /*check and parse BESTN*/
927 if ((strncmp(inPtr, "BESTN", 5) == 0))
928 {
929 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800930 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800931
Rajeev Kumarc933d982013-11-18 20:04:20 -0800932 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800933 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800934 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800935 }
936
Rajeev79dbe4c2013-10-05 11:03:42 +0530937 if (TRUE == lastArg)
938 {
939 goto done;
940 }
941 else if (NULL == inPtr)
942 {
943 return -EINVAL;
944 }
945 }
946
947 /*check and parse CHANNEL*/
948 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
949 {
950 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800951
Rajeev79dbe4c2013-10-05 11:03:42 +0530952 if (('A' == val) || ('a' == val))
953 {
c_hpothuebf89732014-02-25 13:00:24 +0530954 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530955 }
956 else if (('B' == val) || ('b' == val))
957 {
c_hpothuebf89732014-02-25 13:00:24 +0530958 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530959 }
960 else
961 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800962 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
963 }
964
965 if (TRUE == lastArg)
966 {
967 goto done;
968 }
969 else if (NULL == inPtr)
970 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530971 return -EINVAL;
972 }
973 }
974
975 /*check and parse RTT*/
976 if ((strncmp(inPtr, "RTT", 3) == 0))
977 {
978 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800979 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530980 if (TRUE == lastArg)
981 {
982 goto done;
983 }
984 if (NULL == inPtr)
985 {
986 return -EINVAL;
987 }
988 }
989
990
991done:
992
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800993 pHddSetBatchScanReq->scanFrequency = nScanFreq;
994 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
995 pHddSetBatchScanReq->bestNetwork = nBestN;
996 pHddSetBatchScanReq->rfBand = ucRfBand;
997 pHddSetBatchScanReq->rtt = nRtt;
998
Rajeev79dbe4c2013-10-05 11:03:42 +0530999 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1000 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1001 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1002 pHddSetBatchScanReq->scanFrequency,
1003 pHddSetBatchScanReq->numberOfScansToBatch,
1004 pHddSetBatchScanReq->bestNetwork,
1005 pHddSetBatchScanReq->rfBand,
1006 pHddSetBatchScanReq->rtt);
1007
1008 return 0;
1009}/*End of hdd_parse_set_batchscan_command*/
1010
1011/**---------------------------------------------------------------------------
1012
1013 \brief hdd_set_batch_scan_req_callback () - This function is called after
1014 receiving set batch scan response from FW and it saves set batch scan
1015 response data FW to HDD context and sets the completion event on
1016 which hdd_ioctl is waiting
1017
1018 \param - callbackContext Pointer to HDD adapter
1019 \param - pRsp Pointer to set batch scan response data received from FW
1020
1021 \return - nothing
1022
1023 --------------------------------------------------------------------------*/
1024static void hdd_set_batch_scan_req_callback
1025(
1026 void *callbackContext,
1027 tSirSetBatchScanRsp *pRsp
1028)
1029{
1030 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1031 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1032
1033 /*sanity check*/
1034 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1035 {
1036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1037 "%s: Invalid pAdapter magic", __func__);
1038 VOS_ASSERT(0);
1039 return;
1040 }
1041 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1042
1043 /*save set batch scan response*/
1044 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1045
1046 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1047 "Received set batch scan rsp from FW with nScansToBatch=%d",
1048 pHddSetBatchScanRsp->nScansToBatch);
1049
1050 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1051 complete(&pAdapter->hdd_set_batch_scan_req_var);
1052
1053 return;
1054}/*End of hdd_set_batch_scan_req_callback*/
1055
1056
1057/**---------------------------------------------------------------------------
1058
1059 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1060 info in hdd batch scan response queue
1061
1062 \param - pAdapter Pointer to hdd adapter
1063 \param - pAPMetaInfo Pointer to access point meta info
1064 \param - scanId scan ID of batch scan response
1065 \param - isLastAp tells whether AP is last AP in batch scan response or not
1066
1067 \return - nothing
1068
1069 --------------------------------------------------------------------------*/
1070static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1071 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1072{
1073 tHddBatchScanRsp *pHead;
1074 tHddBatchScanRsp *pNode;
1075 tHddBatchScanRsp *pPrev;
1076 tHddBatchScanRsp *pTemp;
1077 tANI_U8 ssidLen;
1078
1079 /*head of hdd batch scan response queue*/
1080 pHead = pAdapter->pBatchScanRsp;
1081
1082 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1083 if (NULL == pNode)
1084 {
1085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1086 "%s: Could not allocate memory", __func__);
1087 VOS_ASSERT(0);
1088 return;
1089 }
1090
1091 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1092 sizeof(pNode->ApInfo.bssid));
1093 ssidLen = strlen(pApMetaInfo->ssid);
1094 if (SIR_MAX_SSID_SIZE < ssidLen)
1095 {
1096 /*invalid scan result*/
1097 vos_mem_free(pNode);
1098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1099 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1100 return;
1101 }
1102 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1103 /*null terminate ssid*/
1104 pNode->ApInfo.ssid[ssidLen] = '\0';
1105 pNode->ApInfo.ch = pApMetaInfo->ch;
1106 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1107 pNode->ApInfo.age = pApMetaInfo->timestamp;
1108 pNode->ApInfo.batchId = scanId;
1109 pNode->ApInfo.isLastAp = isLastAp;
1110
1111 pNode->pNext = NULL;
1112 if (NULL == pHead)
1113 {
1114 pAdapter->pBatchScanRsp = pNode;
1115 }
1116 else
1117 {
1118 pTemp = pHead;
1119 while (NULL != pTemp)
1120 {
1121 pPrev = pTemp;
1122 pTemp = pTemp->pNext;
1123 }
1124 pPrev->pNext = pNode;
1125 }
1126
1127 return;
1128}/*End of hdd_populate_batch_scan_rsp_queue*/
1129
1130/**---------------------------------------------------------------------------
1131
1132 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1133 receiving batch scan response indication from FW. It saves get batch scan
1134 response data in HDD batch scan response queue. This callback sets the
1135 completion event on which hdd_ioctl is waiting only after getting complete
1136 batch scan response data from FW
1137
1138 \param - callbackContext Pointer to HDD adapter
1139 \param - pRsp Pointer to get batch scan response data received from FW
1140
1141 \return - nothing
1142
1143 --------------------------------------------------------------------------*/
1144static void hdd_batch_scan_result_ind_callback
1145(
1146 void *callbackContext,
1147 void *pRsp
1148)
1149{
1150 v_BOOL_t isLastAp;
1151 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001152 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301153 tANI_U32 numberScanList;
1154 tANI_U32 nextScanListOffset;
1155 tANI_U32 nextApMetaInfoOffset;
1156 hdd_adapter_t* pAdapter;
1157 tpSirBatchScanList pScanList;
1158 tpSirBatchScanNetworkInfo pApMetaInfo;
1159 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1160 tSirSetBatchScanReq *pReq;
1161
1162 pAdapter = (hdd_adapter_t *)callbackContext;
1163 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001164 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301165 {
1166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1167 "%s: Invalid pAdapter magic", __func__);
1168 VOS_ASSERT(0);
1169 return;
1170 }
1171
1172 /*initialize locals*/
1173 pReq = &pAdapter->hddSetBatchScanReq;
1174 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1175 isLastAp = FALSE;
1176 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001177 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301178 numberScanList = 0;
1179 nextScanListOffset = 0;
1180 nextApMetaInfoOffset = 0;
1181 pScanList = NULL;
1182 pApMetaInfo = NULL;
1183
1184 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1185 {
1186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1187 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1188 isLastAp = TRUE;
1189 goto done;
1190 }
1191
1192 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1194 "Batch scan rsp: numberScalList %d", numberScanList);
1195
1196 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1197 {
1198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1199 "%s: numberScanList %d", __func__, numberScanList);
1200 isLastAp = TRUE;
1201 goto done;
1202 }
1203
1204 while (numberScanList)
1205 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001206 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301207 nextScanListOffset);
1208 if (NULL == pScanList)
1209 {
1210 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1211 "%s: pScanList is %p", __func__, pScanList);
1212 isLastAp = TRUE;
1213 goto done;
1214 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001215 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001217 "Batch scan rsp: numApMetaInfo %d scanId %d",
1218 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301219
1220 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1221 {
1222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1223 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1224 isLastAp = TRUE;
1225 goto done;
1226 }
1227
Rajeev Kumarce651e42013-10-21 18:57:15 -07001228 /*Initialize next AP meta info offset for next scan list*/
1229 nextApMetaInfoOffset = 0;
1230
Rajeev79dbe4c2013-10-05 11:03:42 +05301231 while (numApMetaInfo)
1232 {
1233 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1234 nextApMetaInfoOffset);
1235 if (NULL == pApMetaInfo)
1236 {
1237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1238 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1239 isLastAp = TRUE;
1240 goto done;
1241 }
1242 /*calculate AP age*/
1243 pApMetaInfo->timestamp =
1244 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1245
1246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001247 "%s: bssId "MAC_ADDRESS_STR
1248 " ch %d rssi %d timestamp %d", __func__,
1249 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1250 pApMetaInfo->ch, pApMetaInfo->rssi,
1251 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301252
1253 /*mark last AP in batch scan response*/
1254 if ((TRUE == pBatchScanRsp->isLastResult) &&
1255 (1 == numberScanList) && (1 == numApMetaInfo))
1256 {
1257 isLastAp = TRUE;
1258 }
1259
1260 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1261 /*store batch scan repsonse in hdd queue*/
1262 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1263 pScanList->scanId, isLastAp);
1264 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1265
1266 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1267 numApMetaInfo--;
1268 }
1269
Rajeev Kumarce651e42013-10-21 18:57:15 -07001270 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1271 + (sizeof(tSirBatchScanNetworkInfo)
1272 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301273 numberScanList--;
1274 }
1275
1276done:
1277
1278 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1279 requested from hdd_ioctl*/
1280 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1281 (TRUE == isLastAp))
1282 {
1283 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1284 complete(&pAdapter->hdd_get_batch_scan_req_var);
1285 }
1286
1287 return;
1288}/*End of hdd_batch_scan_result_ind_callback*/
1289
1290/**---------------------------------------------------------------------------
1291
1292 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1293 response as per batch scan FR request format by putting proper markers
1294
1295 \param - pDest pointer to destination buffer
1296 \param - cur_len current length
1297 \param - tot_len total remaining size which can be written to user space
1298 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1299 \param - pAdapter Pointer to HDD adapter
1300
1301 \return - ret no of characters written
1302
1303 --------------------------------------------------------------------------*/
1304static tANI_U32
1305hdd_format_batch_scan_rsp
1306(
1307 tANI_U8 *pDest,
1308 tANI_U32 cur_len,
1309 tANI_U32 tot_len,
1310 tHddBatchScanRsp *pApMetaInfo,
1311 hdd_adapter_t* pAdapter
1312)
1313{
1314 tANI_U32 ret = 0;
1315 tANI_U32 rem_len = 0;
1316 tANI_U8 temp_len = 0;
1317 tANI_U8 temp_total_len = 0;
1318 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1319 tANI_U8 *pTemp = temp;
1320
1321 /*Batch scan reponse needs to be returned to user space in
1322 following format:
1323 "scancount=X\n" where X is the number of scans in current batch
1324 batch
1325 "trunc\n" optional present if current scan truncated
1326 "bssid=XX:XX:XX:XX:XX:XX\n"
1327 "ssid=XXXX\n"
1328 "freq=X\n" frequency in Mhz
1329 "level=XX\n"
1330 "age=X\n" ms
1331 "dist=X\n" cm (-1 if not available)
1332 "errror=X\n" (-1if not available)
1333 "====\n" (end of ap marker)
1334 "####\n" (end of scan marker)
1335 "----\n" (end of results)*/
1336 /*send scan result in above format to user space based on
1337 available length*/
1338 /*The GET response may have more data than the driver can return in its
1339 buffer. In that case the buffer should be filled to the nearest complete
1340 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1341 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1342 The final buffer should end with "----\n"*/
1343
1344 /*sanity*/
1345 if (cur_len > tot_len)
1346 {
1347 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1348 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1349 return 0;
1350 }
1351 else
1352 {
1353 rem_len = (tot_len - cur_len);
1354 }
1355
1356 /*end scan marker*/
1357 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1358 {
1359 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1360 pTemp += temp_len;
1361 temp_total_len += temp_len;
1362 }
1363
1364 /*bssid*/
1365 temp_len = snprintf(pTemp, sizeof(temp),
1366 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1367 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1368 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1369 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1370 pTemp += temp_len;
1371 temp_total_len += temp_len;
1372
1373 /*ssid*/
1374 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1375 pApMetaInfo->ApInfo.ssid);
1376 pTemp += temp_len;
1377 temp_total_len += temp_len;
1378
1379 /*freq*/
1380 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001381 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301382 pTemp += temp_len;
1383 temp_total_len += temp_len;
1384
1385 /*level*/
1386 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1387 pApMetaInfo->ApInfo.rssi);
1388 pTemp += temp_len;
1389 temp_total_len += temp_len;
1390
1391 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001392 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301393 pApMetaInfo->ApInfo.age);
1394 pTemp += temp_len;
1395 temp_total_len += temp_len;
1396
1397 /*dist*/
1398 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1399 pTemp += temp_len;
1400 temp_total_len += temp_len;
1401
1402 /*error*/
1403 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1404 pTemp += temp_len;
1405 temp_total_len += temp_len;
1406
1407 /*end AP marker*/
1408 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1409 pTemp += temp_len;
1410 temp_total_len += temp_len;
1411
1412 /*last AP in batch scan response*/
1413 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1414 {
1415 /*end scan marker*/
1416 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1417 pTemp += temp_len;
1418 temp_total_len += temp_len;
1419
1420 /*end batch scan result marker*/
1421 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1422 pTemp += temp_len;
1423 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001424
Rajeev79dbe4c2013-10-05 11:03:42 +05301425 }
1426
1427 if (temp_total_len < rem_len)
1428 {
1429 ret = temp_total_len + 1;
1430 strlcpy(pDest, temp, ret);
1431 pAdapter->isTruncated = FALSE;
1432 }
1433 else
1434 {
1435 pAdapter->isTruncated = TRUE;
1436 if (rem_len >= strlen("%%%%"))
1437 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001438 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301439 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001440 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301441 {
1442 ret = 0;
1443 }
1444 }
1445
1446 return ret;
1447
1448}/*End of hdd_format_batch_scan_rsp*/
1449
1450/**---------------------------------------------------------------------------
1451
1452 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1453 buffer starting with head of hdd batch scan response queue
1454
1455 \param - pAdapter Pointer to HDD adapter
1456 \param - pDest Pointer to user data buffer
1457 \param - cur_len current offset in user buffer
1458 \param - rem_len remaining no of bytes in user buffer
1459
1460 \return - number of bytes written in user buffer
1461
1462 --------------------------------------------------------------------------*/
1463
1464tANI_U32 hdd_populate_user_batch_scan_rsp
1465(
1466 hdd_adapter_t* pAdapter,
1467 tANI_U8 *pDest,
1468 tANI_U32 cur_len,
1469 tANI_U32 rem_len
1470)
1471{
1472 tHddBatchScanRsp *pHead;
1473 tHddBatchScanRsp *pPrev;
1474 tANI_U32 len;
1475
Rajeev79dbe4c2013-10-05 11:03:42 +05301476 pAdapter->isTruncated = FALSE;
1477
1478 /*head of hdd batch scan response queue*/
1479 pHead = pAdapter->pBatchScanRsp;
1480 while (pHead)
1481 {
1482 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1483 pAdapter);
1484 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001485 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301486 cur_len += len;
1487 if(TRUE == pAdapter->isTruncated)
1488 {
1489 /*result is truncated return rest of scan rsp in next req*/
1490 cur_len = rem_len;
1491 break;
1492 }
1493 pPrev = pHead;
1494 pHead = pHead->pNext;
1495 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001496 if (TRUE == pPrev->ApInfo.isLastAp)
1497 {
1498 pAdapter->prev_batch_id = 0;
1499 }
1500 else
1501 {
1502 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1503 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301504 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001505 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301506 }
1507
1508 return cur_len;
1509}/*End of hdd_populate_user_batch_scan_rsp*/
1510
1511/**---------------------------------------------------------------------------
1512
1513 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1514 scan response data from HDD queue to user space
1515 It does following in detail:
1516 a) if HDD has enough data in its queue then it 1st copies data to user
1517 space and then send get batch scan indication message to FW. In this
1518 case it does not wait on any event and batch scan response data will
1519 be populated in HDD response queue in MC thread context after receiving
1520 indication from FW
1521 b) else send get batch scan indication message to FW and wait on an event
1522 which will be set once HDD receives complete batch scan response from
1523 FW and then this function returns batch scan response to user space
1524
1525 \param - pAdapter Pointer to HDD adapter
1526 \param - pPrivData Pointer to priv_data
1527
1528 \return - 0 for success -EFAULT for failure
1529
1530 --------------------------------------------------------------------------*/
1531
1532int hdd_return_batch_scan_rsp_to_user
1533(
1534 hdd_adapter_t* pAdapter,
1535 hdd_priv_data_t *pPrivData,
1536 tANI_U8 *command
1537)
1538{
1539 tANI_U8 *pDest;
1540 tANI_U32 count = 0;
1541 tANI_U32 len = 0;
1542 tANI_U32 cur_len = 0;
1543 tANI_U32 rem_len = 0;
1544 eHalStatus halStatus;
1545 unsigned long rc;
1546 tSirTriggerBatchScanResultInd *pReq;
1547
1548 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1549 pReq->param = 0;/*batch scan client*/
1550 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1551 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1552
1553 cur_len = pPrivData->used_len;
1554 if (pPrivData->total_len > pPrivData->used_len)
1555 {
1556 rem_len = pPrivData->total_len - pPrivData->used_len;
1557 }
1558 else
1559 {
1560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1561 "%s: Invalid user data buffer total_len %d used_len %d",
1562 __func__, pPrivData->total_len, pPrivData->used_len);
1563 return -EFAULT;
1564 }
1565
1566 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1567 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1568 cur_len, rem_len);
1569 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1570
1571 /*enough scan result available in cache to return to user space or
1572 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001573 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301574 {
1575 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1576 halStatus = sme_TriggerBatchScanResultInd(
1577 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1578 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1579 pAdapter);
1580 if ( eHAL_STATUS_SUCCESS == halStatus )
1581 {
1582 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1583 {
1584 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1585 rc = wait_for_completion_timeout(
1586 &pAdapter->hdd_get_batch_scan_req_var,
1587 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1588 if (0 == rc)
1589 {
1590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1591 "%s: Timeout waiting to fetch batch scan rsp from fw",
1592 __func__);
1593 return -EFAULT;
1594 }
1595 }
1596
1597 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001598 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301599 pDest += len;
1600 cur_len += len;
1601
1602 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1603 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1604 cur_len, rem_len);
1605 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1606
1607 count = 0;
1608 len = (len - pPrivData->used_len);
1609 pDest = (command + pPrivData->used_len);
1610 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001611 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301612 while(count < len)
1613 {
1614 printk("%c", *(pDest + count));
1615 count++;
1616 }
1617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1618 "%s: copy %d data to user buffer", __func__, len);
1619 if (copy_to_user(pPrivData->buf, pDest, len))
1620 {
1621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1622 "%s: failed to copy data to user buffer", __func__);
1623 return -EFAULT;
1624 }
1625 }
1626 else
1627 {
1628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1629 "sme_GetBatchScanScan returned failure halStatus %d",
1630 halStatus);
1631 return -EINVAL;
1632 }
1633 }
1634 else
1635 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301636 count = 0;
1637 len = (len - pPrivData->used_len);
1638 pDest = (command + pPrivData->used_len);
1639 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001640 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301641 while(count < len)
1642 {
1643 printk("%c", *(pDest + count));
1644 count++;
1645 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1647 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301648 if (copy_to_user(pPrivData->buf, pDest, len))
1649 {
1650 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1651 "%s: failed to copy data to user buffer", __func__);
1652 return -EFAULT;
1653 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301654 }
1655
1656 return 0;
1657} /*End of hdd_return_batch_scan_rsp_to_user*/
1658
Rajeev Kumar8b373292014-01-08 20:36:55 -08001659
1660/**---------------------------------------------------------------------------
1661
1662 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1663 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1664 WLS_BATCHING VERSION
1665 WLS_BATCHING SET
1666 WLS_BATCHING GET
1667 WLS_BATCHING STOP
1668
1669 \param - pAdapter Pointer to HDD adapter
1670 \param - pPrivdata Pointer to priv_data
1671 \param - command Pointer to command
1672
1673 \return - 0 for success -EFAULT for failure
1674
1675 --------------------------------------------------------------------------*/
1676
1677int hdd_handle_batch_scan_ioctl
1678(
1679 hdd_adapter_t *pAdapter,
1680 hdd_priv_data_t *pPrivdata,
1681 tANI_U8 *command
1682)
1683{
1684 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001685 hdd_context_t *pHddCtx;
1686
1687 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1688 ret = wlan_hdd_validate_context(pHddCtx);
1689 if (ret)
1690 {
1691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1692 "%s: HDD context is not valid!", __func__);
1693 goto exit;
1694 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001695
1696 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1697 {
1698 char extra[32];
1699 tANI_U8 len = 0;
1700 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1701
1702 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1703 {
1704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1705 "%s: Batch scan feature is not supported by FW", __func__);
1706 ret = -EINVAL;
1707 goto exit;
1708 }
1709
1710 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1711 version);
1712 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1713 {
1714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1715 "%s: failed to copy data to user buffer", __func__);
1716 ret = -EFAULT;
1717 goto exit;
1718 }
1719 ret = HDD_BATCH_SCAN_VERSION;
1720 }
1721 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1722 {
1723 int status;
1724 tANI_U8 *value = (command + 16);
1725 eHalStatus halStatus;
1726 unsigned long rc;
1727 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1728 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1729
1730 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1731 {
1732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1733 "%s: Batch scan feature is not supported by FW", __func__);
1734 ret = -EINVAL;
1735 goto exit;
1736 }
1737
1738 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1739 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1740 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1741 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1742 {
1743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301744 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001745 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301746 hdd_device_modetoString(pAdapter->device_mode),
1747 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001748 ret = -EINVAL;
1749 goto exit;
1750 }
1751
1752 status = hdd_parse_set_batchscan_command(value, pReq);
1753 if (status)
1754 {
1755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1756 "Invalid WLS_BATCHING SET command");
1757 ret = -EINVAL;
1758 goto exit;
1759 }
1760
1761
1762 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1763 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1764 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1765 pAdapter);
1766
1767 if ( eHAL_STATUS_SUCCESS == halStatus )
1768 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301769 char extra[32];
1770 tANI_U8 len = 0;
1771 tANI_U8 mScan = 0;
1772
Rajeev Kumar8b373292014-01-08 20:36:55 -08001773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1774 "sme_SetBatchScanReq returned success halStatus %d",
1775 halStatus);
1776 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1777 {
1778 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1779 rc = wait_for_completion_timeout(
1780 &pAdapter->hdd_set_batch_scan_req_var,
1781 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1782 if (0 == rc)
1783 {
1784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1785 "%s: Timeout waiting for set batch scan to complete",
1786 __func__);
1787 ret = -EINVAL;
1788 goto exit;
1789 }
1790 }
1791 if ( !pRsp->nScansToBatch )
1792 {
1793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1794 "%s: Received set batch scan failure response from FW",
1795 __func__);
1796 ret = -EINVAL;
1797 goto exit;
1798 }
1799 /*As per the Batch Scan Framework API we should return the MIN of
1800 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301801 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001802
1803 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1804
1805 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1806 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301807 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1808 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1809 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1810 {
1811 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1812 "%s: failed to copy MSCAN value to user buffer", __func__);
1813 ret = -EFAULT;
1814 goto exit;
1815 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001816 }
1817 else
1818 {
1819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1820 "sme_SetBatchScanReq returned failure halStatus %d",
1821 halStatus);
1822 ret = -EINVAL;
1823 goto exit;
1824 }
1825 }
1826 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1827 {
1828 eHalStatus halStatus;
1829 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1830 pInd->param = 0;
1831
1832 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1833 {
1834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1835 "%s: Batch scan feature is not supported by FW", __func__);
1836 ret = -EINVAL;
1837 goto exit;
1838 }
1839
1840 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1841 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001843 "Batch scan is not yet enabled batch scan state %d",
1844 pAdapter->batchScanState);
1845 ret = -EINVAL;
1846 goto exit;
1847 }
1848
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001849 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1850 hdd_deinit_batch_scan(pAdapter);
1851 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1852
Rajeev Kumar8b373292014-01-08 20:36:55 -08001853 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1854
1855 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1856 pAdapter->sessionId);
1857 if ( eHAL_STATUS_SUCCESS == halStatus )
1858 {
1859 ret = 0;
1860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1861 "sme_StopBatchScanInd returned success halStatus %d",
1862 halStatus);
1863 }
1864 else
1865 {
1866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1867 "sme_StopBatchScanInd returned failure halStatus %d",
1868 halStatus);
1869 ret = -EINVAL;
1870 goto exit;
1871 }
1872 }
1873 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1874 {
1875 tANI_U32 remain_len;
1876
1877 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1878 {
1879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1880 "%s: Batch scan feature is not supported by FW", __func__);
1881 ret = -EINVAL;
1882 goto exit;
1883 }
1884
1885 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1886 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001888 "Batch scan is not yet enabled could not return results"
1889 "Batch Scan state %d",
1890 pAdapter->batchScanState);
1891 ret = -EINVAL;
1892 goto exit;
1893 }
1894
1895 pPrivdata->used_len = 16;
1896 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1897 if (remain_len < pPrivdata->total_len)
1898 {
1899 /*Clear previous batch scan response data if any*/
1900 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1901 }
1902 else
1903 {
1904 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1905 "Invalid total length from user space can't fetch batch"
1906 " scan response total_len %d used_len %d remain len %d",
1907 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1908 ret = -EINVAL;
1909 goto exit;
1910 }
1911 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1912 }
1913
1914exit:
1915
1916 return ret;
1917}
1918
1919
Rajeev79dbe4c2013-10-05 11:03:42 +05301920#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1921
c_hpothu92367912014-05-01 15:18:17 +05301922static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1923{
c_hpothu39eb1e32014-06-26 16:31:50 +05301924 bcnMissRateContext_t *pCBCtx;
1925
1926 if (NULL == data)
1927 {
1928 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1929 return;
1930 }
c_hpothu92367912014-05-01 15:18:17 +05301931
1932 /* there is a race condition that exists between this callback
1933 function and the caller since the caller could time out either
1934 before or while this code is executing. we use a spinlock to
1935 serialize these actions */
1936 spin_lock(&hdd_context_lock);
1937
c_hpothu39eb1e32014-06-26 16:31:50 +05301938 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301939 gbcnMissRate = -1;
1940
c_hpothu39eb1e32014-06-26 16:31:50 +05301941 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301942 {
1943 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301944 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301945 spin_unlock(&hdd_context_lock);
1946 return ;
1947 }
1948
1949 if (VOS_STATUS_SUCCESS == status)
1950 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301951 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301952 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301953 else
1954 {
1955 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
1956 }
1957
c_hpothu92367912014-05-01 15:18:17 +05301958 complete(&(pCBCtx->completion));
1959 spin_unlock(&hdd_context_lock);
1960
1961 return;
1962}
1963
Abhishek Singh08aa7762014-12-16 13:59:03 +05301964void hdd_FWStatisCB( VOS_STATUS status,
1965 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05301966{
1967 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301968 hdd_adapter_t *pAdapter;
1969
1970 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
1971
Abhishek Singh08aa7762014-12-16 13:59:03 +05301972 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05301973 {
1974 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1975 return;
1976 }
1977 /* there is a race condition that exists between this callback
1978 function and the caller since the caller could time out either
1979 before or while this code is executing. we use a spinlock to
1980 serialize these actions */
1981 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05301982 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301983 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
1984 {
1985 hddLog(VOS_TRACE_LEVEL_ERROR,
1986 FL("invalid context magic: %08x"), fwStatsCtx->magic);
1987 spin_unlock(&hdd_context_lock);
1988 return;
1989 }
1990 pAdapter = fwStatsCtx->pAdapter;
1991 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
1992 {
1993 hddLog(VOS_TRACE_LEVEL_ERROR,
1994 FL("pAdapter returned is NULL or invalid"));
1995 spin_unlock(&hdd_context_lock);
1996 return;
1997 }
1998 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05301999 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05302000 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302001 switch( fwStatsResult->type )
2002 {
2003 case FW_UBSP_STATS:
2004 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302005 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302006 hddLog(VOS_TRACE_LEVEL_INFO,
2007 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302008 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2009 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302010 }
2011 break;
2012 default:
2013 {
2014 hddLog(VOS_TRACE_LEVEL_ERROR,
2015 FL(" No handling for stats type %d"),fwStatsResult->type);
2016 }
2017 }
2018 }
2019 complete(&(fwStatsCtx->completion));
2020 spin_unlock(&hdd_context_lock);
2021 return;
2022}
2023
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302024static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2025{
2026 int ret = 0;
2027
2028 if (!pCfg || !command || !extra || !len)
2029 {
2030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2031 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2032 ret = -EINVAL;
2033 return ret;
2034 }
2035
2036 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2037 {
2038 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2039 (int)pCfg->nActiveMaxChnTime);
2040 return ret;
2041 }
2042 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2043 {
2044 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2045 (int)pCfg->nActiveMinChnTime);
2046 return ret;
2047 }
2048 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2049 {
2050 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2051 (int)pCfg->nPassiveMaxChnTime);
2052 return ret;
2053 }
2054 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2055 {
2056 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2057 (int)pCfg->nPassiveMinChnTime);
2058 return ret;
2059 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302060 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2061 {
2062 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2063 (int)pCfg->nActiveMaxChnTime);
2064 return ret;
2065 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302066 else
2067 {
2068 ret = -EINVAL;
2069 }
2070
2071 return ret;
2072}
2073
2074static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2075{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302076 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302077 hdd_config_t *pCfg;
2078 tANI_U8 *value = command;
2079 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302080 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302081
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302082 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2083 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302084 {
2085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2086 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2087 ret = -EINVAL;
2088 return ret;
2089 }
2090
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302091 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2092 sme_GetConfigParam(hHal, &smeConfig);
2093
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302094 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2095 {
2096 value = value + 24;
2097 temp = kstrtou32(value, 10, &val);
2098 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2099 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2100 {
2101 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2102 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2103 ret = -EFAULT;
2104 return ret;
2105 }
2106 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302107 smeConfig.csrConfig.nActiveMaxChnTime = val;
2108 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302109 }
2110 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2111 {
2112 value = value + 24;
2113 temp = kstrtou32(value, 10, &val);
2114 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2115 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2116 {
2117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2118 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2119 ret = -EFAULT;
2120 return ret;
2121 }
2122 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302123 smeConfig.csrConfig.nActiveMinChnTime = val;
2124 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302125 }
2126 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2127 {
2128 value = value + 25;
2129 temp = kstrtou32(value, 10, &val);
2130 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2131 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2132 {
2133 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2134 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2135 ret = -EFAULT;
2136 return ret;
2137 }
2138 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302139 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2140 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302141 }
2142 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2143 {
2144 value = value + 25;
2145 temp = kstrtou32(value, 10, &val);
2146 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2147 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2148 {
2149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2150 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2151 ret = -EFAULT;
2152 return ret;
2153 }
2154 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302155 smeConfig.csrConfig.nPassiveMinChnTime = val;
2156 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302157 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302158 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2159 {
2160 value = value + 13;
2161 temp = kstrtou32(value, 10, &val);
2162 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2163 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2164 {
2165 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2166 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2167 ret = -EFAULT;
2168 return ret;
2169 }
2170 pCfg->nActiveMaxChnTime = val;
2171 smeConfig.csrConfig.nActiveMaxChnTime = val;
2172 sme_UpdateConfig(hHal, &smeConfig);
2173 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302174 else
2175 {
2176 ret = -EINVAL;
2177 }
2178
2179 return ret;
2180}
2181
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002182static int hdd_driver_command(hdd_adapter_t *pAdapter,
2183 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002184{
Jeff Johnson295189b2012-06-20 16:38:30 -07002185 hdd_priv_data_t priv_data;
2186 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302187 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2188 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002189 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302190 int status;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002191 /*
2192 * Note that valid pointers are provided by caller
2193 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002194
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002195 /* copy to local struct to avoid numerous changes to legacy code */
2196 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002197
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002198 if (priv_data.total_len <= 0 ||
2199 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002200 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002201 hddLog(VOS_TRACE_LEVEL_WARN,
2202 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2203 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002204 ret = -EINVAL;
2205 goto exit;
2206 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302207 status = wlan_hdd_validate_context(pHddCtx);
2208 if (0 != status)
2209 {
2210 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2211 "%s: HDD context is not valid", __func__);
2212 return status;
2213 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002214 /* Allocate +1 for '\0' */
2215 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002216 if (!command)
2217 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002218 hddLog(VOS_TRACE_LEVEL_ERROR,
2219 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002220 ret = -ENOMEM;
2221 goto exit;
2222 }
2223
2224 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2225 {
2226 ret = -EFAULT;
2227 goto exit;
2228 }
2229
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002230 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002231 command[priv_data.total_len] = '\0';
2232
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002233 /* at one time the following block of code was conditional. braces
2234 * have been retained to avoid re-indenting the legacy code
2235 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002236 {
2237 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2238
2239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002240 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002241
2242 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2243 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302244 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2245 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2246 pAdapter->sessionId, (unsigned)
2247 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2248 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2249 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2250 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002251 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2252 sizeof(tSirMacAddr)))
2253 {
2254 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002255 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002256 ret = -EFAULT;
2257 }
2258 }
Amar Singhal0974e402013-02-12 14:27:46 -08002259 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002260 {
Amar Singhal0974e402013-02-12 14:27:46 -08002261 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002262
Jeff Johnson295189b2012-06-20 16:38:30 -07002263 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002264
2265 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002266 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002267 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002268 "%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 -07002269 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002270 ret = hdd_setBand_helper(pAdapter->dev, ptr);
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05302271 if(ret < 0)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302272 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002273 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002274 }
Kiet Lamf040f472013-11-20 21:15:23 +05302275 else if(strncmp(command, "SETWMMPS", 8) == 0)
2276 {
2277 tANI_U8 *ptr = command;
2278 ret = hdd_wmmps_helper(pAdapter, ptr);
2279 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05302280
2281 else if(strncmp(command, "TDLSSCAN", 8) == 0)
2282 {
2283 tANI_U8 *ptr = command;
2284 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
2285 }
2286
Jeff Johnson32d95a32012-09-10 13:15:23 -07002287 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2288 {
2289 char *country_code;
2290
2291 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002292
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002293 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002294 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002295#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302296 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002297#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002298 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2299 (void *)(tSmeChangeCountryCallback)
2300 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302301 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002302 if (eHAL_STATUS_SUCCESS == ret)
2303 {
2304 ret = wait_for_completion_interruptible_timeout(
2305 &pAdapter->change_country_code,
2306 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2307 if (0 >= ret)
2308 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002309 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302310 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002311 }
2312 }
2313 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002314 {
2315 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002316 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002317 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002318 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002319
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002320 }
2321 /*
2322 command should be a string having format
2323 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2324 */
Amar Singhal0974e402013-02-12 14:27:46 -08002325 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002326 {
Amar Singhal0974e402013-02-12 14:27:46 -08002327 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002328
2329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002330 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002331
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002332 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002333 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002334 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2335 {
2336 int suspend = 0;
2337 tANI_U8 *ptr = (tANI_U8*)command + 15;
2338
2339 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302340 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2341 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2342 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002343 hdd_set_wlan_suspend_mode(suspend);
2344 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002345#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2346 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2347 {
2348 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002349 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002350 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2351 eHalStatus status = eHAL_STATUS_SUCCESS;
2352
2353 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2354 value = value + 15;
2355
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002356 /* Convert the value from ascii to integer */
2357 ret = kstrtos8(value, 10, &rssi);
2358 if (ret < 0)
2359 {
2360 /* If the input value is greater than max value of datatype, then also
2361 kstrtou8 fails */
2362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2363 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002364 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002365 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2366 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2367 ret = -EINVAL;
2368 goto exit;
2369 }
2370
Srinivas Girigowdade697412013-02-14 16:31:48 -08002371 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002372
Srinivas Girigowdade697412013-02-14 16:31:48 -08002373 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2374 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2375 {
2376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2377 "Neighbor lookup threshold value %d is out of range"
2378 " (Min: %d Max: %d)", lookUpThreshold,
2379 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2380 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2381 ret = -EINVAL;
2382 goto exit;
2383 }
2384
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302385 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2386 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2387 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2389 "%s: Received Command to Set Roam trigger"
2390 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2391
2392 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2393 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2394 if (eHAL_STATUS_SUCCESS != status)
2395 {
2396 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2397 "%s: Failed to set roam trigger, try again", __func__);
2398 ret = -EPERM;
2399 goto exit;
2400 }
2401
2402 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302403 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002404 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2405 }
2406 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2407 {
2408 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2409 int rssi = (-1) * lookUpThreshold;
2410 char extra[32];
2411 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302412 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2413 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2414 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002415 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002416 if (copy_to_user(priv_data.buf, &extra, len + 1))
2417 {
2418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2419 "%s: failed to copy data to user buffer", __func__);
2420 ret = -EFAULT;
2421 goto exit;
2422 }
2423 }
2424 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2425 {
2426 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002427 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002428 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002429
Srinivas Girigowdade697412013-02-14 16:31:48 -08002430 /* input refresh period is in terms of seconds */
2431 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2432 value = value + 18;
2433 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002434 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002435 if (ret < 0)
2436 {
2437 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002438 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002440 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002441 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002442 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2443 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002444 ret = -EINVAL;
2445 goto exit;
2446 }
2447
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002448 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2449 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002450 {
2451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002452 "Roam scan period value %d is out of range"
2453 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002454 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2455 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002456 ret = -EINVAL;
2457 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302458 }
2459 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2460 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2461 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002462 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002463
2464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2465 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002466 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002467
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002468 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2469 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002470 }
2471 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2472 {
2473 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2474 char extra[32];
2475 tANI_U8 len = 0;
2476
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302477 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2478 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2479 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002480 len = scnprintf(extra, sizeof(extra), "%s %d",
2481 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002482 /* Returned value is in units of seconds */
2483 if (copy_to_user(priv_data.buf, &extra, len + 1))
2484 {
2485 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2486 "%s: failed to copy data to user buffer", __func__);
2487 ret = -EFAULT;
2488 goto exit;
2489 }
2490 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002491 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2492 {
2493 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002494 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002495 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002496
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002497 /* input refresh period is in terms of seconds */
2498 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2499 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002500
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002501 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002502 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002503 if (ret < 0)
2504 {
2505 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002506 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002508 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002509 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002510 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2511 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2512 ret = -EINVAL;
2513 goto exit;
2514 }
2515
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002516 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2517 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2518 {
2519 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2520 "Neighbor scan results refresh period value %d is out of range"
2521 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2522 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2523 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2524 ret = -EINVAL;
2525 goto exit;
2526 }
2527 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2528
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2530 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002531 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002532
2533 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2534 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2535 }
2536 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2537 {
2538 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2539 char extra[32];
2540 tANI_U8 len = 0;
2541
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002542 len = scnprintf(extra, sizeof(extra), "%s %d",
2543 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002544 /* Returned value is in units of seconds */
2545 if (copy_to_user(priv_data.buf, &extra, len + 1))
2546 {
2547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2548 "%s: failed to copy data to user buffer", __func__);
2549 ret = -EFAULT;
2550 goto exit;
2551 }
2552 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002553#ifdef FEATURE_WLAN_LFR
2554 /* SETROAMMODE */
2555 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2556 {
2557 tANI_U8 *value = command;
2558 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2559
2560 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2561 value = value + SIZE_OF_SETROAMMODE + 1;
2562
2563 /* Convert the value from ascii to integer */
2564 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2565 if (ret < 0)
2566 {
2567 /* If the input value is greater than max value of datatype, then also
2568 kstrtou8 fails */
2569 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2570 "%s: kstrtou8 failed range [%d - %d]", __func__,
2571 CFG_LFR_FEATURE_ENABLED_MIN,
2572 CFG_LFR_FEATURE_ENABLED_MAX);
2573 ret = -EINVAL;
2574 goto exit;
2575 }
2576 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2577 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2578 {
2579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2580 "Roam Mode value %d is out of range"
2581 " (Min: %d Max: %d)", roamMode,
2582 CFG_LFR_FEATURE_ENABLED_MIN,
2583 CFG_LFR_FEATURE_ENABLED_MAX);
2584 ret = -EINVAL;
2585 goto exit;
2586 }
2587
2588 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2589 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2590 /*
2591 * Note that
2592 * SETROAMMODE 0 is to enable LFR while
2593 * SETROAMMODE 1 is to disable LFR, but
2594 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2595 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2596 */
2597 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2598 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2599 else
2600 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2601
2602 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2603 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2604 }
2605 /* GETROAMMODE */
2606 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2607 {
2608 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2609 char extra[32];
2610 tANI_U8 len = 0;
2611
2612 /*
2613 * roamMode value shall be inverted because the sementics is different.
2614 */
2615 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2616 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2617 else
2618 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2619
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002620 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002621 if (copy_to_user(priv_data.buf, &extra, len + 1))
2622 {
2623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2624 "%s: failed to copy data to user buffer", __func__);
2625 ret = -EFAULT;
2626 goto exit;
2627 }
2628 }
2629#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002630#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002631#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002632 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2633 {
2634 tANI_U8 *value = command;
2635 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2636
2637 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2638 value = value + 13;
2639 /* Convert the value from ascii to integer */
2640 ret = kstrtou8(value, 10, &roamRssiDiff);
2641 if (ret < 0)
2642 {
2643 /* If the input value is greater than max value of datatype, then also
2644 kstrtou8 fails */
2645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2646 "%s: kstrtou8 failed range [%d - %d]", __func__,
2647 CFG_ROAM_RSSI_DIFF_MIN,
2648 CFG_ROAM_RSSI_DIFF_MAX);
2649 ret = -EINVAL;
2650 goto exit;
2651 }
2652
2653 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2654 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2655 {
2656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2657 "Roam rssi diff value %d is out of range"
2658 " (Min: %d Max: %d)", roamRssiDiff,
2659 CFG_ROAM_RSSI_DIFF_MIN,
2660 CFG_ROAM_RSSI_DIFF_MAX);
2661 ret = -EINVAL;
2662 goto exit;
2663 }
2664
2665 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2666 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2667
2668 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2669 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2670 }
2671 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2672 {
2673 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2674 char extra[32];
2675 tANI_U8 len = 0;
2676
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302677 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2678 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2679 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002680 len = scnprintf(extra, sizeof(extra), "%s %d",
2681 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002682 if (copy_to_user(priv_data.buf, &extra, len + 1))
2683 {
2684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2685 "%s: failed to copy data to user buffer", __func__);
2686 ret = -EFAULT;
2687 goto exit;
2688 }
2689 }
2690#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002691#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002692 else if (strncmp(command, "GETBAND", 7) == 0)
2693 {
2694 int band = -1;
2695 char extra[32];
2696 tANI_U8 len = 0;
2697 hdd_getBand_helper(pHddCtx, &band);
2698
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302699 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2700 TRACE_CODE_HDD_GETBAND_IOCTL,
2701 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002702 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002703 if (copy_to_user(priv_data.buf, &extra, len + 1))
2704 {
2705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2706 "%s: failed to copy data to user buffer", __func__);
2707 ret = -EFAULT;
2708 goto exit;
2709 }
2710 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002711 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2712 {
2713 tANI_U8 *value = command;
2714 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2715 tANI_U8 numChannels = 0;
2716 eHalStatus status = eHAL_STATUS_SUCCESS;
2717
2718 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2719 if (eHAL_STATUS_SUCCESS != status)
2720 {
2721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2722 "%s: Failed to parse channel list information", __func__);
2723 ret = -EINVAL;
2724 goto exit;
2725 }
2726
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302727 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2728 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2729 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002730 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2731 {
2732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2733 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2734 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2735 ret = -EINVAL;
2736 goto exit;
2737 }
2738 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2739 numChannels);
2740 if (eHAL_STATUS_SUCCESS != status)
2741 {
2742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2743 "%s: Failed to update channel list information", __func__);
2744 ret = -EINVAL;
2745 goto exit;
2746 }
2747 }
2748 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2749 {
2750 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2751 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002752 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002753 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002754 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002755
2756 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2757 ChannelList, &numChannels ))
2758 {
2759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2760 "%s: failed to get roam scan channel list", __func__);
2761 ret = -EFAULT;
2762 goto exit;
2763 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302764 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2765 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2766 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002767 /* output channel list is of the format
2768 [Number of roam scan channels][Channel1][Channel2]... */
2769 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002770 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002771 for (j = 0; (j < numChannels); j++)
2772 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002773 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2774 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002775 }
2776
2777 if (copy_to_user(priv_data.buf, &extra, len + 1))
2778 {
2779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2780 "%s: failed to copy data to user buffer", __func__);
2781 ret = -EFAULT;
2782 goto exit;
2783 }
2784 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002785 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2786 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002787 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002788 char extra[32];
2789 tANI_U8 len = 0;
2790
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002791 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002792 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002793 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002794 hdd_is_okc_mode_enabled(pHddCtx) &&
2795 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2796 {
2797 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002798 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002799 " hence this operation is not permitted!", __func__);
2800 ret = -EPERM;
2801 goto exit;
2802 }
2803
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002804 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002805 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002806 if (copy_to_user(priv_data.buf, &extra, len + 1))
2807 {
2808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2809 "%s: failed to copy data to user buffer", __func__);
2810 ret = -EFAULT;
2811 goto exit;
2812 }
2813 }
2814 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2815 {
2816 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2817 char extra[32];
2818 tANI_U8 len = 0;
2819
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002820 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002821 then this operation is not permitted (return FAILURE) */
2822 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002823 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002824 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2825 {
2826 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002827 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002828 " hence this operation is not permitted!", __func__);
2829 ret = -EPERM;
2830 goto exit;
2831 }
2832
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002833 len = scnprintf(extra, sizeof(extra), "%s %d",
2834 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002835 if (copy_to_user(priv_data.buf, &extra, len + 1))
2836 {
2837 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2838 "%s: failed to copy data to user buffer", __func__);
2839 ret = -EFAULT;
2840 goto exit;
2841 }
2842 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002843 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002844 {
2845 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2846 char extra[32];
2847 tANI_U8 len = 0;
2848
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002849 len = scnprintf(extra, sizeof(extra), "%s %d",
2850 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002851 if (copy_to_user(priv_data.buf, &extra, len + 1))
2852 {
2853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2854 "%s: failed to copy data to user buffer", __func__);
2855 ret = -EFAULT;
2856 goto exit;
2857 }
2858 }
2859 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2860 {
2861 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2862 char extra[32];
2863 tANI_U8 len = 0;
2864
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002865 len = scnprintf(extra, sizeof(extra), "%s %d",
2866 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002867 if (copy_to_user(priv_data.buf, &extra, len + 1))
2868 {
2869 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2870 "%s: failed to copy data to user buffer", __func__);
2871 ret = -EFAULT;
2872 goto exit;
2873 }
2874 }
2875 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2876 {
2877 tANI_U8 *value = command;
2878 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2879
2880 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2881 value = value + 26;
2882 /* Convert the value from ascii to integer */
2883 ret = kstrtou8(value, 10, &minTime);
2884 if (ret < 0)
2885 {
2886 /* If the input value is greater than max value of datatype, then also
2887 kstrtou8 fails */
2888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2889 "%s: kstrtou8 failed range [%d - %d]", __func__,
2890 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2891 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2892 ret = -EINVAL;
2893 goto exit;
2894 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002895 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2896 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2897 {
2898 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2899 "scan min channel time value %d is out of range"
2900 " (Min: %d Max: %d)", minTime,
2901 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2902 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2903 ret = -EINVAL;
2904 goto exit;
2905 }
2906
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302907 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2908 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2909 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2911 "%s: Received Command to change channel min time = %d", __func__, minTime);
2912
2913 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2914 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2915 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002916 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2917 {
2918 tANI_U8 *value = command;
2919 tANI_U8 channel = 0;
2920 tANI_U8 dwellTime = 0;
2921 tANI_U8 bufLen = 0;
2922 tANI_U8 *buf = NULL;
2923 tSirMacAddr targetApBssid;
2924 eHalStatus status = eHAL_STATUS_SUCCESS;
2925 struct ieee80211_channel chan;
2926 tANI_U8 finalLen = 0;
2927 tANI_U8 *finalBuf = NULL;
2928 tANI_U8 temp = 0;
2929 u64 cookie;
2930 hdd_station_ctx_t *pHddStaCtx = NULL;
2931 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2932
2933 /* if not associated, no need to send action frame */
2934 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2935 {
2936 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2937 ret = -EINVAL;
2938 goto exit;
2939 }
2940
2941 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2942 &dwellTime, &buf, &bufLen);
2943 if (eHAL_STATUS_SUCCESS != status)
2944 {
2945 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2946 "%s: Failed to parse send action frame data", __func__);
2947 ret = -EINVAL;
2948 goto exit;
2949 }
2950
2951 /* if the target bssid is different from currently associated AP,
2952 then no need to send action frame */
2953 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2954 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2955 {
2956 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2957 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002958 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002959 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002960 goto exit;
2961 }
2962
2963 /* if the channel number is different from operating channel then
2964 no need to send action frame */
2965 if (channel != pHddStaCtx->conn_info.operationChannel)
2966 {
2967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2968 "%s: channel(%d) is different from operating channel(%d)",
2969 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2970 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002971 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002972 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002973 goto exit;
2974 }
2975 chan.center_freq = sme_ChnToFreq(channel);
2976
2977 finalLen = bufLen + 24;
2978 finalBuf = vos_mem_malloc(finalLen);
2979 if (NULL == finalBuf)
2980 {
2981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2982 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002983 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002984 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002985 goto exit;
2986 }
2987 vos_mem_zero(finalBuf, finalLen);
2988
2989 /* Fill subtype */
2990 temp = SIR_MAC_MGMT_ACTION << 4;
2991 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2992
2993 /* Fill type */
2994 temp = SIR_MAC_MGMT_FRAME;
2995 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2996
2997 /* Fill destination address (bssid of the AP) */
2998 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2999
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003000 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003001 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3002
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003003 /* Fill BSSID (AP mac address) */
3004 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003005
3006 /* Fill received buffer from 24th address */
3007 vos_mem_copy(finalBuf + 24, buf, bufLen);
3008
Jeff Johnson11c33152013-04-16 17:52:40 -07003009 /* done with the parsed buffer */
3010 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003011 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003012
DARAM SUDHA39eede62014-02-12 11:16:40 +05303013 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003014#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3015 &(pAdapter->wdev),
3016#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003017 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003018#endif
3019 &chan, 0,
3020#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3021 NL80211_CHAN_HT20, 1,
3022#endif
3023 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003024 1, &cookie );
3025 vos_mem_free(finalBuf);
3026 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003027 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3028 {
3029 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3030 char extra[32];
3031 tANI_U8 len = 0;
3032
3033 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003034 len = scnprintf(extra, sizeof(extra), "%s %d",
3035 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303036 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3037 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3038 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003039 if (copy_to_user(priv_data.buf, &extra, len + 1))
3040 {
3041 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3042 "%s: failed to copy data to user buffer", __func__);
3043 ret = -EFAULT;
3044 goto exit;
3045 }
3046 }
3047 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3048 {
3049 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003050 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003051
3052 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3053 value = value + 19;
3054 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003055 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003056 if (ret < 0)
3057 {
3058 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003059 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003060 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003061 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003062 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3063 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3064 ret = -EINVAL;
3065 goto exit;
3066 }
3067
3068 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3069 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3070 {
3071 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3072 "lfr mode value %d is out of range"
3073 " (Min: %d Max: %d)", maxTime,
3074 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3075 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3076 ret = -EINVAL;
3077 goto exit;
3078 }
3079
3080 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3081 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3082
3083 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3084 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3085 }
3086 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3087 {
3088 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3089 char extra[32];
3090 tANI_U8 len = 0;
3091
3092 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003093 len = scnprintf(extra, sizeof(extra), "%s %d",
3094 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003095 if (copy_to_user(priv_data.buf, &extra, len + 1))
3096 {
3097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3098 "%s: failed to copy data to user buffer", __func__);
3099 ret = -EFAULT;
3100 goto exit;
3101 }
3102 }
3103 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3104 {
3105 tANI_U8 *value = command;
3106 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3107
3108 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3109 value = value + 16;
3110 /* Convert the value from ascii to integer */
3111 ret = kstrtou16(value, 10, &val);
3112 if (ret < 0)
3113 {
3114 /* If the input value is greater than max value of datatype, then also
3115 kstrtou16 fails */
3116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3117 "%s: kstrtou16 failed range [%d - %d]", __func__,
3118 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3119 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3120 ret = -EINVAL;
3121 goto exit;
3122 }
3123
3124 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3125 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3126 {
3127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3128 "scan home time value %d is out of range"
3129 " (Min: %d Max: %d)", val,
3130 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3131 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3132 ret = -EINVAL;
3133 goto exit;
3134 }
3135
3136 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3137 "%s: Received Command to change scan home time = %d", __func__, val);
3138
3139 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3140 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3141 }
3142 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3143 {
3144 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3145 char extra[32];
3146 tANI_U8 len = 0;
3147
3148 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003149 len = scnprintf(extra, sizeof(extra), "%s %d",
3150 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003151 if (copy_to_user(priv_data.buf, &extra, len + 1))
3152 {
3153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3154 "%s: failed to copy data to user buffer", __func__);
3155 ret = -EFAULT;
3156 goto exit;
3157 }
3158 }
3159 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3160 {
3161 tANI_U8 *value = command;
3162 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3163
3164 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3165 value = value + 17;
3166 /* Convert the value from ascii to integer */
3167 ret = kstrtou8(value, 10, &val);
3168 if (ret < 0)
3169 {
3170 /* If the input value is greater than max value of datatype, then also
3171 kstrtou8 fails */
3172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3173 "%s: kstrtou8 failed range [%d - %d]", __func__,
3174 CFG_ROAM_INTRA_BAND_MIN,
3175 CFG_ROAM_INTRA_BAND_MAX);
3176 ret = -EINVAL;
3177 goto exit;
3178 }
3179
3180 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3181 (val > CFG_ROAM_INTRA_BAND_MAX))
3182 {
3183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3184 "intra band mode value %d is out of range"
3185 " (Min: %d Max: %d)", val,
3186 CFG_ROAM_INTRA_BAND_MIN,
3187 CFG_ROAM_INTRA_BAND_MAX);
3188 ret = -EINVAL;
3189 goto exit;
3190 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3192 "%s: Received Command to change intra band = %d", __func__, val);
3193
3194 pHddCtx->cfg_ini->nRoamIntraBand = val;
3195 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3196 }
3197 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3198 {
3199 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3200 char extra[32];
3201 tANI_U8 len = 0;
3202
3203 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003204 len = scnprintf(extra, sizeof(extra), "%s %d",
3205 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003206 if (copy_to_user(priv_data.buf, &extra, len + 1))
3207 {
3208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3209 "%s: failed to copy data to user buffer", __func__);
3210 ret = -EFAULT;
3211 goto exit;
3212 }
3213 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003214 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3215 {
3216 tANI_U8 *value = command;
3217 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3218
3219 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3220 value = value + 15;
3221 /* Convert the value from ascii to integer */
3222 ret = kstrtou8(value, 10, &nProbes);
3223 if (ret < 0)
3224 {
3225 /* If the input value is greater than max value of datatype, then also
3226 kstrtou8 fails */
3227 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3228 "%s: kstrtou8 failed range [%d - %d]", __func__,
3229 CFG_ROAM_SCAN_N_PROBES_MIN,
3230 CFG_ROAM_SCAN_N_PROBES_MAX);
3231 ret = -EINVAL;
3232 goto exit;
3233 }
3234
3235 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3236 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3237 {
3238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3239 "NProbes value %d is out of range"
3240 " (Min: %d Max: %d)", nProbes,
3241 CFG_ROAM_SCAN_N_PROBES_MIN,
3242 CFG_ROAM_SCAN_N_PROBES_MAX);
3243 ret = -EINVAL;
3244 goto exit;
3245 }
3246
3247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3248 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3249
3250 pHddCtx->cfg_ini->nProbes = nProbes;
3251 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3252 }
3253 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
3254 {
3255 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3256 char extra[32];
3257 tANI_U8 len = 0;
3258
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003259 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003260 if (copy_to_user(priv_data.buf, &extra, len + 1))
3261 {
3262 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3263 "%s: failed to copy data to user buffer", __func__);
3264 ret = -EFAULT;
3265 goto exit;
3266 }
3267 }
3268 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3269 {
3270 tANI_U8 *value = command;
3271 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3272
3273 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3274 /* input value is in units of msec */
3275 value = value + 20;
3276 /* Convert the value from ascii to integer */
3277 ret = kstrtou16(value, 10, &homeAwayTime);
3278 if (ret < 0)
3279 {
3280 /* If the input value is greater than max value of datatype, then also
3281 kstrtou8 fails */
3282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3283 "%s: kstrtou8 failed range [%d - %d]", __func__,
3284 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3285 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3286 ret = -EINVAL;
3287 goto exit;
3288 }
3289
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003290 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3291 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3292 {
3293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3294 "homeAwayTime value %d is out of range"
3295 " (Min: %d Max: %d)", homeAwayTime,
3296 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3297 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3298 ret = -EINVAL;
3299 goto exit;
3300 }
3301
3302 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3303 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003304 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3305 {
3306 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3307 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3308 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003309 }
3310 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3311 {
3312 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3313 char extra[32];
3314 tANI_U8 len = 0;
3315
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003316 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003317 if (copy_to_user(priv_data.buf, &extra, len + 1))
3318 {
3319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3320 "%s: failed to copy data to user buffer", __func__);
3321 ret = -EFAULT;
3322 goto exit;
3323 }
3324 }
3325 else if (strncmp(command, "REASSOC", 7) == 0)
3326 {
3327 tANI_U8 *value = command;
3328 tANI_U8 channel = 0;
3329 tSirMacAddr targetApBssid;
3330 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003331#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3332 tCsrHandoffRequest handoffInfo;
3333#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003334 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003335 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3336
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003337 /* if not associated, no need to proceed with reassoc */
3338 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3339 {
3340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3341 ret = -EINVAL;
3342 goto exit;
3343 }
3344
3345 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3346 if (eHAL_STATUS_SUCCESS != status)
3347 {
3348 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3349 "%s: Failed to parse reassoc command data", __func__);
3350 ret = -EINVAL;
3351 goto exit;
3352 }
3353
3354 /* if the target bssid is same as currently associated AP,
3355 then no need to proceed with reassoc */
3356 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3357 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3358 {
3359 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3360 ret = -EINVAL;
3361 goto exit;
3362 }
3363
3364 /* Check channel number is a valid channel number */
3365 if(VOS_STATUS_SUCCESS !=
3366 wlan_hdd_validate_operation_channel(pAdapter, channel))
3367 {
3368 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003369 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003370 return -EINVAL;
3371 }
3372
3373 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003374#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3375 handoffInfo.channel = channel;
3376 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3377 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3378#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003379 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003380 else if (strncmp(command, "SETWESMODE", 10) == 0)
3381 {
3382 tANI_U8 *value = command;
3383 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3384
3385 /* Move pointer to ahead of SETWESMODE<delimiter> */
3386 value = value + 11;
3387 /* Convert the value from ascii to integer */
3388 ret = kstrtou8(value, 10, &wesMode);
3389 if (ret < 0)
3390 {
3391 /* If the input value is greater than max value of datatype, then also
3392 kstrtou8 fails */
3393 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3394 "%s: kstrtou8 failed range [%d - %d]", __func__,
3395 CFG_ENABLE_WES_MODE_NAME_MIN,
3396 CFG_ENABLE_WES_MODE_NAME_MAX);
3397 ret = -EINVAL;
3398 goto exit;
3399 }
3400
3401 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3402 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3403 {
3404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3405 "WES Mode value %d is out of range"
3406 " (Min: %d Max: %d)", wesMode,
3407 CFG_ENABLE_WES_MODE_NAME_MIN,
3408 CFG_ENABLE_WES_MODE_NAME_MAX);
3409 ret = -EINVAL;
3410 goto exit;
3411 }
3412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3413 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3414
3415 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3416 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3417 }
3418 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3419 {
3420 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3421 char extra[32];
3422 tANI_U8 len = 0;
3423
Arif Hussain826d9412013-11-12 16:44:54 -08003424 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003425 if (copy_to_user(priv_data.buf, &extra, len + 1))
3426 {
3427 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3428 "%s: failed to copy data to user buffer", __func__);
3429 ret = -EFAULT;
3430 goto exit;
3431 }
3432 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003433#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003434#ifdef FEATURE_WLAN_LFR
3435 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3436 {
3437 tANI_U8 *value = command;
3438 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3439
3440 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3441 value = value + 12;
3442 /* Convert the value from ascii to integer */
3443 ret = kstrtou8(value, 10, &lfrMode);
3444 if (ret < 0)
3445 {
3446 /* If the input value is greater than max value of datatype, then also
3447 kstrtou8 fails */
3448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3449 "%s: kstrtou8 failed range [%d - %d]", __func__,
3450 CFG_LFR_FEATURE_ENABLED_MIN,
3451 CFG_LFR_FEATURE_ENABLED_MAX);
3452 ret = -EINVAL;
3453 goto exit;
3454 }
3455
3456 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3457 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3458 {
3459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3460 "lfr mode value %d is out of range"
3461 " (Min: %d Max: %d)", lfrMode,
3462 CFG_LFR_FEATURE_ENABLED_MIN,
3463 CFG_LFR_FEATURE_ENABLED_MAX);
3464 ret = -EINVAL;
3465 goto exit;
3466 }
3467
3468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3469 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3470
3471 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3472 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3473 }
3474#endif
3475#ifdef WLAN_FEATURE_VOWIFI_11R
3476 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3477 {
3478 tANI_U8 *value = command;
3479 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3480
3481 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3482 value = value + 18;
3483 /* Convert the value from ascii to integer */
3484 ret = kstrtou8(value, 10, &ft);
3485 if (ret < 0)
3486 {
3487 /* If the input value is greater than max value of datatype, then also
3488 kstrtou8 fails */
3489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3490 "%s: kstrtou8 failed range [%d - %d]", __func__,
3491 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3492 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3493 ret = -EINVAL;
3494 goto exit;
3495 }
3496
3497 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3498 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3499 {
3500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3501 "ft mode value %d is out of range"
3502 " (Min: %d Max: %d)", ft,
3503 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3504 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3505 ret = -EINVAL;
3506 goto exit;
3507 }
3508
3509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3510 "%s: Received Command to change ft mode = %d", __func__, ft);
3511
3512 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3513 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3514 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303515
3516 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3517 {
3518 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303519 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303520 tSirMacAddr targetApBssid;
3521 tANI_U8 trigger = 0;
3522 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303523 tHalHandle hHal;
3524 v_U32_t roamId = 0;
3525 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303526 hdd_station_ctx_t *pHddStaCtx = NULL;
3527 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303528 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303529
3530 /* if not associated, no need to proceed with reassoc */
3531 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3532 {
3533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3534 ret = -EINVAL;
3535 goto exit;
3536 }
3537
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303538 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303539 if (eHAL_STATUS_SUCCESS != status)
3540 {
3541 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3542 "%s: Failed to parse reassoc command data", __func__);
3543 ret = -EINVAL;
3544 goto exit;
3545 }
3546
3547 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303548 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303549 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3550 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3551 {
3552 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3553 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3554 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303555 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3556 &modProfileFields);
3557 sme_RoamReassoc(hHal, pAdapter->sessionId,
3558 NULL, modProfileFields, &roamId, 1);
3559 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303560 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303561
3562 /* Check channel number is a valid channel number */
3563 if(VOS_STATUS_SUCCESS !=
3564 wlan_hdd_validate_operation_channel(pAdapter, channel))
3565 {
3566 hddLog(VOS_TRACE_LEVEL_ERROR,
3567 "%s: Invalid Channel [%d]", __func__, channel);
3568 return -EINVAL;
3569 }
3570
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303571 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303572
3573 /* Proceed with scan/roam */
3574 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3575 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303576 (tSmeFastRoamTrigger)(trigger),
3577 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303578 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003579#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003580#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003581 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3582 {
3583 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003584 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003585
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003586 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003587 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003588 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003589 hdd_is_okc_mode_enabled(pHddCtx) &&
3590 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3591 {
3592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003593 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003594 " hence this operation is not permitted!", __func__);
3595 ret = -EPERM;
3596 goto exit;
3597 }
3598
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003599 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3600 value = value + 11;
3601 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003602 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003603 if (ret < 0)
3604 {
3605 /* If the input value is greater than max value of datatype, then also
3606 kstrtou8 fails */
3607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3608 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003609 CFG_ESE_FEATURE_ENABLED_MIN,
3610 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003611 ret = -EINVAL;
3612 goto exit;
3613 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003614 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3615 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003616 {
3617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003618 "Ese mode value %d is out of range"
3619 " (Min: %d Max: %d)", eseMode,
3620 CFG_ESE_FEATURE_ENABLED_MIN,
3621 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003622 ret = -EINVAL;
3623 goto exit;
3624 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003626 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003627
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003628 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3629 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003630 }
3631#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003632 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3633 {
3634 tANI_U8 *value = command;
3635 tANI_BOOLEAN roamScanControl = 0;
3636
3637 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3638 value = value + 19;
3639 /* Convert the value from ascii to integer */
3640 ret = kstrtou8(value, 10, &roamScanControl);
3641 if (ret < 0)
3642 {
3643 /* If the input value is greater than max value of datatype, then also
3644 kstrtou8 fails */
3645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3646 "%s: kstrtou8 failed ", __func__);
3647 ret = -EINVAL;
3648 goto exit;
3649 }
3650
3651 if (0 != roamScanControl)
3652 {
3653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3654 "roam scan control invalid value = %d",
3655 roamScanControl);
3656 ret = -EINVAL;
3657 goto exit;
3658 }
3659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3660 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3661
3662 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3663 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003664#ifdef FEATURE_WLAN_OKC
3665 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3666 {
3667 tANI_U8 *value = command;
3668 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3669
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003670 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003671 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003672 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003673 hdd_is_okc_mode_enabled(pHddCtx) &&
3674 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3675 {
3676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003677 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003678 " hence this operation is not permitted!", __func__);
3679 ret = -EPERM;
3680 goto exit;
3681 }
3682
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003683 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3684 value = value + 11;
3685 /* Convert the value from ascii to integer */
3686 ret = kstrtou8(value, 10, &okcMode);
3687 if (ret < 0)
3688 {
3689 /* If the input value is greater than max value of datatype, then also
3690 kstrtou8 fails */
3691 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3692 "%s: kstrtou8 failed range [%d - %d]", __func__,
3693 CFG_OKC_FEATURE_ENABLED_MIN,
3694 CFG_OKC_FEATURE_ENABLED_MAX);
3695 ret = -EINVAL;
3696 goto exit;
3697 }
3698
3699 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3700 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3701 {
3702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3703 "Okc mode value %d is out of range"
3704 " (Min: %d Max: %d)", okcMode,
3705 CFG_OKC_FEATURE_ENABLED_MIN,
3706 CFG_OKC_FEATURE_ENABLED_MAX);
3707 ret = -EINVAL;
3708 goto exit;
3709 }
3710
3711 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3712 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3713
3714 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3715 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003716#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003717 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3718 {
3719 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3720 char extra[32];
3721 tANI_U8 len = 0;
3722
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003723 len = scnprintf(extra, sizeof(extra), "%s %d",
3724 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003725 if (copy_to_user(priv_data.buf, &extra, len + 1))
3726 {
3727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3728 "%s: failed to copy data to user buffer", __func__);
3729 ret = -EFAULT;
3730 goto exit;
3731 }
3732 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303733#ifdef WLAN_FEATURE_PACKET_FILTERING
3734 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3735 {
3736 tANI_U8 filterType = 0;
3737 tANI_U8 *value = command;
3738
3739 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3740 value = value + 22;
3741
3742 /* Convert the value from ascii to integer */
3743 ret = kstrtou8(value, 10, &filterType);
3744 if (ret < 0)
3745 {
3746 /* If the input value is greater than max value of datatype,
3747 * then also kstrtou8 fails
3748 */
3749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3750 "%s: kstrtou8 failed range ", __func__);
3751 ret = -EINVAL;
3752 goto exit;
3753 }
3754
3755 if (filterType != 0 && filterType != 1)
3756 {
3757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3758 "%s: Accepted Values are 0 and 1 ", __func__);
3759 ret = -EINVAL;
3760 goto exit;
3761 }
3762 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3763 pAdapter->sessionId);
3764 }
3765#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303766 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3767 {
Kiet Lamad161252014-07-22 11:23:32 -07003768 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303769 int ret;
3770
Kiet Lamad161252014-07-22 11:23:32 -07003771 dhcpPhase = command + 11;
3772 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303773 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303774 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003775 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303776
3777 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003778
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303779 ret = wlan_hdd_scan_abort(pAdapter);
3780 if (ret < 0)
3781 {
3782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3783 FL("failed to abort existing scan %d"), ret);
3784 }
3785
Kiet Lamad161252014-07-22 11:23:32 -07003786 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3787 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303788 }
Kiet Lamad161252014-07-22 11:23:32 -07003789 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303790 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003792 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303793
3794 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003795
3796 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3797 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303798 }
3799 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003800 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3801 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3803 FL("making default scan to ACTIVE"));
3804 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003805 }
3806 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3807 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3809 FL("making default scan to PASSIVE"));
3810 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003811 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303812 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3813 {
3814 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3815 char extra[32];
3816 tANI_U8 len = 0;
3817
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303818 memset(extra, 0, sizeof(extra));
3819 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3820 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303821 {
3822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3823 "%s: failed to copy data to user buffer", __func__);
3824 ret = -EFAULT;
3825 goto exit;
3826 }
3827 ret = len;
3828 }
3829 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3830 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303831 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303832 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003833 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3834 {
3835 tANI_U8 filterType = 0;
3836 tANI_U8 *value;
3837 value = command + 9;
3838
3839 /* Convert the value from ascii to integer */
3840 ret = kstrtou8(value, 10, &filterType);
3841 if (ret < 0)
3842 {
3843 /* If the input value is greater than max value of datatype,
3844 * then also kstrtou8 fails
3845 */
3846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3847 "%s: kstrtou8 failed range ", __func__);
3848 ret = -EINVAL;
3849 goto exit;
3850 }
3851 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3852 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3853 {
3854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3855 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3856 " 2-Sink ", __func__);
3857 ret = -EINVAL;
3858 goto exit;
3859 }
3860 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3861 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303862 pScanInfo = &pHddCtx->scan_info;
3863 if (filterType && pScanInfo != NULL &&
3864 pHddCtx->scan_info.mScanPending)
3865 {
3866 /*Miracast Session started. Abort Scan */
3867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3868 "%s, Aborting Scan For Miracast",__func__);
3869 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3870 eCSR_SCAN_ABORT_DEFAULT);
3871 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003872 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303873 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003874 }
Leo Chang614d2072013-08-22 14:59:44 -07003875 else if (strncmp(command, "SETMCRATE", 9) == 0)
3876 {
Leo Chang614d2072013-08-22 14:59:44 -07003877 tANI_U8 *value = command;
3878 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003879 tSirRateUpdateInd *rateUpdate;
3880 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003881
3882 /* Only valid for SAP mode */
3883 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3884 {
3885 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3886 "%s: SAP mode is not running", __func__);
3887 ret = -EFAULT;
3888 goto exit;
3889 }
3890
3891 /* Move pointer to ahead of SETMCRATE<delimiter> */
3892 /* input value is in units of hundred kbps */
3893 value = value + 10;
3894 /* Convert the value from ascii to integer, decimal base */
3895 ret = kstrtouint(value, 10, &targetRate);
3896
Leo Chang1f98cbd2013-10-17 15:03:52 -07003897 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3898 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003899 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003900 hddLog(VOS_TRACE_LEVEL_ERROR,
3901 "%s: SETMCRATE indication alloc fail", __func__);
3902 ret = -EFAULT;
3903 goto exit;
3904 }
3905 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3906
3907 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3908 "MC Target rate %d", targetRate);
3909 /* Ignore unicast */
3910 rateUpdate->ucastDataRate = -1;
3911 rateUpdate->mcastDataRate24GHz = targetRate;
3912 rateUpdate->mcastDataRate5GHz = targetRate;
3913 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3914 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3915 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3916 if (eHAL_STATUS_SUCCESS != status)
3917 {
3918 hddLog(VOS_TRACE_LEVEL_ERROR,
3919 "%s: SET_MC_RATE failed", __func__);
3920 vos_mem_free(rateUpdate);
3921 ret = -EFAULT;
3922 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003923 }
3924 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303925#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003926 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303927 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003928 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303929 }
3930#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003931#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003932 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3933 {
3934 tANI_U8 *value = command;
3935 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3936 tANI_U8 numChannels = 0;
3937 eHalStatus status = eHAL_STATUS_SUCCESS;
3938
3939 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3940 if (eHAL_STATUS_SUCCESS != status)
3941 {
3942 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3943 "%s: Failed to parse channel list information", __func__);
3944 ret = -EINVAL;
3945 goto exit;
3946 }
3947
3948 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3949 {
3950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3951 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3952 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3953 ret = -EINVAL;
3954 goto exit;
3955 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003956 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003957 ChannelList,
3958 numChannels);
3959 if (eHAL_STATUS_SUCCESS != status)
3960 {
3961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3962 "%s: Failed to update channel list information", __func__);
3963 ret = -EINVAL;
3964 goto exit;
3965 }
3966 }
3967 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3968 {
3969 tANI_U8 *value = command;
3970 char extra[128] = {0};
3971 int len = 0;
3972 tANI_U8 tid = 0;
3973 hdd_station_ctx_t *pHddStaCtx = NULL;
3974 tAniTrafStrmMetrics tsmMetrics;
3975 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3976
3977 /* if not associated, return error */
3978 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3979 {
3980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3981 ret = -EINVAL;
3982 goto exit;
3983 }
3984
3985 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3986 value = value + 12;
3987 /* Convert the value from ascii to integer */
3988 ret = kstrtou8(value, 10, &tid);
3989 if (ret < 0)
3990 {
3991 /* If the input value is greater than max value of datatype, then also
3992 kstrtou8 fails */
3993 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3994 "%s: kstrtou8 failed range [%d - %d]", __func__,
3995 TID_MIN_VALUE,
3996 TID_MAX_VALUE);
3997 ret = -EINVAL;
3998 goto exit;
3999 }
4000
4001 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4002 {
4003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4004 "tid value %d is out of range"
4005 " (Min: %d Max: %d)", tid,
4006 TID_MIN_VALUE,
4007 TID_MAX_VALUE);
4008 ret = -EINVAL;
4009 goto exit;
4010 }
4011
4012 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4013 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4014
4015 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4016 {
4017 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4018 "%s: failed to get tsm stats", __func__);
4019 ret = -EFAULT;
4020 goto exit;
4021 }
4022
4023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4024 "UplinkPktQueueDly(%d)\n"
4025 "UplinkPktQueueDlyHist[0](%d)\n"
4026 "UplinkPktQueueDlyHist[1](%d)\n"
4027 "UplinkPktQueueDlyHist[2](%d)\n"
4028 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304029 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004030 "UplinkPktLoss(%d)\n"
4031 "UplinkPktCount(%d)\n"
4032 "RoamingCount(%d)\n"
4033 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4034 tsmMetrics.UplinkPktQueueDlyHist[0],
4035 tsmMetrics.UplinkPktQueueDlyHist[1],
4036 tsmMetrics.UplinkPktQueueDlyHist[2],
4037 tsmMetrics.UplinkPktQueueDlyHist[3],
4038 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4039 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4040
4041 /* Output TSM stats is of the format
4042 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4043 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004044 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004045 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4046 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4047 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4048 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4049 tsmMetrics.RoamingDly);
4050
4051 if (copy_to_user(priv_data.buf, &extra, len + 1))
4052 {
4053 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4054 "%s: failed to copy data to user buffer", __func__);
4055 ret = -EFAULT;
4056 goto exit;
4057 }
4058 }
4059 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4060 {
4061 tANI_U8 *value = command;
4062 tANI_U8 *cckmIe = NULL;
4063 tANI_U8 cckmIeLen = 0;
4064 eHalStatus status = eHAL_STATUS_SUCCESS;
4065
4066 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4067 if (eHAL_STATUS_SUCCESS != status)
4068 {
4069 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4070 "%s: Failed to parse cckm ie data", __func__);
4071 ret = -EINVAL;
4072 goto exit;
4073 }
4074
4075 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4076 {
4077 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4078 "%s: CCKM Ie input length is more than max[%d]", __func__,
4079 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004080 vos_mem_free(cckmIe);
4081 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004082 ret = -EINVAL;
4083 goto exit;
4084 }
4085 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004086 vos_mem_free(cckmIe);
4087 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004088 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004089 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4090 {
4091 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004092 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004093 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004094
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004095 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004096 if (eHAL_STATUS_SUCCESS != status)
4097 {
4098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004099 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004100 ret = -EINVAL;
4101 goto exit;
4102 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004103 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4104 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4105 hdd_indicateEseBcnReportNoResults (pAdapter,
4106 eseBcnReq.bcnReq[0].measurementToken,
4107 0x02, //BIT(1) set for measurement done
4108 0); // no BSS
4109 goto exit;
4110 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004111
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004112 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4113 if (eHAL_STATUS_SUCCESS != status)
4114 {
4115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4116 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4117 ret = -EINVAL;
4118 goto exit;
4119 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004120 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004121#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304122 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4123 {
4124 eHalStatus status;
4125 char buf[32], len;
4126 long waitRet;
4127 bcnMissRateContext_t getBcnMissRateCtx;
4128
4129 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4130
4131 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4132 {
4133 hddLog(VOS_TRACE_LEVEL_WARN,
4134 FL("GETBCNMISSRATE: STA is not in connected state"));
4135 ret = -1;
4136 goto exit;
4137 }
4138
4139 init_completion(&(getBcnMissRateCtx.completion));
4140 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4141
4142 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4143 pAdapter->sessionId,
4144 (void *)getBcnMissRateCB,
4145 (void *)(&getBcnMissRateCtx));
4146 if( eHAL_STATUS_SUCCESS != status)
4147 {
4148 hddLog(VOS_TRACE_LEVEL_INFO,
4149 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4150 ret = -EINVAL;
4151 goto exit;
4152 }
4153
4154 waitRet = wait_for_completion_interruptible_timeout
4155 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4156 if(waitRet <= 0)
4157 {
4158 hddLog(VOS_TRACE_LEVEL_ERROR,
4159 FL("failed to wait on bcnMissRateComp %d"), ret);
4160
4161 //Make magic number to zero so that callback is not called.
4162 spin_lock(&hdd_context_lock);
4163 getBcnMissRateCtx.magic = 0x0;
4164 spin_unlock(&hdd_context_lock);
4165 ret = -EINVAL;
4166 goto exit;
4167 }
4168
4169 hddLog(VOS_TRACE_LEVEL_INFO,
4170 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4171
4172 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4173 if (copy_to_user(priv_data.buf, &buf, len + 1))
4174 {
4175 hddLog(VOS_TRACE_LEVEL_ERROR,
4176 "%s: failed to copy data to user buffer", __func__);
4177 ret = -EFAULT;
4178 goto exit;
4179 }
4180 ret = len;
4181 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304182#ifdef FEATURE_WLAN_TDLS
4183 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4184 tANI_U8 *value = command;
4185 int set_value;
4186 /* Move pointer to ahead of TDLSOFFCH*/
4187 value += 26;
4188 sscanf(value, "%d", &set_value);
4189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4190 "%s: Tdls offchannel offset:%d",
4191 __func__, set_value);
4192 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4193 if (ret < 0)
4194 {
4195 ret = -EINVAL;
4196 goto exit;
4197 }
4198
4199 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4200 tANI_U8 *value = command;
4201 int set_value;
4202 /* Move pointer to ahead of tdlsoffchnmode*/
4203 value += 18;
4204 sscanf(value, "%d", &set_value);
4205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4206 "%s: Tdls offchannel mode:%d",
4207 __func__, set_value);
4208 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4209 if (ret < 0)
4210 {
4211 ret = -EINVAL;
4212 goto exit;
4213 }
4214 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4215 tANI_U8 *value = command;
4216 int set_value;
4217 /* Move pointer to ahead of TDLSOFFCH*/
4218 value += 14;
4219 sscanf(value, "%d", &set_value);
4220 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4221 "%s: Tdls offchannel num: %d",
4222 __func__, set_value);
4223 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4224 if (ret < 0)
4225 {
4226 ret = -EINVAL;
4227 goto exit;
4228 }
4229 }
4230#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304231 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4232 {
4233 eHalStatus status;
4234 char *buf = NULL;
4235 char len;
4236 long waitRet;
4237 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304238 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304239 tANI_U8 *ptr = command;
4240 int stats = *(ptr + 11) - '0';
4241
4242 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4243 if (!IS_FEATURE_FW_STATS_ENABLE)
4244 {
4245 hddLog(VOS_TRACE_LEVEL_INFO,
4246 FL("Get Firmware stats feature not supported"));
4247 ret = -EINVAL;
4248 goto exit;
4249 }
4250
4251 if (FW_STATS_MAX <= stats || 0 >= stats)
4252 {
4253 hddLog(VOS_TRACE_LEVEL_INFO,
4254 FL(" stats %d not supported"),stats);
4255 ret = -EINVAL;
4256 goto exit;
4257 }
4258
4259 init_completion(&(fwStatsCtx.completion));
4260 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4261 fwStatsCtx.pAdapter = pAdapter;
4262 fwStatsRsp->type = 0;
4263 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304264 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304265 if (eHAL_STATUS_SUCCESS != status)
4266 {
4267 hddLog(VOS_TRACE_LEVEL_ERROR,
4268 FL(" fail to post WDA cmd status = %d"), status);
4269 ret = -EINVAL;
4270 goto exit;
4271 }
4272 waitRet = wait_for_completion_timeout
4273 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4274 if (waitRet <= 0)
4275 {
4276 hddLog(VOS_TRACE_LEVEL_ERROR,
4277 FL("failed to wait on GwtFwstats"));
4278 //Make magic number to zero so that callback is not executed.
4279 spin_lock(&hdd_context_lock);
4280 fwStatsCtx.magic = 0x0;
4281 spin_unlock(&hdd_context_lock);
4282 ret = -EINVAL;
4283 goto exit;
4284 }
4285 if (fwStatsRsp->type)
4286 {
4287 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4288 if (!buf)
4289 {
4290 hddLog(VOS_TRACE_LEVEL_ERROR,
4291 FL(" failed to allocate memory"));
4292 ret = -ENOMEM;
4293 goto exit;
4294 }
4295 switch( fwStatsRsp->type )
4296 {
4297 case FW_UBSP_STATS:
4298 {
4299 len = snprintf(buf, FW_STATE_RSP_LEN,
4300 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304301 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4302 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304303 }
4304 break;
4305 default:
4306 {
4307 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4308 ret = -EFAULT;
4309 kfree(buf);
4310 goto exit;
4311 }
4312 }
4313 if (copy_to_user(priv_data.buf, buf, len + 1))
4314 {
4315 hddLog(VOS_TRACE_LEVEL_ERROR,
4316 FL(" failed to copy data to user buffer"));
4317 ret = -EFAULT;
4318 kfree(buf);
4319 goto exit;
4320 }
4321 ret = len;
4322 kfree(buf);
4323 }
4324 else
4325 {
4326 hddLog(VOS_TRACE_LEVEL_ERROR,
4327 FL("failed to fetch the stats"));
4328 ret = -EFAULT;
4329 goto exit;
4330 }
4331
4332 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004333 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304334 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4335 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4336 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304337 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4338 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004339 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004340 }
4341exit:
4342 if (command)
4343 {
4344 kfree(command);
4345 }
4346 return ret;
4347}
4348
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004349#ifdef CONFIG_COMPAT
4350static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4351{
4352 struct {
4353 compat_uptr_t buf;
4354 int used_len;
4355 int total_len;
4356 } compat_priv_data;
4357 hdd_priv_data_t priv_data;
4358 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004359
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004360 /*
4361 * Note that pAdapter and ifr have already been verified by caller,
4362 * and HDD context has also been validated
4363 */
4364 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4365 sizeof(compat_priv_data))) {
4366 ret = -EFAULT;
4367 goto exit;
4368 }
4369 priv_data.buf = compat_ptr(compat_priv_data.buf);
4370 priv_data.used_len = compat_priv_data.used_len;
4371 priv_data.total_len = compat_priv_data.total_len;
4372 ret = hdd_driver_command(pAdapter, &priv_data);
4373 exit:
4374 return ret;
4375}
4376#else /* CONFIG_COMPAT */
4377static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4378{
4379 /* will never be invoked */
4380 return 0;
4381}
4382#endif /* CONFIG_COMPAT */
4383
4384static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4385{
4386 hdd_priv_data_t priv_data;
4387 int ret = 0;
4388
4389 /*
4390 * Note that pAdapter and ifr have already been verified by caller,
4391 * and HDD context has also been validated
4392 */
4393 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4394 ret = -EFAULT;
4395 } else {
4396 ret = hdd_driver_command(pAdapter, &priv_data);
4397 }
4398 return ret;
4399}
4400
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304401int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004402{
4403 hdd_adapter_t *pAdapter;
4404 hdd_context_t *pHddCtx;
4405 int ret;
4406
4407 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4408 if (NULL == pAdapter) {
4409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4410 "%s: HDD adapter context is Null", __func__);
4411 ret = -ENODEV;
4412 goto exit;
4413 }
4414 if (dev != pAdapter->dev) {
4415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4416 "%s: HDD adapter/dev inconsistency", __func__);
4417 ret = -ENODEV;
4418 goto exit;
4419 }
4420
4421 if ((!ifr) || (!ifr->ifr_data)) {
4422 ret = -EINVAL;
4423 goto exit;
4424 }
4425
4426 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4427 ret = wlan_hdd_validate_context(pHddCtx);
4428 if (ret) {
Mahesh A Saptasagar5b16d0a2014-11-03 17:55:29 +05304429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004430 "%s: invalid context", __func__);
4431 ret = -EBUSY;
4432 goto exit;
4433 }
4434
4435 switch (cmd) {
4436 case (SIOCDEVPRIVATE + 1):
4437 if (is_compat_task())
4438 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4439 else
4440 ret = hdd_driver_ioctl(pAdapter, ifr);
4441 break;
4442 default:
4443 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4444 __func__, cmd);
4445 ret = -EINVAL;
4446 break;
4447 }
4448 exit:
4449 return ret;
4450}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004451
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304452int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4453{
4454 int ret;
4455
4456 vos_ssr_protect(__func__);
4457 ret = __hdd_ioctl(dev, ifr, cmd);
4458 vos_ssr_unprotect(__func__);
4459
4460 return ret;
4461}
4462
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004463#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004464/**---------------------------------------------------------------------------
4465
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004466 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004467
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004468 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004469 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4470 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4471 <space>Scan Mode N<space>Meas Duration N
4472 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4473 then take N.
4474 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4475 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4476 This function does not take care of removing duplicate channels from the list
4477
4478 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004479 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004480
4481 \return - 0 for success non-zero for failure
4482
4483 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004484static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4485 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004486{
4487 tANI_U8 *inPtr = pValue;
4488 int tempInt = 0;
4489 int j = 0, i = 0, v = 0;
4490 char buf[32];
4491
4492 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4493 /*no argument after the command*/
4494 if (NULL == inPtr)
4495 {
4496 return -EINVAL;
4497 }
4498 /*no space after the command*/
4499 else if (SPACE_ASCII_VALUE != *inPtr)
4500 {
4501 return -EINVAL;
4502 }
4503
4504 /*removing empty spaces*/
4505 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4506
4507 /*no argument followed by spaces*/
4508 if ('\0' == *inPtr) return -EINVAL;
4509
4510 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004511 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004512 if (1 != v) return -EINVAL;
4513
4514 v = kstrtos32(buf, 10, &tempInt);
4515 if ( v < 0) return -EINVAL;
4516
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004517 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004518
4519 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004520 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004521
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004522 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004523 {
4524 for (i = 0; i < 4; i++)
4525 {
4526 /*inPtr pointing to the beginning of first space after number of ie fields*/
4527 inPtr = strpbrk( inPtr, " " );
4528 /*no ie data after the number of ie fields argument*/
4529 if (NULL == inPtr) return -EINVAL;
4530
4531 /*removing empty space*/
4532 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4533
4534 /*no ie data after the number of ie fields argument and spaces*/
4535 if ( '\0' == *inPtr ) return -EINVAL;
4536
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004537 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004538 if (1 != v) return -EINVAL;
4539
4540 v = kstrtos32(buf, 10, &tempInt);
4541 if (v < 0) return -EINVAL;
4542
4543 switch (i)
4544 {
4545 case 0: /* Measurement token */
4546 if (tempInt <= 0)
4547 {
4548 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4549 "Invalid Measurement Token(%d)", tempInt);
4550 return -EINVAL;
4551 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004552 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004553 break;
4554
4555 case 1: /* Channel number */
4556 if ((tempInt <= 0) ||
4557 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4558 {
4559 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4560 "Invalid Channel Number(%d)", tempInt);
4561 return -EINVAL;
4562 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004563 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004564 break;
4565
4566 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004567 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004568 {
4569 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4570 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4571 return -EINVAL;
4572 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004573 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004574 break;
4575
4576 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004577 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4578 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004579 {
4580 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4581 "Invalid Measurement Duration(%d)", tempInt);
4582 return -EINVAL;
4583 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004584 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004585 break;
4586 }
4587 }
4588 }
4589
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004590 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004591 {
4592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304593 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004594 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004595 pEseBcnReq->bcnReq[j].measurementToken,
4596 pEseBcnReq->bcnReq[j].channel,
4597 pEseBcnReq->bcnReq[j].scanMode,
4598 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004599 }
4600
4601 return VOS_STATUS_SUCCESS;
4602}
4603
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004604static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4605{
4606 struct statsContext *pStatsContext = NULL;
4607 hdd_adapter_t *pAdapter = NULL;
4608
4609 if (NULL == pContext)
4610 {
4611 hddLog(VOS_TRACE_LEVEL_ERROR,
4612 "%s: Bad param, pContext [%p]",
4613 __func__, pContext);
4614 return;
4615 }
4616
Jeff Johnson72a40512013-12-19 10:14:15 -08004617 /* there is a race condition that exists between this callback
4618 function and the caller since the caller could time out either
4619 before or while this code is executing. we use a spinlock to
4620 serialize these actions */
4621 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004622
4623 pStatsContext = pContext;
4624 pAdapter = pStatsContext->pAdapter;
4625 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4626 {
4627 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004628 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004629 hddLog(VOS_TRACE_LEVEL_WARN,
4630 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4631 __func__, pAdapter, pStatsContext->magic);
4632 return;
4633 }
4634
Jeff Johnson72a40512013-12-19 10:14:15 -08004635 /* context is valid so caller is still waiting */
4636
4637 /* paranoia: invalidate the magic */
4638 pStatsContext->magic = 0;
4639
4640 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004641 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4642 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4643 tsmMetrics.UplinkPktQueueDlyHist,
4644 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4645 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4646 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4647 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4648 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4649 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4650 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4651
Jeff Johnson72a40512013-12-19 10:14:15 -08004652 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004653 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004654
4655 /* serialization is complete */
4656 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004657}
4658
4659
4660
4661static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4662 tAniTrafStrmMetrics* pTsmMetrics)
4663{
4664 hdd_station_ctx_t *pHddStaCtx = NULL;
4665 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004666 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004667 long lrc;
4668 struct statsContext context;
4669 hdd_context_t *pHddCtx = NULL;
4670
4671 if (NULL == pAdapter)
4672 {
4673 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4674 return VOS_STATUS_E_FAULT;
4675 }
4676
4677 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4678 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4679
4680 /* we are connected prepare our callback context */
4681 init_completion(&context.completion);
4682 context.pAdapter = pAdapter;
4683 context.magic = STATS_CONTEXT_MAGIC;
4684
4685 /* query tsm stats */
4686 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4687 pHddStaCtx->conn_info.staId[ 0 ],
4688 pHddStaCtx->conn_info.bssId,
4689 &context, pHddCtx->pvosContext, tid);
4690
4691 if (eHAL_STATUS_SUCCESS != hstatus)
4692 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004693 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4694 __func__);
4695 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004696 }
4697 else
4698 {
4699 /* request was sent -- wait for the response */
4700 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4701 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004702 if (lrc <= 0)
4703 {
4704 hddLog(VOS_TRACE_LEVEL_ERROR,
4705 "%s: SME %s while retrieving statistics",
4706 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004707 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004708 }
4709 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004710
Jeff Johnson72a40512013-12-19 10:14:15 -08004711 /* either we never sent a request, we sent a request and received a
4712 response or we sent a request and timed out. if we never sent a
4713 request or if we sent a request and got a response, we want to
4714 clear the magic out of paranoia. if we timed out there is a
4715 race condition such that the callback function could be
4716 executing at the same time we are. of primary concern is if the
4717 callback function had already verified the "magic" but had not
4718 yet set the completion variable when a timeout occurred. we
4719 serialize these activities by invalidating the magic while
4720 holding a shared spinlock which will cause us to block if the
4721 callback is currently executing */
4722 spin_lock(&hdd_context_lock);
4723 context.magic = 0;
4724 spin_unlock(&hdd_context_lock);
4725
4726 if (VOS_STATUS_SUCCESS == vstatus)
4727 {
4728 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4729 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4730 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4731 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4732 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4733 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4734 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4735 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4736 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4737 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4738 }
4739 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004740}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004741#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004742
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004743#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004744void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4745{
4746 eCsrBand band = -1;
4747 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4748 switch (band)
4749 {
4750 case eCSR_BAND_ALL:
4751 *pBand = WLAN_HDD_UI_BAND_AUTO;
4752 break;
4753
4754 case eCSR_BAND_24:
4755 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4756 break;
4757
4758 case eCSR_BAND_5G:
4759 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4760 break;
4761
4762 default:
4763 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4764 *pBand = -1;
4765 break;
4766 }
4767}
4768
4769/**---------------------------------------------------------------------------
4770
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004771 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4772
4773 This function parses the send action frame data passed in the format
4774 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4775
Srinivas Girigowda56076852013-08-20 14:00:50 -07004776 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004777 \param - pTargetApBssid Pointer to target Ap bssid
4778 \param - pChannel Pointer to the Target AP channel
4779 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4780 \param - pBuf Pointer to data
4781 \param - pBufLen Pointer to data length
4782
4783 \return - 0 for success non-zero for failure
4784
4785 --------------------------------------------------------------------------*/
4786VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4787 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4788{
4789 tANI_U8 *inPtr = pValue;
4790 tANI_U8 *dataEnd;
4791 int tempInt;
4792 int j = 0;
4793 int i = 0;
4794 int v = 0;
4795 tANI_U8 tempBuf[32];
4796 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004797 /* 12 hexa decimal digits, 5 ':' and '\0' */
4798 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004799
4800 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4801 /*no argument after the command*/
4802 if (NULL == inPtr)
4803 {
4804 return -EINVAL;
4805 }
4806
4807 /*no space after the command*/
4808 else if (SPACE_ASCII_VALUE != *inPtr)
4809 {
4810 return -EINVAL;
4811 }
4812
4813 /*removing empty spaces*/
4814 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4815
4816 /*no argument followed by spaces*/
4817 if ('\0' == *inPtr)
4818 {
4819 return -EINVAL;
4820 }
4821
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004822 v = sscanf(inPtr, "%17s", macAddress);
4823 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004824 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4826 "Invalid MAC address or All hex inputs are not read (%d)", v);
4827 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004828 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004829
4830 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4831 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4832 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4833 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4834 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4835 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004836
4837 /* point to the next argument */
4838 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4839 /*no argument after the command*/
4840 if (NULL == inPtr) return -EINVAL;
4841
4842 /*removing empty spaces*/
4843 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4844
4845 /*no argument followed by spaces*/
4846 if ('\0' == *inPtr)
4847 {
4848 return -EINVAL;
4849 }
4850
4851 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004852 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004853 if (1 != v) return -EINVAL;
4854
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004855 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304856 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304857 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004858
4859 *pChannel = tempInt;
4860
4861 /* point to the next argument */
4862 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4863 /*no argument after the command*/
4864 if (NULL == inPtr) return -EINVAL;
4865 /*removing empty spaces*/
4866 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4867
4868 /*no argument followed by spaces*/
4869 if ('\0' == *inPtr)
4870 {
4871 return -EINVAL;
4872 }
4873
4874 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004875 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004876 if (1 != v) return -EINVAL;
4877
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004878 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004879 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004880
4881 *pDwellTime = tempInt;
4882
4883 /* point to the next argument */
4884 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4885 /*no argument after the command*/
4886 if (NULL == inPtr) return -EINVAL;
4887 /*removing empty spaces*/
4888 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4889
4890 /*no argument followed by spaces*/
4891 if ('\0' == *inPtr)
4892 {
4893 return -EINVAL;
4894 }
4895
4896 /* find the length of data */
4897 dataEnd = inPtr;
4898 while(('\0' != *dataEnd) )
4899 {
4900 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004901 }
Kiet Lambe150c22013-11-21 16:30:32 +05304902 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004903 if ( *pBufLen <= 0) return -EINVAL;
4904
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004905 /* Allocate the number of bytes based on the number of input characters
4906 whether it is even or odd.
4907 if the number of input characters are even, then we need N/2 byte.
4908 if the number of input characters are odd, then we need do (N+1)/2 to
4909 compensate rounding off.
4910 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4911 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4912 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004913 if (NULL == *pBuf)
4914 {
4915 hddLog(VOS_TRACE_LEVEL_FATAL,
4916 "%s: vos_mem_alloc failed ", __func__);
4917 return -EINVAL;
4918 }
4919
4920 /* the buffer received from the upper layer is character buffer,
4921 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4922 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4923 and f0 in 3rd location */
4924 for (i = 0, j = 0; j < *pBufLen; j += 2)
4925 {
Kiet Lambe150c22013-11-21 16:30:32 +05304926 if( j+1 == *pBufLen)
4927 {
4928 tempByte = hdd_parse_hex(inPtr[j]);
4929 }
4930 else
4931 {
4932 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4933 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004934 (*pBuf)[i++] = tempByte;
4935 }
4936 *pBufLen = i;
4937 return VOS_STATUS_SUCCESS;
4938}
4939
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004940/**---------------------------------------------------------------------------
4941
Srinivas Girigowdade697412013-02-14 16:31:48 -08004942 \brief hdd_parse_channellist() - HDD Parse channel list
4943
4944 This function parses the channel list passed in the format
4945 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004946 if the Number of channels (N) does not match with the actual number of channels passed
4947 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4948 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4949 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4950 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004951
4952 \param - pValue Pointer to input channel list
4953 \param - ChannelList Pointer to local output array to record channel list
4954 \param - pNumChannels Pointer to number of roam scan channels
4955
4956 \return - 0 for success non-zero for failure
4957
4958 --------------------------------------------------------------------------*/
4959VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4960{
4961 tANI_U8 *inPtr = pValue;
4962 int tempInt;
4963 int j = 0;
4964 int v = 0;
4965 char buf[32];
4966
4967 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4968 /*no argument after the command*/
4969 if (NULL == inPtr)
4970 {
4971 return -EINVAL;
4972 }
4973
4974 /*no space after the command*/
4975 else if (SPACE_ASCII_VALUE != *inPtr)
4976 {
4977 return -EINVAL;
4978 }
4979
4980 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004981 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004982
4983 /*no argument followed by spaces*/
4984 if ('\0' == *inPtr)
4985 {
4986 return -EINVAL;
4987 }
4988
4989 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004990 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004991 if (1 != v) return -EINVAL;
4992
Srinivas Girigowdade697412013-02-14 16:31:48 -08004993 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004994 if ((v < 0) ||
4995 (tempInt <= 0) ||
4996 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4997 {
4998 return -EINVAL;
4999 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005000
5001 *pNumChannels = tempInt;
5002
5003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5004 "Number of channels are: %d", *pNumChannels);
5005
5006 for (j = 0; j < (*pNumChannels); j++)
5007 {
5008 /*inPtr pointing to the beginning of first space after number of channels*/
5009 inPtr = strpbrk( inPtr, " " );
5010 /*no channel list after the number of channels argument*/
5011 if (NULL == inPtr)
5012 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005013 if (0 != j)
5014 {
5015 *pNumChannels = j;
5016 return VOS_STATUS_SUCCESS;
5017 }
5018 else
5019 {
5020 return -EINVAL;
5021 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005022 }
5023
5024 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005025 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005026
5027 /*no channel list after the number of channels argument and spaces*/
5028 if ( '\0' == *inPtr )
5029 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005030 if (0 != j)
5031 {
5032 *pNumChannels = j;
5033 return VOS_STATUS_SUCCESS;
5034 }
5035 else
5036 {
5037 return -EINVAL;
5038 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005039 }
5040
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005041 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005042 if (1 != v) return -EINVAL;
5043
Srinivas Girigowdade697412013-02-14 16:31:48 -08005044 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005045 if ((v < 0) ||
5046 (tempInt <= 0) ||
5047 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5048 {
5049 return -EINVAL;
5050 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005051 pChannelList[j] = tempInt;
5052
5053 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5054 "Channel %d added to preferred channel list",
5055 pChannelList[j] );
5056 }
5057
Srinivas Girigowdade697412013-02-14 16:31:48 -08005058 return VOS_STATUS_SUCCESS;
5059}
5060
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005061
5062/**---------------------------------------------------------------------------
5063
5064 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5065
5066 This function parses the reasoc command data passed in the format
5067 REASSOC<space><bssid><space><channel>
5068
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005069 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005070 \param - pTargetApBssid Pointer to target Ap bssid
5071 \param - pChannel Pointer to the Target AP channel
5072
5073 \return - 0 for success non-zero for failure
5074
5075 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005076VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5077 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005078{
5079 tANI_U8 *inPtr = pValue;
5080 int tempInt;
5081 int v = 0;
5082 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005083 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005084 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005085
5086 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5087 /*no argument after the command*/
5088 if (NULL == inPtr)
5089 {
5090 return -EINVAL;
5091 }
5092
5093 /*no space after the command*/
5094 else if (SPACE_ASCII_VALUE != *inPtr)
5095 {
5096 return -EINVAL;
5097 }
5098
5099 /*removing empty spaces*/
5100 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5101
5102 /*no argument followed by spaces*/
5103 if ('\0' == *inPtr)
5104 {
5105 return -EINVAL;
5106 }
5107
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005108 v = sscanf(inPtr, "%17s", macAddress);
5109 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005110 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005111 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5112 "Invalid MAC address or All hex inputs are not read (%d)", v);
5113 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005114 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005115
5116 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5117 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5118 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5119 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5120 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5121 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005122
5123 /* point to the next argument */
5124 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5125 /*no argument after the command*/
5126 if (NULL == inPtr) return -EINVAL;
5127
5128 /*removing empty spaces*/
5129 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5130
5131 /*no argument followed by spaces*/
5132 if ('\0' == *inPtr)
5133 {
5134 return -EINVAL;
5135 }
5136
5137 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005138 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005139 if (1 != v) return -EINVAL;
5140
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005141 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005142 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305143 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005144 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5145 {
5146 return -EINVAL;
5147 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005148
5149 *pChannel = tempInt;
5150 return VOS_STATUS_SUCCESS;
5151}
5152
5153#endif
5154
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005155#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005156/**---------------------------------------------------------------------------
5157
5158 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5159
5160 This function parses the SETCCKM IE command
5161 SETCCKMIE<space><ie data>
5162
5163 \param - pValue Pointer to input data
5164 \param - pCckmIe Pointer to output cckm Ie
5165 \param - pCckmIeLen Pointer to output cckm ie length
5166
5167 \return - 0 for success non-zero for failure
5168
5169 --------------------------------------------------------------------------*/
5170VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5171 tANI_U8 *pCckmIeLen)
5172{
5173 tANI_U8 *inPtr = pValue;
5174 tANI_U8 *dataEnd;
5175 int j = 0;
5176 int i = 0;
5177 tANI_U8 tempByte = 0;
5178
5179 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5180 /*no argument after the command*/
5181 if (NULL == inPtr)
5182 {
5183 return -EINVAL;
5184 }
5185
5186 /*no space after the command*/
5187 else if (SPACE_ASCII_VALUE != *inPtr)
5188 {
5189 return -EINVAL;
5190 }
5191
5192 /*removing empty spaces*/
5193 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5194
5195 /*no argument followed by spaces*/
5196 if ('\0' == *inPtr)
5197 {
5198 return -EINVAL;
5199 }
5200
5201 /* find the length of data */
5202 dataEnd = inPtr;
5203 while(('\0' != *dataEnd) )
5204 {
5205 dataEnd++;
5206 ++(*pCckmIeLen);
5207 }
5208 if ( *pCckmIeLen <= 0) return -EINVAL;
5209
5210 /* Allocate the number of bytes based on the number of input characters
5211 whether it is even or odd.
5212 if the number of input characters are even, then we need N/2 byte.
5213 if the number of input characters are odd, then we need do (N+1)/2 to
5214 compensate rounding off.
5215 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5216 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5217 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5218 if (NULL == *pCckmIe)
5219 {
5220 hddLog(VOS_TRACE_LEVEL_FATAL,
5221 "%s: vos_mem_alloc failed ", __func__);
5222 return -EINVAL;
5223 }
5224 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5225 /* the buffer received from the upper layer is character buffer,
5226 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5227 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5228 and f0 in 3rd location */
5229 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5230 {
5231 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5232 (*pCckmIe)[i++] = tempByte;
5233 }
5234 *pCckmIeLen = i;
5235
5236 return VOS_STATUS_SUCCESS;
5237}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005238#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005239
Jeff Johnson295189b2012-06-20 16:38:30 -07005240/**---------------------------------------------------------------------------
5241
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005242 \brief hdd_is_valid_mac_address() - Validate MAC address
5243
5244 This function validates whether the given MAC address is valid or not
5245 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5246 where X is the hexa decimal digit character and separated by ':'
5247 This algorithm works even if MAC address is not separated by ':'
5248
5249 This code checks given input string mac contains exactly 12 hexadecimal digits.
5250 and a separator colon : appears in the input string only after
5251 an even number of hex digits.
5252
5253 \param - pMacAddr pointer to the input MAC address
5254 \return - 1 for valid and 0 for invalid
5255
5256 --------------------------------------------------------------------------*/
5257
5258v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5259{
5260 int xdigit = 0;
5261 int separator = 0;
5262 while (*pMacAddr)
5263 {
5264 if (isxdigit(*pMacAddr))
5265 {
5266 xdigit++;
5267 }
5268 else if (':' == *pMacAddr)
5269 {
5270 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5271 break;
5272
5273 ++separator;
5274 }
5275 else
5276 {
5277 separator = -1;
5278 /* Invalid MAC found */
5279 return 0;
5280 }
5281 ++pMacAddr;
5282 }
5283 return (xdigit == 12 && (separator == 5 || separator == 0));
5284}
5285
5286/**---------------------------------------------------------------------------
5287
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305288 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005289
5290 \param - dev Pointer to net_device structure
5291
5292 \return - 0 for success non-zero for failure
5293
5294 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305295int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005296{
5297 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5298 hdd_context_t *pHddCtx;
5299 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5300 VOS_STATUS status;
5301 v_BOOL_t in_standby = TRUE;
5302
5303 if (NULL == pAdapter)
5304 {
5305 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305306 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005307 return -ENODEV;
5308 }
5309
5310 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305311 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5312 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005313 if (NULL == pHddCtx)
5314 {
5315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005316 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005317 return -ENODEV;
5318 }
5319
5320 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5321 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5322 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005323 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5324 {
5325 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305326 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005327 in_standby = FALSE;
5328 break;
5329 }
5330 else
5331 {
5332 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5333 pAdapterNode = pNext;
5334 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005335 }
5336
5337 if (TRUE == in_standby)
5338 {
5339 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5340 {
5341 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5342 "wlan out of power save", __func__);
5343 return -EINVAL;
5344 }
5345 }
5346
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005347 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005348 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5349 {
5350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005351 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005352 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305353 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005354 netif_tx_start_all_queues(dev);
5355 }
5356
5357 return 0;
5358}
5359
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305360/**---------------------------------------------------------------------------
5361
5362 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5363
5364 This is called in response to ifconfig up
5365
5366 \param - dev Pointer to net_device structure
5367
5368 \return - 0 for success non-zero for failure
5369
5370 --------------------------------------------------------------------------*/
5371int hdd_open(struct net_device *dev)
5372{
5373 int ret;
5374
5375 vos_ssr_protect(__func__);
5376 ret = __hdd_open(dev);
5377 vos_ssr_unprotect(__func__);
5378
5379 return ret;
5380}
5381
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305382int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005383{
5384 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5385
5386 if(pAdapter == NULL) {
5387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005388 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005389 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005390 }
5391
5392 netif_start_queue(dev);
5393
5394 return 0;
5395}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305396
5397int hdd_mon_open (struct net_device *dev)
5398{
5399 int ret;
5400
5401 vos_ssr_protect(__func__);
5402 ret = __hdd_mon_open(dev);
5403 vos_ssr_unprotect(__func__);
5404
5405 return ret;
5406}
5407
Jeff Johnson295189b2012-06-20 16:38:30 -07005408/**---------------------------------------------------------------------------
5409
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305410 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005411
5412 \param - dev Pointer to net_device structure
5413
5414 \return - 0 for success non-zero for failure
5415
5416 --------------------------------------------------------------------------*/
5417
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305418int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005419{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305420 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005421 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5422 hdd_context_t *pHddCtx;
5423 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5424 VOS_STATUS status;
5425 v_BOOL_t enter_standby = TRUE;
5426
5427 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005428 if (NULL == pAdapter)
5429 {
5430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305431 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005432 return -ENODEV;
5433 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305434 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305435 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305436
5437 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5438 ret = wlan_hdd_validate_context(pHddCtx);
5439 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005440 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305441 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5442 "%s: HDD context is not valid!", __func__);
5443 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005444 }
5445
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305446 /* Nothing to be done if the interface is not opened */
5447 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5448 {
5449 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5450 "%s: NETDEV Interface is not OPENED", __func__);
5451 return -ENODEV;
5452 }
5453
5454 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005455 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005456 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305457
5458 /* Disable TX on the interface, after this hard_start_xmit() will not
5459 * be called on that interface
5460 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305461 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005462 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305463
5464 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005465 netif_carrier_off(pAdapter->dev);
5466
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305467 /* The interface is marked as down for outside world (aka kernel)
5468 * But the driver is pretty much alive inside. The driver needs to
5469 * tear down the existing connection on the netdev (session)
5470 * cleanup the data pipes and wait until the control plane is stabilized
5471 * for this interface. The call also needs to wait until the above
5472 * mentioned actions are completed before returning to the caller.
5473 * Notice that the hdd_stop_adapter is requested not to close the session
5474 * That is intentional to be able to scan if it is a STA/P2P interface
5475 */
5476 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305477#ifdef FEATURE_WLAN_TDLS
5478 mutex_lock(&pHddCtx->tdls_lock);
5479#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305480 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305481 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305482#ifdef FEATURE_WLAN_TDLS
5483 mutex_unlock(&pHddCtx->tdls_lock);
5484#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005485 /* SoftAP ifaces should never go in power save mode
5486 making sure same here. */
5487 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5488 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005489 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005490 )
5491 {
5492 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305493 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5494 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005495 EXIT();
5496 return 0;
5497 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305498 /* Find if any iface is up. If any iface is up then can't put device to
5499 * sleep/power save mode
5500 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005501 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5502 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5503 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005504 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5505 {
5506 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305507 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005508 enter_standby = FALSE;
5509 break;
5510 }
5511 else
5512 {
5513 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5514 pAdapterNode = pNext;
5515 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005516 }
5517
5518 if (TRUE == enter_standby)
5519 {
5520 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5521 "entering standby", __func__);
5522 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5523 {
5524 /*log and return success*/
5525 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5526 "wlan in power save", __func__);
5527 }
5528 }
5529
5530 EXIT();
5531 return 0;
5532}
5533
5534/**---------------------------------------------------------------------------
5535
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305536 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005537
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305538 This is called in response to ifconfig down
5539
5540 \param - dev Pointer to net_device structure
5541
5542 \return - 0 for success non-zero for failure
5543-----------------------------------------------------------------------------*/
5544int hdd_stop (struct net_device *dev)
5545{
5546 int ret;
5547
5548 vos_ssr_protect(__func__);
5549 ret = __hdd_stop(dev);
5550 vos_ssr_unprotect(__func__);
5551
5552 return ret;
5553}
5554
5555/**---------------------------------------------------------------------------
5556
5557 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005558
5559 \param - dev Pointer to net_device structure
5560
5561 \return - void
5562
5563 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305564static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005565{
5566 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305567 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005568 ENTER();
5569
5570 do
5571 {
5572 if (NULL == pAdapter)
5573 {
5574 hddLog(VOS_TRACE_LEVEL_FATAL,
5575 "%s: NULL pAdapter", __func__);
5576 break;
5577 }
5578
5579 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5580 {
5581 hddLog(VOS_TRACE_LEVEL_FATAL,
5582 "%s: Invalid magic", __func__);
5583 break;
5584 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305585 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5586 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005587 {
5588 hddLog(VOS_TRACE_LEVEL_FATAL,
5589 "%s: NULL pHddCtx", __func__);
5590 break;
5591 }
5592
5593 if (dev != pAdapter->dev)
5594 {
5595 hddLog(VOS_TRACE_LEVEL_FATAL,
5596 "%s: Invalid device reference", __func__);
5597 /* we haven't validated all cases so let this go for now */
5598 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305599#ifdef FEATURE_WLAN_TDLS
5600 mutex_lock(&pHddCtx->tdls_lock);
5601#endif
c_hpothu002231a2015-02-05 14:58:51 +05305602 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305603#ifdef FEATURE_WLAN_TDLS
5604 mutex_unlock(&pHddCtx->tdls_lock);
5605#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005606
5607 /* after uninit our adapter structure will no longer be valid */
5608 pAdapter->dev = NULL;
5609 pAdapter->magic = 0;
5610 } while (0);
5611
5612 EXIT();
5613}
5614
5615/**---------------------------------------------------------------------------
5616
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305617 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5618
5619 This is called during the netdev unregister to uninitialize all data
5620associated with the device
5621
5622 \param - dev Pointer to net_device structure
5623
5624 \return - void
5625
5626 --------------------------------------------------------------------------*/
5627static void hdd_uninit (struct net_device *dev)
5628{
5629 vos_ssr_protect(__func__);
5630 __hdd_uninit(dev);
5631 vos_ssr_unprotect(__func__);
5632}
5633
5634/**---------------------------------------------------------------------------
5635
Jeff Johnson295189b2012-06-20 16:38:30 -07005636 \brief hdd_release_firmware() -
5637
5638 This function calls the release firmware API to free the firmware buffer.
5639
5640 \param - pFileName Pointer to the File Name.
5641 pCtx - Pointer to the adapter .
5642
5643
5644 \return - 0 for success, non zero for failure
5645
5646 --------------------------------------------------------------------------*/
5647
5648VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5649{
5650 VOS_STATUS status = VOS_STATUS_SUCCESS;
5651 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5652 ENTER();
5653
5654
5655 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5656
5657 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5658
5659 if(pHddCtx->fw) {
5660 release_firmware(pHddCtx->fw);
5661 pHddCtx->fw = NULL;
5662 }
5663 else
5664 status = VOS_STATUS_E_FAILURE;
5665 }
5666 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5667 if(pHddCtx->nv) {
5668 release_firmware(pHddCtx->nv);
5669 pHddCtx->nv = NULL;
5670 }
5671 else
5672 status = VOS_STATUS_E_FAILURE;
5673
5674 }
5675
5676 EXIT();
5677 return status;
5678}
5679
5680/**---------------------------------------------------------------------------
5681
5682 \brief hdd_request_firmware() -
5683
5684 This function reads the firmware file using the request firmware
5685 API and returns the the firmware data and the firmware file size.
5686
5687 \param - pfileName - Pointer to the file name.
5688 - pCtx - Pointer to the adapter .
5689 - ppfw_data - Pointer to the pointer of the firmware data.
5690 - pSize - Pointer to the file size.
5691
5692 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5693
5694 --------------------------------------------------------------------------*/
5695
5696
5697VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5698{
5699 int status;
5700 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5701 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5702 ENTER();
5703
5704 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5705
5706 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5707
5708 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5709 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5710 __func__, pfileName);
5711 retval = VOS_STATUS_E_FAILURE;
5712 }
5713
5714 else {
5715 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5716 *pSize = pHddCtx->fw->size;
5717 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5718 __func__, *pSize);
5719 }
5720 }
5721 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5722
5723 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5724
5725 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5726 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5727 __func__, pfileName);
5728 retval = VOS_STATUS_E_FAILURE;
5729 }
5730
5731 else {
5732 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5733 *pSize = pHddCtx->nv->size;
5734 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5735 __func__, *pSize);
5736 }
5737 }
5738
5739 EXIT();
5740 return retval;
5741}
5742/**---------------------------------------------------------------------------
5743 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5744
5745 This is the function invoked by SME to inform the result of a full power
5746 request issued by HDD
5747
5748 \param - callbackcontext - Pointer to cookie
5749 status - result of request
5750
5751 \return - None
5752
5753--------------------------------------------------------------------------*/
5754void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5755{
5756 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5757
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005758 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005759 if(&pHddCtx->full_pwr_comp_var)
5760 {
5761 complete(&pHddCtx->full_pwr_comp_var);
5762 }
5763}
5764
5765/**---------------------------------------------------------------------------
5766
5767 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5768
5769 This is the function invoked by SME to inform the result of BMPS
5770 request issued by HDD
5771
5772 \param - callbackcontext - Pointer to cookie
5773 status - result of request
5774
5775 \return - None
5776
5777--------------------------------------------------------------------------*/
5778void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5779{
5780
5781 struct completion *completion_var = (struct completion*) callbackContext;
5782
Arif Hussain6d2a3322013-11-17 19:50:10 -08005783 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005784 if(completion_var != NULL)
5785 {
5786 complete(completion_var);
5787 }
5788}
5789
5790/**---------------------------------------------------------------------------
5791
5792 \brief hdd_get_cfg_file_size() -
5793
5794 This function reads the configuration file using the request firmware
5795 API and returns the configuration file size.
5796
5797 \param - pCtx - Pointer to the adapter .
5798 - pFileName - Pointer to the file name.
5799 - pBufSize - Pointer to the buffer size.
5800
5801 \return - 0 for success, non zero for failure
5802
5803 --------------------------------------------------------------------------*/
5804
5805VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5806{
5807 int status;
5808 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5809
5810 ENTER();
5811
5812 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5813
5814 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5815 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5816 status = VOS_STATUS_E_FAILURE;
5817 }
5818 else {
5819 *pBufSize = pHddCtx->fw->size;
5820 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5821 release_firmware(pHddCtx->fw);
5822 pHddCtx->fw = NULL;
5823 }
5824
5825 EXIT();
5826 return VOS_STATUS_SUCCESS;
5827}
5828
5829/**---------------------------------------------------------------------------
5830
5831 \brief hdd_read_cfg_file() -
5832
5833 This function reads the configuration file using the request firmware
5834 API and returns the cfg data and the buffer size of the configuration file.
5835
5836 \param - pCtx - Pointer to the adapter .
5837 - pFileName - Pointer to the file name.
5838 - pBuffer - Pointer to the data buffer.
5839 - pBufSize - Pointer to the buffer size.
5840
5841 \return - 0 for success, non zero for failure
5842
5843 --------------------------------------------------------------------------*/
5844
5845VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5846 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5847{
5848 int status;
5849 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5850
5851 ENTER();
5852
5853 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5854
5855 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5856 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5857 return VOS_STATUS_E_FAILURE;
5858 }
5859 else {
5860 if(*pBufSize != pHddCtx->fw->size) {
5861 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5862 "file size", __func__);
5863 release_firmware(pHddCtx->fw);
5864 pHddCtx->fw = NULL;
5865 return VOS_STATUS_E_FAILURE;
5866 }
5867 else {
5868 if(pBuffer) {
5869 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5870 }
5871 release_firmware(pHddCtx->fw);
5872 pHddCtx->fw = NULL;
5873 }
5874 }
5875
5876 EXIT();
5877
5878 return VOS_STATUS_SUCCESS;
5879}
5880
5881/**---------------------------------------------------------------------------
5882
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305883 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07005884
5885 This function sets the user specified mac address using
5886 the command ifconfig wlanX hw ether <mac adress>.
5887
5888 \param - dev - Pointer to the net device.
5889 - addr - Pointer to the sockaddr.
5890 \return - 0 for success, non zero for failure
5891
5892 --------------------------------------------------------------------------*/
5893
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305894static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07005895{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305896 hdd_adapter_t *pAdapter;
5897 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005898 struct sockaddr *psta_mac_addr = addr;
5899 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305900 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005901
5902 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305903 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5904 if (NULL == pAdapter)
5905 {
5906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5907 "%s: Adapter is NULL",__func__);
5908 return -EINVAL;
5909 }
5910 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5911 ret = wlan_hdd_validate_context(pHddCtx);
5912 if (0 != ret)
5913 {
5914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5915 "%s: HDD context is not valid",__func__);
5916 return ret;
5917 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005918
5919 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07005920 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5921
5922 EXIT();
5923 return halStatus;
5924}
5925
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305926/**---------------------------------------------------------------------------
5927
5928 \brief hdd_set_mac_address() -
5929
5930 Wrapper function to protect __hdd_set_mac_address() function from ssr
5931
5932 \param - dev - Pointer to the net device.
5933 - addr - Pointer to the sockaddr.
5934 \return - 0 for success, non zero for failure
5935
5936 --------------------------------------------------------------------------*/
5937static int hdd_set_mac_address(struct net_device *dev, void *addr)
5938{
5939 int ret;
5940
5941 vos_ssr_protect(__func__);
5942 ret = __hdd_set_mac_address(dev, addr);
5943 vos_ssr_unprotect(__func__);
5944
5945 return ret;
5946}
5947
Jeff Johnson295189b2012-06-20 16:38:30 -07005948tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5949{
5950 int i;
5951 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5952 {
Abhishek Singheb183782014-02-06 13:37:21 +05305953 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005954 break;
5955 }
5956
5957 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5958 return NULL;
5959
5960 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5961 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5962}
5963
5964void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5965{
5966 int i;
5967 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5968 {
5969 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5970 {
5971 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5972 break;
5973 }
5974 }
5975 return;
5976}
5977
5978#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5979 static struct net_device_ops wlan_drv_ops = {
5980 .ndo_open = hdd_open,
5981 .ndo_stop = hdd_stop,
5982 .ndo_uninit = hdd_uninit,
5983 .ndo_start_xmit = hdd_hard_start_xmit,
5984 .ndo_tx_timeout = hdd_tx_timeout,
5985 .ndo_get_stats = hdd_stats,
5986 .ndo_do_ioctl = hdd_ioctl,
5987 .ndo_set_mac_address = hdd_set_mac_address,
5988 .ndo_select_queue = hdd_select_queue,
5989#ifdef WLAN_FEATURE_PACKET_FILTERING
5990#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5991 .ndo_set_rx_mode = hdd_set_multicast_list,
5992#else
5993 .ndo_set_multicast_list = hdd_set_multicast_list,
5994#endif //LINUX_VERSION_CODE
5995#endif
5996 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005997 static struct net_device_ops wlan_mon_drv_ops = {
5998 .ndo_open = hdd_mon_open,
5999 .ndo_stop = hdd_stop,
6000 .ndo_uninit = hdd_uninit,
6001 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6002 .ndo_tx_timeout = hdd_tx_timeout,
6003 .ndo_get_stats = hdd_stats,
6004 .ndo_do_ioctl = hdd_ioctl,
6005 .ndo_set_mac_address = hdd_set_mac_address,
6006 };
Mahesh A Saptasagard477b092015-02-06 15:12:16 +05306007 static struct net_device_ops nullify_netdev_ops = {
6008 .ndo_open = NULL,
6009 .ndo_stop = NULL,
6010 .ndo_uninit = NULL,
6011 .ndo_start_xmit = NULL,
6012 .ndo_tx_timeout = NULL,
6013 .ndo_get_stats = NULL,
6014 .ndo_set_mac_address = NULL,
6015 .ndo_do_ioctl = NULL,
6016 .ndo_change_mtu = NULL,
6017 .ndo_select_queue = NULL,
6018 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006019#endif
6020
6021void hdd_set_station_ops( struct net_device *pWlanDev )
6022{
6023#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006024 pWlanDev->netdev_ops = &wlan_drv_ops;
6025#else
6026 pWlanDev->open = hdd_open;
6027 pWlanDev->stop = hdd_stop;
6028 pWlanDev->uninit = hdd_uninit;
6029 pWlanDev->hard_start_xmit = NULL;
6030 pWlanDev->tx_timeout = hdd_tx_timeout;
6031 pWlanDev->get_stats = hdd_stats;
6032 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006033 pWlanDev->set_mac_address = hdd_set_mac_address;
6034#endif
6035}
6036
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006037static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006038{
6039 struct net_device *pWlanDev = NULL;
6040 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006041 /*
6042 * cfg80211 initialization and registration....
6043 */
6044 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
6045
Jeff Johnson295189b2012-06-20 16:38:30 -07006046 if(pWlanDev != NULL)
6047 {
6048
6049 //Save the pointer to the net_device in the HDD adapter
6050 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6051
Jeff Johnson295189b2012-06-20 16:38:30 -07006052 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6053
6054 pAdapter->dev = pWlanDev;
6055 pAdapter->pHddCtx = pHddCtx;
6056 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306057 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006058
6059 init_completion(&pAdapter->session_open_comp_var);
6060 init_completion(&pAdapter->session_close_comp_var);
6061 init_completion(&pAdapter->disconnect_comp_var);
6062 init_completion(&pAdapter->linkup_event_var);
6063 init_completion(&pAdapter->cancel_rem_on_chan_var);
6064 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306065 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006066#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6067 init_completion(&pAdapter->offchannel_tx_event);
6068#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006069 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006070#ifdef FEATURE_WLAN_TDLS
6071 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006072 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006073 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306074 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006075#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006076 init_completion(&pHddCtx->mc_sus_event_var);
6077 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306078 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006079 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006080 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006081
Rajeev79dbe4c2013-10-05 11:03:42 +05306082#ifdef FEATURE_WLAN_BATCH_SCAN
6083 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6084 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6085 pAdapter->pBatchScanRsp = NULL;
6086 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006087 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006088 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306089 mutex_init(&pAdapter->hdd_batch_scan_lock);
6090#endif
6091
Jeff Johnson295189b2012-06-20 16:38:30 -07006092 pAdapter->isLinkUpSvcNeeded = FALSE;
6093 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6094 //Init the net_device structure
6095 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6096
6097 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6098 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6099 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6100 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6101
6102 hdd_set_station_ops( pAdapter->dev );
6103
6104 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006105 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6106 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6107 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006108 /* set pWlanDev's parent to underlying device */
6109 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006110
6111 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006112 }
6113
6114 return pAdapter;
6115}
6116
6117VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6118{
6119 struct net_device *pWlanDev = pAdapter->dev;
6120 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6121 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6122 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6123
6124 if( rtnl_lock_held )
6125 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006126 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006127 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6128 {
6129 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6130 return VOS_STATUS_E_FAILURE;
6131 }
6132 }
6133 if (register_netdevice(pWlanDev))
6134 {
6135 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6136 return VOS_STATUS_E_FAILURE;
6137 }
6138 }
6139 else
6140 {
6141 if(register_netdev(pWlanDev))
6142 {
6143 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6144 return VOS_STATUS_E_FAILURE;
6145 }
6146 }
6147 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6148
6149 return VOS_STATUS_SUCCESS;
6150}
6151
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006152static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006153{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006154 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006155
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006156 if (NULL == pAdapter)
6157 {
6158 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6159 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006160 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006161
6162 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6163 {
6164 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6165 return eHAL_STATUS_NOT_INITIALIZED;
6166 }
6167
6168 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6169
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006170#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006171 /* need to make sure all of our scheduled work has completed.
6172 * This callback is called from MC thread context, so it is safe to
6173 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006174 *
6175 * Even though this is called from MC thread context, if there is a faulty
6176 * work item in the system, that can hang this call forever. So flushing
6177 * this global work queue is not safe; and now we make sure that
6178 * individual work queues are stopped correctly. But the cancel work queue
6179 * is a GPL only API, so the proprietary version of the driver would still
6180 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006181 */
6182 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006183#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006184
6185 /* We can be blocked while waiting for scheduled work to be
6186 * flushed, and the adapter structure can potentially be freed, in
6187 * which case the magic will have been reset. So make sure the
6188 * magic is still good, and hence the adapter structure is still
6189 * valid, before signaling completion */
6190 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6191 {
6192 complete(&pAdapter->session_close_comp_var);
6193 }
6194
Jeff Johnson295189b2012-06-20 16:38:30 -07006195 return eHAL_STATUS_SUCCESS;
6196}
6197
6198VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6199{
6200 struct net_device *pWlanDev = pAdapter->dev;
6201 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6202 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6203 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6204 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306205 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006206
6207 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006208 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006209 //Open a SME session for future operation
6210 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006211 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006212 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6213 {
6214 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006215 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006216 halStatus, halStatus );
6217 status = VOS_STATUS_E_FAILURE;
6218 goto error_sme_open;
6219 }
6220
6221 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306222 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006223 &pAdapter->session_open_comp_var,
6224 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306225 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006226 {
6227 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306228 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006229 status = VOS_STATUS_E_FAILURE;
6230 goto error_sme_open;
6231 }
6232
6233 // Register wireless extensions
6234 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6235 {
6236 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006237 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006238 halStatus, halStatus );
6239 status = VOS_STATUS_E_FAILURE;
6240 goto error_register_wext;
6241 }
6242 //Safe to register the hard_start_xmit function again
6243#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6244 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6245#else
6246 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6247#endif
6248
6249 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306250 hddLog(VOS_TRACE_LEVEL_INFO,
6251 "%s: Set HDD connState to eConnectionState_NotConnected",
6252 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006253 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6254
6255 //Set the default operation channel
6256 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6257
6258 /* Make the default Auth Type as OPEN*/
6259 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6260
6261 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6262 {
6263 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006264 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006265 status, status );
6266 goto error_init_txrx;
6267 }
6268
6269 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6270
6271 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6272 {
6273 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006274 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006275 status, status );
6276 goto error_wmm_init;
6277 }
6278
6279 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6280
6281 return VOS_STATUS_SUCCESS;
6282
6283error_wmm_init:
6284 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6285 hdd_deinit_tx_rx(pAdapter);
6286error_init_txrx:
6287 hdd_UnregisterWext(pWlanDev);
6288error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006289 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006290 {
6291 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006292 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006293 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006294 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006295 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306296 unsigned long rc;
6297
Jeff Johnson295189b2012-06-20 16:38:30 -07006298 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306299 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006300 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006301 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306302 if (rc <= 0)
6303 hddLog(VOS_TRACE_LEVEL_ERROR,
6304 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006305 }
6306}
6307error_sme_open:
6308 return status;
6309}
6310
Jeff Johnson295189b2012-06-20 16:38:30 -07006311void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6312{
6313 hdd_cfg80211_state_t *cfgState;
6314
6315 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6316
6317 if( NULL != cfgState->buf )
6318 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306319 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006320 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6321 rc = wait_for_completion_interruptible_timeout(
6322 &pAdapter->tx_action_cnf_event,
6323 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306324 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006325 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306327 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6328 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006329 }
6330 }
6331 return;
6332}
Jeff Johnson295189b2012-06-20 16:38:30 -07006333
c_hpothu002231a2015-02-05 14:58:51 +05306334void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006335{
6336 ENTER();
6337 switch ( pAdapter->device_mode )
6338 {
6339 case WLAN_HDD_INFRA_STATION:
6340 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006341 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006342 {
6343 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6344 {
6345 hdd_deinit_tx_rx( pAdapter );
6346 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6347 }
6348
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 break;
6357 }
6358
6359 case WLAN_HDD_SOFTAP:
6360 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006361 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306362
6363 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6364 {
6365 hdd_wmm_adapter_close( pAdapter );
6366 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6367 }
6368
Jeff Johnson295189b2012-06-20 16:38:30 -07006369 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006370
c_hpothu002231a2015-02-05 14:58:51 +05306371 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006372 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006373 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07006374 break;
6375 }
6376
6377 case WLAN_HDD_MONITOR:
6378 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006379 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006380 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6381 {
6382 hdd_deinit_tx_rx( pAdapter );
6383 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6384 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006385 if(NULL != pAdapterforTx)
6386 {
6387 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
6388 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006389 break;
6390 }
6391
6392
6393 default:
6394 break;
6395 }
6396
6397 EXIT();
6398}
6399
6400void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6401{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006402 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306403
6404 ENTER();
6405 if (NULL == pAdapter)
6406 {
6407 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6408 "%s: HDD adapter is Null", __func__);
6409 return;
6410 }
6411
6412 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006413
Rajeev79dbe4c2013-10-05 11:03:42 +05306414#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306415 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6416 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006417 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306418 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6419 )
6420 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006421 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306422 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006423 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6424 {
6425 hdd_deinit_batch_scan(pAdapter);
6426 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306427 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006428 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306429#endif
6430
Jeff Johnson295189b2012-06-20 16:38:30 -07006431 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6432 if( rtnl_held )
6433 {
6434 unregister_netdevice(pWlanDev);
6435 }
6436 else
6437 {
6438 unregister_netdev(pWlanDev);
6439 }
6440 // note that the pAdapter is no longer valid at this point
6441 // since the memory has been reclaimed
6442 }
6443
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306444 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006445}
6446
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006447void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6448{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306449 VOS_STATUS status;
6450 hdd_adapter_t *pAdapter = NULL;
6451 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006452
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306453 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006454
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306455 /*loop through all adapters.*/
6456 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006457 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306458 pAdapter = pAdapterNode->pAdapter;
6459 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6460 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006461
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306462 { // we skip this registration for modes other than STA and P2P client modes.
6463 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6464 pAdapterNode = pNext;
6465 continue;
6466 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006467
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306468 //Apply Dynamic DTIM For P2P
6469 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6470 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6471 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6472 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6473 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6474 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6475 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6476 (eConnectionState_Associated ==
6477 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6478 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6479 {
6480 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006481
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306482 powerRequest.uIgnoreDTIM = 1;
6483 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6484
6485 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6486 {
6487 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6488 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6489 }
6490 else
6491 {
6492 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6493 }
6494
6495 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6496 * specified during Enter/Exit BMPS when LCD off*/
6497 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6498 NULL, eANI_BOOLEAN_FALSE);
6499 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6500 NULL, eANI_BOOLEAN_FALSE);
6501
6502 /* switch to the DTIM specified in cfg.ini */
6503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6504 "Switch to DTIM %d", powerRequest.uListenInterval);
6505 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6506 break;
6507
6508 }
6509
6510 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6511 pAdapterNode = pNext;
6512 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006513}
6514
6515void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6516{
6517 /*Switch back to DTIM 1*/
6518 tSirSetPowerParamsReq powerRequest = { 0 };
6519
6520 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6521 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006522 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006523
6524 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6525 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6526 NULL, eANI_BOOLEAN_FALSE);
6527 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6528 NULL, eANI_BOOLEAN_FALSE);
6529
6530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6531 "Switch to DTIM%d",powerRequest.uListenInterval);
6532 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6533
6534}
6535
Jeff Johnson295189b2012-06-20 16:38:30 -07006536VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6537{
6538 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306539 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6540 {
6541 hddLog( LOGE, FL("Wlan Unload in progress"));
6542 return VOS_STATUS_E_PERM;
6543 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006544 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6545 {
6546 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6547 }
6548
6549 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6550 {
6551 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6552 }
6553
6554 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6555 {
6556 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6557 }
6558
6559 return status;
6560}
6561
6562VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6563{
6564 hdd_adapter_t *pAdapter = NULL;
6565 eHalStatus halStatus;
6566 VOS_STATUS status = VOS_STATUS_E_INVAL;
6567 v_BOOL_t disableBmps = FALSE;
6568 v_BOOL_t disableImps = FALSE;
6569
6570 switch(session_type)
6571 {
6572 case WLAN_HDD_INFRA_STATION:
6573 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006574 case WLAN_HDD_P2P_CLIENT:
6575 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006576 //Exit BMPS -> Is Sta/P2P Client is already connected
6577 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6578 if((NULL != pAdapter)&&
6579 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6580 {
6581 disableBmps = TRUE;
6582 }
6583
6584 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6585 if((NULL != pAdapter)&&
6586 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6587 {
6588 disableBmps = TRUE;
6589 }
6590
6591 //Exit both Bmps and Imps incase of Go/SAP Mode
6592 if((WLAN_HDD_SOFTAP == session_type) ||
6593 (WLAN_HDD_P2P_GO == session_type))
6594 {
6595 disableBmps = TRUE;
6596 disableImps = TRUE;
6597 }
6598
6599 if(TRUE == disableImps)
6600 {
6601 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6602 {
6603 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6604 }
6605 }
6606
6607 if(TRUE == disableBmps)
6608 {
6609 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6610 {
6611 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6612
6613 if(eHAL_STATUS_SUCCESS != halStatus)
6614 {
6615 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006616 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006617 VOS_ASSERT(0);
6618 return status;
6619 }
6620 }
6621
6622 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6623 {
6624 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6625
6626 if(eHAL_STATUS_SUCCESS != halStatus)
6627 {
6628 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006629 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006630 VOS_ASSERT(0);
6631 return status;
6632 }
6633 }
6634 }
6635
6636 if((TRUE == disableBmps) ||
6637 (TRUE == disableImps))
6638 {
6639 /* Now, get the chip into Full Power now */
6640 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6641 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6642 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6643
6644 if(halStatus != eHAL_STATUS_SUCCESS)
6645 {
6646 if(halStatus == eHAL_STATUS_PMC_PENDING)
6647 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306648 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006649 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306650 ret = wait_for_completion_interruptible_timeout(
6651 &pHddCtx->full_pwr_comp_var,
6652 msecs_to_jiffies(1000));
6653 if (ret <= 0)
6654 {
6655 hddLog(VOS_TRACE_LEVEL_ERROR,
6656 "%s: wait on full_pwr_comp_var failed %ld",
6657 __func__, ret);
6658 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006659 }
6660 else
6661 {
6662 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006663 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006664 VOS_ASSERT(0);
6665 return status;
6666 }
6667 }
6668
6669 status = VOS_STATUS_SUCCESS;
6670 }
6671
6672 break;
6673 }
6674 return status;
6675}
6676
6677hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006678 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006679 tANI_U8 rtnl_held )
6680{
6681 hdd_adapter_t *pAdapter = NULL;
6682 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6683 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6684 VOS_STATUS exitbmpsStatus;
6685
Arif Hussain6d2a3322013-11-17 19:50:10 -08006686 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006687
Nirav Shah436658f2014-02-28 17:05:45 +05306688 if(macAddr == NULL)
6689 {
6690 /* Not received valid macAddr */
6691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6692 "%s:Unable to add virtual intf: Not able to get"
6693 "valid mac address",__func__);
6694 return NULL;
6695 }
6696
Jeff Johnson295189b2012-06-20 16:38:30 -07006697 //Disable BMPS incase of Concurrency
6698 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6699
6700 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6701 {
6702 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306703 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006704 VOS_ASSERT(0);
6705 return NULL;
6706 }
6707
6708 switch(session_type)
6709 {
6710 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006711 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006712 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006713 {
6714 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6715
6716 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306717 {
6718 hddLog(VOS_TRACE_LEVEL_FATAL,
6719 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006720 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306721 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006722
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306723#ifdef FEATURE_WLAN_TDLS
6724 /* A Mutex Lock is introduced while changing/initializing the mode to
6725 * protect the concurrent access for the Adapters by TDLS module.
6726 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306727 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306728#endif
6729
Jeff Johnsone7245742012-09-05 17:12:55 -07006730 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6731 NL80211_IFTYPE_P2P_CLIENT:
6732 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006733
Jeff Johnson295189b2012-06-20 16:38:30 -07006734 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306735#ifdef FEATURE_WLAN_TDLS
6736 mutex_unlock(&pHddCtx->tdls_lock);
6737#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306738
6739 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006740 if( VOS_STATUS_SUCCESS != status )
6741 goto err_free_netdev;
6742
6743 status = hdd_register_interface( pAdapter, rtnl_held );
6744 if( VOS_STATUS_SUCCESS != status )
6745 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306746#ifdef FEATURE_WLAN_TDLS
6747 mutex_lock(&pHddCtx->tdls_lock);
6748#endif
c_hpothu002231a2015-02-05 14:58:51 +05306749 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306750#ifdef FEATURE_WLAN_TDLS
6751 mutex_unlock(&pHddCtx->tdls_lock);
6752#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006753 goto err_free_netdev;
6754 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306755
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306756 // Workqueue which gets scheduled in IPv4 notification callback.
6757 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6758
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306759#ifdef WLAN_NS_OFFLOAD
6760 // Workqueue which gets scheduled in IPv6 notification callback.
6761 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6762#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006763 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306764 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006765 netif_tx_disable(pAdapter->dev);
6766 //netif_tx_disable(pWlanDev);
6767 netif_carrier_off(pAdapter->dev);
6768
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306769 if (WLAN_HDD_P2P_CLIENT == session_type ||
6770 WLAN_HDD_P2P_DEVICE == session_type)
6771 {
6772 /* Initialize the work queue to defer the
6773 * back to back RoC request */
6774 INIT_DELAYED_WORK(&pAdapter->roc_work,
6775 hdd_p2p_roc_work_queue);
6776 }
6777
Jeff Johnson295189b2012-06-20 16:38:30 -07006778 break;
6779 }
6780
Jeff Johnson295189b2012-06-20 16:38:30 -07006781 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006782 case WLAN_HDD_SOFTAP:
6783 {
6784 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6785 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306786 {
6787 hddLog(VOS_TRACE_LEVEL_FATAL,
6788 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006789 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306790 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006791
Jeff Johnson295189b2012-06-20 16:38:30 -07006792 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6793 NL80211_IFTYPE_AP:
6794 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006795 pAdapter->device_mode = session_type;
6796
6797 status = hdd_init_ap_mode(pAdapter);
6798 if( VOS_STATUS_SUCCESS != status )
6799 goto err_free_netdev;
6800
6801 status = hdd_register_hostapd( pAdapter, rtnl_held );
6802 if( VOS_STATUS_SUCCESS != status )
6803 {
c_hpothu002231a2015-02-05 14:58:51 +05306804 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006805 goto err_free_netdev;
6806 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306807 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006808 netif_tx_disable(pAdapter->dev);
6809 netif_carrier_off(pAdapter->dev);
6810
6811 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306812
6813 if (WLAN_HDD_P2P_GO == session_type)
6814 {
6815 /* Initialize the work queue to
6816 * defer the back to back RoC request */
6817 INIT_DELAYED_WORK(&pAdapter->roc_work,
6818 hdd_p2p_roc_work_queue);
6819 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006820 break;
6821 }
6822 case WLAN_HDD_MONITOR:
6823 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006824 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6825 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306826 {
6827 hddLog(VOS_TRACE_LEVEL_FATAL,
6828 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006829 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306830 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006831
6832 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6833 pAdapter->device_mode = session_type;
6834 status = hdd_register_interface( pAdapter, rtnl_held );
6835#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6836 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6837#else
6838 pAdapter->dev->open = hdd_mon_open;
6839 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6840#endif
6841 hdd_init_tx_rx( pAdapter );
6842 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6843 //Set adapter to be used for data tx. It will use either GO or softap.
6844 pAdapter->sessionCtx.monitor.pAdapterForTx =
6845 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006846 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6847 {
6848 pAdapter->sessionCtx.monitor.pAdapterForTx =
6849 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6850 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006851 /* This workqueue will be used to transmit management packet over
6852 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006853 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6854 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6855 return NULL;
6856 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006857
Jeff Johnson295189b2012-06-20 16:38:30 -07006858 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6859 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006860 }
6861 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006862 case WLAN_HDD_FTM:
6863 {
6864 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6865
6866 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306867 {
6868 hddLog(VOS_TRACE_LEVEL_FATAL,
6869 FL("failed to allocate adapter for session %d"), session_type);
6870 return NULL;
6871 }
6872
Jeff Johnson295189b2012-06-20 16:38:30 -07006873 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6874 * message while loading driver in FTM mode. */
6875 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6876 pAdapter->device_mode = session_type;
6877 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306878
6879 hdd_init_tx_rx( pAdapter );
6880
6881 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306882 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306883 netif_tx_disable(pAdapter->dev);
6884 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006885 }
6886 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006887 default:
6888 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306889 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6890 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006891 VOS_ASSERT(0);
6892 return NULL;
6893 }
6894 }
6895
Jeff Johnson295189b2012-06-20 16:38:30 -07006896 if( VOS_STATUS_SUCCESS == status )
6897 {
6898 //Add it to the hdd's session list.
6899 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6900 if( NULL == pHddAdapterNode )
6901 {
6902 status = VOS_STATUS_E_NOMEM;
6903 }
6904 else
6905 {
6906 pHddAdapterNode->pAdapter = pAdapter;
6907 status = hdd_add_adapter_back ( pHddCtx,
6908 pHddAdapterNode );
6909 }
6910 }
6911
6912 if( VOS_STATUS_SUCCESS != status )
6913 {
6914 if( NULL != pAdapter )
6915 {
6916 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6917 pAdapter = NULL;
6918 }
6919 if( NULL != pHddAdapterNode )
6920 {
6921 vos_mem_free( pHddAdapterNode );
6922 }
6923
6924 goto resume_bmps;
6925 }
6926
6927 if(VOS_STATUS_SUCCESS == status)
6928 {
6929 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6930
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006931 //Initialize the WoWL service
6932 if(!hdd_init_wowl(pAdapter))
6933 {
6934 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6935 goto err_free_netdev;
6936 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006937 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006938 return pAdapter;
6939
6940err_free_netdev:
6941 free_netdev(pAdapter->dev);
6942 wlan_hdd_release_intf_addr( pHddCtx,
6943 pAdapter->macAddressCurrent.bytes );
6944
6945resume_bmps:
6946 //If bmps disabled enable it
6947 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6948 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306949 if (pHddCtx->hdd_wlan_suspended)
6950 {
6951 hdd_set_pwrparams(pHddCtx);
6952 }
6953 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006954 }
6955 return NULL;
6956}
6957
6958VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6959 tANI_U8 rtnl_held )
6960{
6961 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6962 VOS_STATUS status;
6963
6964 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6965 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306966 {
6967 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6968 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006969 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306970 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006971
6972 while ( pCurrent->pAdapter != pAdapter )
6973 {
6974 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6975 if( VOS_STATUS_SUCCESS != status )
6976 break;
6977
6978 pCurrent = pNext;
6979 }
6980 pAdapterNode = pCurrent;
6981 if( VOS_STATUS_SUCCESS == status )
6982 {
6983 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6984 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306985
6986#ifdef FEATURE_WLAN_TDLS
6987
6988 /* A Mutex Lock is introduced while changing/initializing the mode to
6989 * protect the concurrent access for the Adapters by TDLS module.
6990 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306991 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306992#endif
6993
Jeff Johnson295189b2012-06-20 16:38:30 -07006994 hdd_remove_adapter( pHddCtx, pAdapterNode );
6995 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006996 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006997
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306998#ifdef FEATURE_WLAN_TDLS
6999 mutex_unlock(&pHddCtx->tdls_lock);
7000#endif
7001
Jeff Johnson295189b2012-06-20 16:38:30 -07007002
7003 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307004 if ((!vos_concurrent_open_sessions_running()) &&
7005 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7006 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007007 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307008 if (pHddCtx->hdd_wlan_suspended)
7009 {
7010 hdd_set_pwrparams(pHddCtx);
7011 }
7012 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007013 }
7014
7015 return VOS_STATUS_SUCCESS;
7016 }
7017
7018 return VOS_STATUS_E_FAILURE;
7019}
7020
7021VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7022{
7023 hdd_adapter_list_node_t *pHddAdapterNode;
7024 VOS_STATUS status;
7025
7026 ENTER();
7027
7028 do
7029 {
7030 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7031 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7032 {
7033 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7034 vos_mem_free( pHddAdapterNode );
7035 }
7036 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7037
7038 EXIT();
7039
7040 return VOS_STATUS_SUCCESS;
7041}
7042
7043void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7044{
7045 v_U8_t addIE[1] = {0};
7046
7047 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7048 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7049 eANI_BOOLEAN_FALSE) )
7050 {
7051 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007052 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007053 }
7054
7055 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7056 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7057 eANI_BOOLEAN_FALSE) )
7058 {
7059 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007060 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007061 }
7062
7063 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7064 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7065 eANI_BOOLEAN_FALSE) )
7066 {
7067 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007068 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007069 }
7070}
7071
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307072VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7073 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007074{
7075 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7076 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307077 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007078 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307079 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307080 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007081
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307082 if (pHddCtx->isLogpInProgress) {
7083 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7084 "%s:LOGP in Progress. Ignore!!!",__func__);
7085 return VOS_STATUS_E_FAILURE;
7086 }
7087
Jeff Johnson295189b2012-06-20 16:38:30 -07007088 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307089
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307090 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007091 switch(pAdapter->device_mode)
7092 {
7093 case WLAN_HDD_INFRA_STATION:
7094 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007095 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307096 {
7097 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7098 if( hdd_connIsConnected(pstation) ||
7099 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007100 {
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307101#ifdef FEATURE_WLAN_TDLS
7102 mutex_lock(&pHddCtx->tdls_lock);
7103 wlan_hdd_tdls_exit(pAdapter);
7104 mutex_unlock(&pHddCtx->tdls_lock);
7105#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007106 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7107 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7108 pAdapter->sessionId,
7109 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7110 else
7111 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7112 pAdapter->sessionId,
7113 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7114 //success implies disconnect command got queued up successfully
7115 if(halStatus == eHAL_STATUS_SUCCESS)
7116 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307117 ret = wait_for_completion_interruptible_timeout(
7118 &pAdapter->disconnect_comp_var,
7119 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7120 if (ret <= 0)
7121 {
7122 hddLog(VOS_TRACE_LEVEL_ERROR,
7123 "%s: wait on disconnect_comp_var failed %ld",
7124 __func__, ret);
7125 }
7126 }
7127 else
7128 {
7129 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7130 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007131 }
7132 memset(&wrqu, '\0', sizeof(wrqu));
7133 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7134 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7135 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7136 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307137 else if(pstation->conn_info.connState ==
7138 eConnectionState_Disconnecting)
7139 {
7140 ret = wait_for_completion_interruptible_timeout(
7141 &pAdapter->disconnect_comp_var,
7142 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7143 if (ret <= 0)
7144 {
7145 hddLog(VOS_TRACE_LEVEL_ERROR,
7146 FL("wait on disconnect_comp_var failed %ld"), ret);
7147 }
7148 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307149 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007150 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307151 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307152 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007153 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307154 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7155 {
7156 while (pAdapter->is_roc_inprogress)
7157 {
7158 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7159 "%s: ROC in progress for session %d!!!",
7160 __func__, pAdapter->sessionId);
7161 // waiting for ROC to expire
7162 msleep(500);
7163 /* In GO present case , if retry exceeds 3,
7164 it means something went wrong. */
7165 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7166 {
7167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7168 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307169 if (eHAL_STATUS_SUCCESS !=
7170 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7171 pAdapter->sessionId ))
7172 {
7173 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7174 FL("Failed to Cancel Remain on Channel"));
7175 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307176 wait_for_completion_interruptible_timeout(
7177 &pAdapter->cancel_rem_on_chan_var,
7178 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7179 break;
7180 }
7181 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307182#ifdef WLAN_OPEN_SOURCE
7183 cancel_delayed_work_sync(&pAdapter->roc_work);
7184#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307185 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307186#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05307187#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307188 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
7189#endif
7190#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307191
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05307192#ifdef WLAN_OPEN_SOURCE
7193 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
7194#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307195
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307196 /* It is possible that the caller of this function does not
7197 * wish to close the session
7198 */
7199 if (VOS_TRUE == bCloseSession &&
7200 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007201 {
7202 INIT_COMPLETION(pAdapter->session_close_comp_var);
7203 if (eHAL_STATUS_SUCCESS ==
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307204 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
7205 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007206 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307207 unsigned long ret;
7208
Jeff Johnson295189b2012-06-20 16:38:30 -07007209 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307210 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307211 &pAdapter->session_close_comp_var,
7212 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307213 if ( 0 >= ret)
7214 {
7215 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307216 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307217 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007218 }
7219 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307220 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007221 break;
7222
7223 case WLAN_HDD_SOFTAP:
7224 case WLAN_HDD_P2P_GO:
7225 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307226 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7227 while (pAdapter->is_roc_inprogress) {
7228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7229 "%s: ROC in progress for session %d!!!",
7230 __func__, pAdapter->sessionId);
7231 msleep(500);
7232 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7234 "%s: ROC completion is not received.!!!", __func__);
7235 WLANSAP_CancelRemainOnChannel(
7236 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7237 wait_for_completion_interruptible_timeout(
7238 &pAdapter->cancel_rem_on_chan_var,
7239 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7240 break;
7241 }
7242 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307243
7244#ifdef WLAN_OPEN_SOURCE
7245 cancel_delayed_work_sync(&pAdapter->roc_work);
7246#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307247 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007248 mutex_lock(&pHddCtx->sap_lock);
7249 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7250 {
7251 VOS_STATUS status;
7252 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7253
7254 //Stop Bss.
7255 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7256 if (VOS_IS_STATUS_SUCCESS(status))
7257 {
7258 hdd_hostapd_state_t *pHostapdState =
7259 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7260
7261 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7262
7263 if (!VOS_IS_STATUS_SUCCESS(status))
7264 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307265 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7266 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007267 }
7268 }
7269 else
7270 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007271 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007272 }
7273 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307274 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007275
7276 if (eHAL_STATUS_FAILURE ==
7277 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7278 0, NULL, eANI_BOOLEAN_FALSE))
7279 {
7280 hddLog(LOGE,
7281 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007282 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007283 }
7284
7285 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7286 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7287 eANI_BOOLEAN_FALSE) )
7288 {
7289 hddLog(LOGE,
7290 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7291 }
7292
7293 // Reset WNI_CFG_PROBE_RSP Flags
7294 wlan_hdd_reset_prob_rspies(pAdapter);
7295 kfree(pAdapter->sessionCtx.ap.beacon);
7296 pAdapter->sessionCtx.ap.beacon = NULL;
7297 }
7298 mutex_unlock(&pHddCtx->sap_lock);
7299 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007300
Jeff Johnson295189b2012-06-20 16:38:30 -07007301 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007302#ifdef WLAN_OPEN_SOURCE
7303 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
7304#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007305 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007306
Jeff Johnson295189b2012-06-20 16:38:30 -07007307 default:
7308 break;
7309 }
7310
7311 EXIT();
7312 return VOS_STATUS_SUCCESS;
7313}
7314
7315VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7316{
7317 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7318 VOS_STATUS status;
7319 hdd_adapter_t *pAdapter;
7320
7321 ENTER();
7322
7323 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7324
7325 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7326 {
7327 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007328
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307329 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007330
7331 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7332 pAdapterNode = pNext;
7333 }
7334
7335 EXIT();
7336
7337 return VOS_STATUS_SUCCESS;
7338}
7339
Rajeev Kumarf999e582014-01-09 17:33:29 -08007340
7341#ifdef FEATURE_WLAN_BATCH_SCAN
7342/**---------------------------------------------------------------------------
7343
7344 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7345 structures
7346
7347 \param - pAdapter Pointer to HDD adapter
7348
7349 \return - None
7350
7351 --------------------------------------------------------------------------*/
7352void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7353{
7354 tHddBatchScanRsp *pNode;
7355 tHddBatchScanRsp *pPrev;
7356
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307357 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007358 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307359 hddLog(VOS_TRACE_LEVEL_ERROR,
7360 "%s: Adapter context is Null", __func__);
7361 return;
7362 }
7363
7364 pNode = pAdapter->pBatchScanRsp;
7365 while (pNode)
7366 {
7367 pPrev = pNode;
7368 pNode = pNode->pNext;
7369 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007370 }
7371
7372 pAdapter->pBatchScanRsp = NULL;
7373 pAdapter->numScanList = 0;
7374 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7375 pAdapter->prev_batch_id = 0;
7376
7377 return;
7378}
7379#endif
7380
7381
Jeff Johnson295189b2012-06-20 16:38:30 -07007382VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7383{
7384 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7385 VOS_STATUS status;
7386 hdd_adapter_t *pAdapter;
7387
7388 ENTER();
7389
7390 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7391
7392 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7393 {
7394 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307395 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007396 netif_tx_disable(pAdapter->dev);
7397 netif_carrier_off(pAdapter->dev);
7398
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007399 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7400
Jeff Johnson295189b2012-06-20 16:38:30 -07007401 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307402
7403 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7404
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307405 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7406 {
7407 hdd_wmm_adapter_close( pAdapter );
7408 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7409 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007410
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307411 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7412 {
7413 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7414 }
7415
Rajeev Kumarf999e582014-01-09 17:33:29 -08007416#ifdef FEATURE_WLAN_BATCH_SCAN
7417 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7418 {
7419 hdd_deinit_batch_scan(pAdapter);
7420 }
7421#endif
7422
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307423#ifdef FEATURE_WLAN_TDLS
7424 mutex_lock(&pHddCtx->tdls_lock);
7425 wlan_hdd_tdls_exit(pAdapter);
7426 mutex_unlock(&pHddCtx->tdls_lock);
7427#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007428 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7429 pAdapterNode = pNext;
7430 }
7431
7432 EXIT();
7433
7434 return VOS_STATUS_SUCCESS;
7435}
7436
7437VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7438{
7439 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7440 VOS_STATUS status;
7441 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307442 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007443
7444 ENTER();
7445
7446 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7447
7448 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7449 {
7450 pAdapter = pAdapterNode->pAdapter;
7451
Kumar Anand82c009f2014-05-29 00:29:42 -07007452 hdd_wmm_init( pAdapter );
7453
Jeff Johnson295189b2012-06-20 16:38:30 -07007454 switch(pAdapter->device_mode)
7455 {
7456 case WLAN_HDD_INFRA_STATION:
7457 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007458 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307459
7460 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7461
Jeff Johnson295189b2012-06-20 16:38:30 -07007462 hdd_init_station_mode(pAdapter);
7463 /* Open the gates for HDD to receive Wext commands */
7464 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007465 pHddCtx->scan_info.mScanPending = FALSE;
7466 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007467
7468 //Trigger the initial scan
7469 hdd_wlan_initial_scan(pAdapter);
7470
7471 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307472 if (eConnectionState_Associated == connState ||
7473 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007474 {
7475 union iwreq_data wrqu;
7476 memset(&wrqu, '\0', sizeof(wrqu));
7477 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7478 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7479 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007480 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007481
Jeff Johnson295189b2012-06-20 16:38:30 -07007482 /* indicate disconnected event to nl80211 */
7483 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7484 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007485 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307486 else if (eConnectionState_Connecting == connState)
7487 {
7488 /*
7489 * Indicate connect failure to supplicant if we were in the
7490 * process of connecting
7491 */
7492 cfg80211_connect_result(pAdapter->dev, NULL,
7493 NULL, 0, NULL, 0,
7494 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7495 GFP_KERNEL);
7496 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007497 break;
7498
7499 case WLAN_HDD_SOFTAP:
7500 /* softAP can handle SSR */
7501 break;
7502
7503 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007504 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007505 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007506 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007507 break;
7508
7509 case WLAN_HDD_MONITOR:
7510 /* monitor interface start */
7511 break;
7512 default:
7513 break;
7514 }
7515
7516 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7517 pAdapterNode = pNext;
7518 }
7519
7520 EXIT();
7521
7522 return VOS_STATUS_SUCCESS;
7523}
7524
7525VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7526{
7527 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7528 hdd_adapter_t *pAdapter;
7529 VOS_STATUS status;
7530 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307531 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007532
7533 ENTER();
7534
7535 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7536
7537 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7538 {
7539 pAdapter = pAdapterNode->pAdapter;
7540
7541 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7542 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7543 {
7544 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7545 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7546
Abhishek Singhf4669da2014-05-26 15:07:49 +05307547 hddLog(VOS_TRACE_LEVEL_INFO,
7548 "%s: Set HDD connState to eConnectionState_NotConnected",
7549 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007550 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7551 init_completion(&pAdapter->disconnect_comp_var);
7552 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7553 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7554
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307555 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007556 &pAdapter->disconnect_comp_var,
7557 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307558 if (0 >= ret)
7559 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7560 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007561
7562 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7563 pHddCtx->isAmpAllowed = VOS_FALSE;
7564 sme_RoamConnect(pHddCtx->hHal,
7565 pAdapter->sessionId, &(pWextState->roamProfile),
7566 &roamId);
7567 }
7568
7569 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7570 pAdapterNode = pNext;
7571 }
7572
7573 EXIT();
7574
7575 return VOS_STATUS_SUCCESS;
7576}
7577
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007578void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7579{
7580 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7581 VOS_STATUS status;
7582 hdd_adapter_t *pAdapter;
7583 hdd_station_ctx_t *pHddStaCtx;
7584 hdd_ap_ctx_t *pHddApCtx;
7585 hdd_hostapd_state_t * pHostapdState;
7586 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7587 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7588 const char *p2pMode = "DEV";
7589 const char *ccMode = "Standalone";
7590 int n;
7591
7592 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7593 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7594 {
7595 pAdapter = pAdapterNode->pAdapter;
7596 switch (pAdapter->device_mode) {
7597 case WLAN_HDD_INFRA_STATION:
7598 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7599 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7600 staChannel = pHddStaCtx->conn_info.operationChannel;
7601 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7602 }
7603 break;
7604 case WLAN_HDD_P2P_CLIENT:
7605 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7606 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7607 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7608 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7609 p2pMode = "CLI";
7610 }
7611 break;
7612 case WLAN_HDD_P2P_GO:
7613 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7614 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7615 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7616 p2pChannel = pHddApCtx->operatingChannel;
7617 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7618 }
7619 p2pMode = "GO";
7620 break;
7621 case WLAN_HDD_SOFTAP:
7622 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7623 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7624 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7625 apChannel = pHddApCtx->operatingChannel;
7626 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7627 }
7628 break;
7629 default:
7630 break;
7631 }
7632 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7633 pAdapterNode = pNext;
7634 }
7635 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7636 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7637 }
7638 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7639 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7640 if (p2pChannel > 0) {
7641 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7642 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7643 }
7644 if (apChannel > 0) {
7645 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7646 apChannel, MAC_ADDR_ARRAY(apBssid));
7647 }
7648
7649 if (p2pChannel > 0 && apChannel > 0) {
7650 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7651 }
7652}
7653
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007654bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007655{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007656 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007657}
7658
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007659/* Once SSR is disabled then it cannot be set. */
7660void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007661{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007662 if (HDD_SSR_DISABLED == isSsrRequired)
7663 return;
7664
Jeff Johnson295189b2012-06-20 16:38:30 -07007665 isSsrRequired = value;
7666}
7667
7668VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7669 hdd_adapter_list_node_t** ppAdapterNode)
7670{
7671 VOS_STATUS status;
7672 spin_lock(&pHddCtx->hddAdapters.lock);
7673 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7674 (hdd_list_node_t**) ppAdapterNode );
7675 spin_unlock(&pHddCtx->hddAdapters.lock);
7676 return status;
7677}
7678
7679VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7680 hdd_adapter_list_node_t* pAdapterNode,
7681 hdd_adapter_list_node_t** pNextAdapterNode)
7682{
7683 VOS_STATUS status;
7684 spin_lock(&pHddCtx->hddAdapters.lock);
7685 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7686 (hdd_list_node_t*) pAdapterNode,
7687 (hdd_list_node_t**)pNextAdapterNode );
7688
7689 spin_unlock(&pHddCtx->hddAdapters.lock);
7690 return status;
7691}
7692
7693VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7694 hdd_adapter_list_node_t* pAdapterNode)
7695{
7696 VOS_STATUS status;
7697 spin_lock(&pHddCtx->hddAdapters.lock);
7698 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7699 &pAdapterNode->node );
7700 spin_unlock(&pHddCtx->hddAdapters.lock);
7701 return status;
7702}
7703
7704VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7705 hdd_adapter_list_node_t** ppAdapterNode)
7706{
7707 VOS_STATUS status;
7708 spin_lock(&pHddCtx->hddAdapters.lock);
7709 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7710 (hdd_list_node_t**) ppAdapterNode );
7711 spin_unlock(&pHddCtx->hddAdapters.lock);
7712 return status;
7713}
7714
7715VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7716 hdd_adapter_list_node_t* pAdapterNode)
7717{
7718 VOS_STATUS status;
7719 spin_lock(&pHddCtx->hddAdapters.lock);
7720 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7721 (hdd_list_node_t*) pAdapterNode );
7722 spin_unlock(&pHddCtx->hddAdapters.lock);
7723 return status;
7724}
7725
7726VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7727 hdd_adapter_list_node_t* pAdapterNode)
7728{
7729 VOS_STATUS status;
7730 spin_lock(&pHddCtx->hddAdapters.lock);
7731 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7732 (hdd_list_node_t*) pAdapterNode );
7733 spin_unlock(&pHddCtx->hddAdapters.lock);
7734 return status;
7735}
7736
7737hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7738 tSirMacAddr macAddr )
7739{
7740 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7741 hdd_adapter_t *pAdapter;
7742 VOS_STATUS status;
7743
7744 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7745
7746 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7747 {
7748 pAdapter = pAdapterNode->pAdapter;
7749
7750 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7751 macAddr, sizeof(tSirMacAddr) ) )
7752 {
7753 return pAdapter;
7754 }
7755 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7756 pAdapterNode = pNext;
7757 }
7758
7759 return NULL;
7760
7761}
7762
7763hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7764{
7765 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7766 hdd_adapter_t *pAdapter;
7767 VOS_STATUS status;
7768
7769 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7770
7771 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7772 {
7773 pAdapter = pAdapterNode->pAdapter;
7774
7775 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7776 IFNAMSIZ ) )
7777 {
7778 return pAdapter;
7779 }
7780 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7781 pAdapterNode = pNext;
7782 }
7783
7784 return NULL;
7785
7786}
7787
7788hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7789{
7790 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7791 hdd_adapter_t *pAdapter;
7792 VOS_STATUS status;
7793
7794 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7795
7796 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7797 {
7798 pAdapter = pAdapterNode->pAdapter;
7799
7800 if( pAdapter && (mode == pAdapter->device_mode) )
7801 {
7802 return pAdapter;
7803 }
7804 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7805 pAdapterNode = pNext;
7806 }
7807
7808 return NULL;
7809
7810}
7811
7812//Remove this function later
7813hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7814{
7815 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7816 hdd_adapter_t *pAdapter;
7817 VOS_STATUS status;
7818
7819 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7820
7821 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7822 {
7823 pAdapter = pAdapterNode->pAdapter;
7824
7825 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7826 {
7827 return pAdapter;
7828 }
7829
7830 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7831 pAdapterNode = pNext;
7832 }
7833
7834 return NULL;
7835
7836}
7837
Jeff Johnson295189b2012-06-20 16:38:30 -07007838/**---------------------------------------------------------------------------
7839
7840 \brief hdd_set_monitor_tx_adapter() -
7841
7842 This API initializes the adapter to be used while transmitting on monitor
7843 adapter.
7844
7845 \param - pHddCtx - Pointer to the HDD context.
7846 pAdapter - Adapter that will used for TX. This can be NULL.
7847 \return - None.
7848 --------------------------------------------------------------------------*/
7849void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7850{
7851 hdd_adapter_t *pMonAdapter;
7852
7853 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7854
7855 if( NULL != pMonAdapter )
7856 {
7857 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7858 }
7859}
Jeff Johnson295189b2012-06-20 16:38:30 -07007860/**---------------------------------------------------------------------------
7861
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307862 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007863
7864 This API returns the operating channel of the requested device mode
7865
7866 \param - pHddCtx - Pointer to the HDD context.
7867 - mode - Device mode for which operating channel is required
7868 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7869 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7870 \return - channel number. "0" id the requested device is not found OR it is not connected.
7871 --------------------------------------------------------------------------*/
7872v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7873{
7874 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7875 VOS_STATUS status;
7876 hdd_adapter_t *pAdapter;
7877 v_U8_t operatingChannel = 0;
7878
7879 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7880
7881 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7882 {
7883 pAdapter = pAdapterNode->pAdapter;
7884
7885 if( mode == pAdapter->device_mode )
7886 {
7887 switch(pAdapter->device_mode)
7888 {
7889 case WLAN_HDD_INFRA_STATION:
7890 case WLAN_HDD_P2P_CLIENT:
7891 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7892 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7893 break;
7894 case WLAN_HDD_SOFTAP:
7895 case WLAN_HDD_P2P_GO:
7896 /*softap connection info */
7897 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7898 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7899 break;
7900 default:
7901 break;
7902 }
7903
7904 break; //Found the device of interest. break the loop
7905 }
7906
7907 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7908 pAdapterNode = pNext;
7909 }
7910 return operatingChannel;
7911}
7912
7913#ifdef WLAN_FEATURE_PACKET_FILTERING
7914/**---------------------------------------------------------------------------
7915
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307916 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007917
7918 This used to set the multicast address list.
7919
7920 \param - dev - Pointer to the WLAN device.
7921 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307922 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07007923
7924 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307925static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007926{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307927 hdd_adapter_t *pAdapter;
7928 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007929 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307930 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007931 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307932
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307933 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307934 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007935 {
7936 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307937 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007938 return;
7939 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307940 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7941 ret = wlan_hdd_validate_context(pHddCtx);
7942 if (0 != ret)
7943 {
7944 hddLog(VOS_TRACE_LEVEL_ERROR,
7945 "%s: HDD context is not valid",__func__);
7946 return;
7947 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007948 if (dev->flags & IFF_ALLMULTI)
7949 {
7950 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007951 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307952 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007953 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307954 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007955 {
7956 mc_count = netdev_mc_count(dev);
7957 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007958 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007959 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7960 {
7961 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007962 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307963 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007964 return;
7965 }
7966
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307967 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007968
7969 netdev_for_each_mc_addr(ha, dev) {
7970 if (i == mc_count)
7971 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307972 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7973 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007974 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307975 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307976 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007977 i++;
7978 }
7979 }
7980 return;
7981}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307982
7983static void hdd_set_multicast_list(struct net_device *dev)
7984{
7985 vos_ssr_protect(__func__);
7986 __hdd_set_multicast_list(dev);
7987 vos_ssr_unprotect(__func__);
7988}
Jeff Johnson295189b2012-06-20 16:38:30 -07007989#endif
7990
7991/**---------------------------------------------------------------------------
7992
7993 \brief hdd_select_queue() -
7994
7995 This function is registered with the Linux OS for network
7996 core to decide which queue to use first.
7997
7998 \param - dev - Pointer to the WLAN device.
7999 - skb - Pointer to OS packet (sk_buff).
8000 \return - ac, Queue Index/access category corresponding to UP in IP header
8001
8002 --------------------------------------------------------------------------*/
8003v_U16_t hdd_select_queue(struct net_device *dev,
8004 struct sk_buff *skb)
8005{
8006 return hdd_wmm_select_queue(dev, skb);
8007}
8008
8009
8010/**---------------------------------------------------------------------------
8011
8012 \brief hdd_wlan_initial_scan() -
8013
8014 This function triggers the initial scan
8015
8016 \param - pAdapter - Pointer to the HDD adapter.
8017
8018 --------------------------------------------------------------------------*/
8019void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8020{
8021 tCsrScanRequest scanReq;
8022 tCsrChannelInfo channelInfo;
8023 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008024 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008025 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8026
8027 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8028 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8029 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8030
8031 if(sme_Is11dSupported(pHddCtx->hHal))
8032 {
8033 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8034 if ( HAL_STATUS_SUCCESS( halStatus ) )
8035 {
8036 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8037 if( !scanReq.ChannelInfo.ChannelList )
8038 {
8039 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8040 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008041 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008042 return;
8043 }
8044 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8045 channelInfo.numOfChannels);
8046 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8047 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008048 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008049 }
8050
8051 scanReq.scanType = eSIR_PASSIVE_SCAN;
8052 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8053 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8054 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8055 }
8056 else
8057 {
8058 scanReq.scanType = eSIR_ACTIVE_SCAN;
8059 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8060 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8061 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8062 }
8063
8064 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8065 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8066 {
8067 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8068 __func__, halStatus );
8069 }
8070
8071 if(sme_Is11dSupported(pHddCtx->hHal))
8072 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8073}
8074
Jeff Johnson295189b2012-06-20 16:38:30 -07008075/**---------------------------------------------------------------------------
8076
8077 \brief hdd_full_power_callback() - HDD full power callback function
8078
8079 This is the function invoked by SME to inform the result of a full power
8080 request issued by HDD
8081
8082 \param - callbackcontext - Pointer to cookie
8083 \param - status - result of request
8084
8085 \return - None
8086
8087 --------------------------------------------------------------------------*/
8088static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8089{
Jeff Johnson72a40512013-12-19 10:14:15 -08008090 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008091
8092 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308093 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008094
8095 if (NULL == callbackContext)
8096 {
8097 hddLog(VOS_TRACE_LEVEL_ERROR,
8098 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008099 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008100 return;
8101 }
8102
Jeff Johnson72a40512013-12-19 10:14:15 -08008103 /* there is a race condition that exists between this callback
8104 function and the caller since the caller could time out either
8105 before or while this code is executing. we use a spinlock to
8106 serialize these actions */
8107 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008108
8109 if (POWER_CONTEXT_MAGIC != pContext->magic)
8110 {
8111 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008112 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008113 hddLog(VOS_TRACE_LEVEL_WARN,
8114 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008115 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008116 return;
8117 }
8118
Jeff Johnson72a40512013-12-19 10:14:15 -08008119 /* context is valid so caller is still waiting */
8120
8121 /* paranoia: invalidate the magic */
8122 pContext->magic = 0;
8123
8124 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008125 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008126
8127 /* serialization is complete */
8128 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008129}
8130
8131/**---------------------------------------------------------------------------
8132
8133 \brief hdd_wlan_exit() - HDD WLAN exit function
8134
8135 This is the driver exit point (invoked during rmmod)
8136
8137 \param - pHddCtx - Pointer to the HDD Context
8138
8139 \return - None
8140
8141 --------------------------------------------------------------------------*/
8142void hdd_wlan_exit(hdd_context_t *pHddCtx)
8143{
8144 eHalStatus halStatus;
8145 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8146 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308147 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008148 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008149 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008150 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308151 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008152
8153 ENTER();
8154
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308155#ifdef WLAN_NS_OFFLOAD
8156 hddLog(LOGE, FL("Unregister IPv6 notifier"));
8157 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8158#endif
8159 hddLog(LOGE, FL("Unregister IPv4 notifier"));
8160 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8161
Jeff Johnson88ba7742013-02-27 14:36:02 -08008162 if (VOS_FTM_MODE != hdd_get_conparam())
8163 {
8164 // Unloading, restart logic is no more required.
8165 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008166
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308167#ifdef FEATURE_WLAN_TDLS
8168 /* At the time of driver unloading; if tdls connection is present;
8169 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8170 * wlan_hdd_tdls_find_peer always checks for valid context;
8171 * as load/unload in progress there can be a race condition.
8172 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8173 * when tdls state is enabled.
8174 * As soon as driver set load/unload flag; tdls flag also needs
8175 * to be disabled so that hdd_rx_packet_cbk won't call
8176 * wlan_hdd_tdls_find_peer.
8177 */
8178 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8179#endif
8180
c_hpothu5ab05e92014-06-13 17:34:05 +05308181 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8182 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008183 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308184 pAdapter = pAdapterNode->pAdapter;
8185 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008186 {
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308187 /* DeInit the adapter. This ensures that all data packets
8188 * are freed.
8189 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308190#ifdef FEATURE_WLAN_TDLS
8191 mutex_lock(&pHddCtx->tdls_lock);
8192#endif
c_hpothu002231a2015-02-05 14:58:51 +05308193 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308194#ifdef FEATURE_WLAN_TDLS
8195 mutex_unlock(&pHddCtx->tdls_lock);
8196#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308197
c_hpothu5ab05e92014-06-13 17:34:05 +05308198 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8199 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8200 {
8201 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8202 hdd_UnregisterWext(pAdapter->dev);
8203 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308204
Jeff Johnson295189b2012-06-20 16:38:30 -07008205 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308206 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8207 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008208 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308209 // Cancel any outstanding scan requests. We are about to close all
8210 // of our adapters, but an adapter structure is what SME passes back
8211 // to our callback function. Hence if there are any outstanding scan
8212 // requests then there is a race condition between when the adapter
8213 // is closed and when the callback is invoked.We try to resolve that
8214 // race condition here by canceling any outstanding scans before we
8215 // close the adapters.
8216 // Note that the scans may be cancelled in an asynchronous manner,
8217 // so ideally there needs to be some kind of synchronization. Rather
8218 // than introduce a new synchronization here, we will utilize the
8219 // fact that we are about to Request Full Power, and since that is
8220 // synchronized, the expectation is that by the time Request Full
8221 // Power has completed all scans will be cancelled.
8222 if (pHddCtx->scan_info.mScanPending)
8223 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308224 if(NULL != pAdapter)
8225 {
8226 hddLog(VOS_TRACE_LEVEL_INFO,
8227 FL("abort scan mode: %d sessionId: %d"),
8228 pAdapter->device_mode,
8229 pAdapter->sessionId);
8230 }
8231 hdd_abort_mac_scan(pHddCtx,
8232 pHddCtx->scan_info.sessionId,
8233 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308234 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008235 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308236 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008237 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308238 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308239 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8240 {
8241 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8242 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8243 "%s: in middle of FTM START", __func__);
8244 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8245 msecs_to_jiffies(20000));
8246 if(!lrc)
8247 {
8248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8249 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8250 }
8251 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008252 wlan_hdd_ftm_close(pHddCtx);
8253 goto free_hdd_ctx;
8254 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308255
Jeff Johnson295189b2012-06-20 16:38:30 -07008256 /* DeRegister with platform driver as client for Suspend/Resume */
8257 vosStatus = hddDeregisterPmOps(pHddCtx);
8258 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8259 {
8260 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8261 VOS_ASSERT(0);
8262 }
8263
8264 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8265 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8266 {
8267 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8268 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008269
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008270 //Stop the traffic monitor timer
8271 if ( VOS_TIMER_STATE_RUNNING ==
8272 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8273 {
8274 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8275 }
8276
8277 // Destroy the traffic monitor timer
8278 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8279 &pHddCtx->tx_rx_trafficTmr)))
8280 {
8281 hddLog(VOS_TRACE_LEVEL_ERROR,
8282 "%s: Cannot deallocate Traffic monitor timer", __func__);
8283 }
8284
Jeff Johnson295189b2012-06-20 16:38:30 -07008285 //Disable IMPS/BMPS as we do not want the device to enter any power
8286 //save mode during shutdown
8287 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8288 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8289 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8290
8291 //Ensure that device is in full power as we will touch H/W during vos_Stop
8292 init_completion(&powerContext.completion);
8293 powerContext.magic = POWER_CONTEXT_MAGIC;
8294
8295 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8296 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8297
8298 if (eHAL_STATUS_SUCCESS != halStatus)
8299 {
8300 if (eHAL_STATUS_PMC_PENDING == halStatus)
8301 {
8302 /* request was sent -- wait for the response */
8303 lrc = wait_for_completion_interruptible_timeout(
8304 &powerContext.completion,
8305 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008306 if (lrc <= 0)
8307 {
8308 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008309 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008310 }
8311 }
8312 else
8313 {
8314 hddLog(VOS_TRACE_LEVEL_ERROR,
8315 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008316 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008317 /* continue -- need to clean up as much as possible */
8318 }
8319 }
8320
Jeff Johnson72a40512013-12-19 10:14:15 -08008321 /* either we never sent a request, we sent a request and received a
8322 response or we sent a request and timed out. if we never sent a
8323 request or if we sent a request and got a response, we want to
8324 clear the magic out of paranoia. if we timed out there is a
8325 race condition such that the callback function could be
8326 executing at the same time we are. of primary concern is if the
8327 callback function had already verified the "magic" but had not
8328 yet set the completion variable when a timeout occurred. we
8329 serialize these activities by invalidating the magic while
8330 holding a shared spinlock which will cause us to block if the
8331 callback is currently executing */
8332 spin_lock(&hdd_context_lock);
8333 powerContext.magic = 0;
8334 spin_unlock(&hdd_context_lock);
8335
Yue Ma0d4891e2013-08-06 17:01:45 -07008336 hdd_debugfs_exit(pHddCtx);
8337
Jeff Johnson295189b2012-06-20 16:38:30 -07008338 // Unregister the Net Device Notifier
8339 unregister_netdevice_notifier(&hdd_netdev_notifier);
8340
Jeff Johnson295189b2012-06-20 16:38:30 -07008341 hdd_stop_all_adapters( pHddCtx );
8342
Jeff Johnson295189b2012-06-20 16:38:30 -07008343#ifdef WLAN_BTAMP_FEATURE
8344 vosStatus = WLANBAP_Stop(pVosContext);
8345 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8346 {
8347 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8348 "%s: Failed to stop BAP",__func__);
8349 }
8350#endif //WLAN_BTAMP_FEATURE
8351
8352 //Stop all the modules
8353 vosStatus = vos_stop( pVosContext );
8354 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8355 {
8356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8357 "%s: Failed to stop VOSS",__func__);
8358 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8359 }
8360
Jeff Johnson295189b2012-06-20 16:38:30 -07008361 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008362 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008363
8364 //Close the scheduler before calling vos_close to make sure no thread is
8365 // scheduled after the each module close is called i.e after all the data
8366 // structures are freed.
8367 vosStatus = vos_sched_close( pVosContext );
8368 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8369 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8370 "%s: Failed to close VOSS Scheduler",__func__);
8371 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8372 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008373#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008374#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8375 /* Destroy the wake lock */
8376 wake_lock_destroy(&pHddCtx->rx_wake_lock);
8377#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008378 /* Destroy the wake lock */
8379 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008380#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008381
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308382#ifdef CONFIG_ENABLE_LINUX_REG
8383 vosStatus = vos_nv_close();
8384 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8385 {
8386 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8387 "%s: Failed to close NV", __func__);
8388 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8389 }
8390#endif
8391
Jeff Johnson295189b2012-06-20 16:38:30 -07008392 //Close VOSS
8393 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8394 vos_close(pVosContext);
8395
Jeff Johnson295189b2012-06-20 16:38:30 -07008396 //Close Watchdog
8397 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8398 vos_watchdog_close(pVosContext);
8399
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308400 //Clean up HDD Nlink Service
8401 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308402
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308403#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308404 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308405 {
8406 wlan_logging_sock_deactivate_svc();
8407 }
8408#endif
8409
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308410#ifdef WLAN_KD_READY_NOTIFIER
8411 nl_srv_exit(pHddCtx->ptt_pid);
8412#else
8413 nl_srv_exit();
8414#endif /* WLAN_KD_READY_NOTIFIER */
8415
8416
Jeff Johnson295189b2012-06-20 16:38:30 -07008417 hdd_close_all_adapters( pHddCtx );
8418
Jeff Johnson295189b2012-06-20 16:38:30 -07008419 /* free the power on lock from platform driver */
8420 if (free_riva_power_on_lock("wlan"))
8421 {
8422 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8423 __func__);
8424 }
8425
Jeff Johnson88ba7742013-02-27 14:36:02 -08008426free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308427
8428 //Free up dynamically allocated members inside HDD Adapter
8429 if (pHddCtx->cfg_ini)
8430 {
8431 kfree(pHddCtx->cfg_ini);
8432 pHddCtx->cfg_ini= NULL;
8433 }
8434
Leo Changf04ddad2013-09-18 13:46:38 -07008435 /* FTM mode, WIPHY did not registered
8436 If un-register here, system crash will happen */
8437 if (VOS_FTM_MODE != hdd_get_conparam())
8438 {
8439 wiphy_unregister(wiphy) ;
8440 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008441 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008442 if (hdd_is_ssr_required())
8443 {
8444 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008445 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008446 msleep(5000);
8447 }
8448 hdd_set_ssr_required (VOS_FALSE);
8449}
8450
8451
8452/**---------------------------------------------------------------------------
8453
8454 \brief hdd_update_config_from_nv() - Function to update the contents of
8455 the running configuration with parameters taken from NV storage
8456
8457 \param - pHddCtx - Pointer to the HDD global context
8458
8459 \return - VOS_STATUS_SUCCESS if successful
8460
8461 --------------------------------------------------------------------------*/
8462static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8463{
Jeff Johnson295189b2012-06-20 16:38:30 -07008464 v_BOOL_t itemIsValid = VOS_FALSE;
8465 VOS_STATUS status;
8466 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8467 v_U8_t macLoop;
8468
8469 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8470 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8471 if(status != VOS_STATUS_SUCCESS)
8472 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008473 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008474 return VOS_STATUS_E_FAILURE;
8475 }
8476
8477 if (itemIsValid == VOS_TRUE)
8478 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008479 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008480 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8481 VOS_MAX_CONCURRENCY_PERSONA);
8482 if(status != VOS_STATUS_SUCCESS)
8483 {
8484 /* Get MAC from NV fail, not update CFG info
8485 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008486 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008487 return VOS_STATUS_E_FAILURE;
8488 }
8489
8490 /* If first MAC is not valid, treat all others are not valid
8491 * Then all MACs will be got from ini file */
8492 if(vos_is_macaddr_zero(&macFromNV[0]))
8493 {
8494 /* MAC address in NV file is not configured yet */
8495 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8496 return VOS_STATUS_E_INVAL;
8497 }
8498
8499 /* Get MAC address from NV, update CFG info */
8500 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8501 {
8502 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8503 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308504 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008505 /* This MAC is not valid, skip it
8506 * This MAC will be got from ini file */
8507 }
8508 else
8509 {
8510 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8511 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8512 VOS_MAC_ADDR_SIZE);
8513 }
8514 }
8515 }
8516 else
8517 {
8518 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8519 return VOS_STATUS_E_FAILURE;
8520 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008521
Jeff Johnson295189b2012-06-20 16:38:30 -07008522
8523 return VOS_STATUS_SUCCESS;
8524}
8525
8526/**---------------------------------------------------------------------------
8527
8528 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8529
8530 \param - pAdapter - Pointer to the HDD
8531
8532 \return - None
8533
8534 --------------------------------------------------------------------------*/
8535VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8536{
8537 eHalStatus halStatus;
8538 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308539 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008540
Jeff Johnson295189b2012-06-20 16:38:30 -07008541
8542 // Send ready indication to the HDD. This will kick off the MAC
8543 // into a 'running' state and should kick off an initial scan.
8544 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8545 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8546 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308547 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008548 "code %08d [x%08x]",__func__, halStatus, halStatus );
8549 return VOS_STATUS_E_FAILURE;
8550 }
8551
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308552 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008553 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8554 // And RIVA will crash
8555 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8556 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308557 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8558 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8559
8560
Jeff Johnson295189b2012-06-20 16:38:30 -07008561 return VOS_STATUS_SUCCESS;
8562}
8563
Jeff Johnson295189b2012-06-20 16:38:30 -07008564/* wake lock APIs for HDD */
8565void hdd_prevent_suspend(void)
8566{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008567#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008568 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008569#else
8570 wcnss_prevent_suspend();
8571#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008572}
8573
8574void hdd_allow_suspend(void)
8575{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008576#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008577 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008578#else
8579 wcnss_allow_suspend();
8580#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008581}
8582
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308583void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008584{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008585#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008586 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008587#else
8588 /* Do nothing as there is no API in wcnss for timeout*/
8589#endif
8590}
8591
Jeff Johnson295189b2012-06-20 16:38:30 -07008592/**---------------------------------------------------------------------------
8593
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008594 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8595 information between Host and Riva
8596
8597 This function gets reported version of FW
8598 It also finds the version of Riva headers used to compile the host
8599 It compares the above two and prints a warning if they are different
8600 It gets the SW and HW version string
8601 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8602 indicating the features they support through a bitmap
8603
8604 \param - pHddCtx - Pointer to HDD context
8605
8606 \return - void
8607
8608 --------------------------------------------------------------------------*/
8609
8610void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8611{
8612
8613 tSirVersionType versionCompiled;
8614 tSirVersionType versionReported;
8615 tSirVersionString versionString;
8616 tANI_U8 fwFeatCapsMsgSupported = 0;
8617 VOS_STATUS vstatus;
8618
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008619 memset(&versionCompiled, 0, sizeof(versionCompiled));
8620 memset(&versionReported, 0, sizeof(versionReported));
8621
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008622 /* retrieve and display WCNSS version information */
8623 do {
8624
8625 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8626 &versionCompiled);
8627 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8628 {
8629 hddLog(VOS_TRACE_LEVEL_FATAL,
8630 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008631 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008632 break;
8633 }
8634
8635 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8636 &versionReported);
8637 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8638 {
8639 hddLog(VOS_TRACE_LEVEL_FATAL,
8640 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008641 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008642 break;
8643 }
8644
8645 if ((versionCompiled.major != versionReported.major) ||
8646 (versionCompiled.minor != versionReported.minor) ||
8647 (versionCompiled.version != versionReported.version) ||
8648 (versionCompiled.revision != versionReported.revision))
8649 {
8650 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8651 "Host expected %u.%u.%u.%u\n",
8652 WLAN_MODULE_NAME,
8653 (int)versionReported.major,
8654 (int)versionReported.minor,
8655 (int)versionReported.version,
8656 (int)versionReported.revision,
8657 (int)versionCompiled.major,
8658 (int)versionCompiled.minor,
8659 (int)versionCompiled.version,
8660 (int)versionCompiled.revision);
8661 }
8662 else
8663 {
8664 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8665 WLAN_MODULE_NAME,
8666 (int)versionReported.major,
8667 (int)versionReported.minor,
8668 (int)versionReported.version,
8669 (int)versionReported.revision);
8670 }
8671
8672 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8673 versionString,
8674 sizeof(versionString));
8675 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8676 {
8677 hddLog(VOS_TRACE_LEVEL_FATAL,
8678 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008679 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008680 break;
8681 }
8682
8683 pr_info("%s: WCNSS software version %s\n",
8684 WLAN_MODULE_NAME, versionString);
8685
8686 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8687 versionString,
8688 sizeof(versionString));
8689 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8690 {
8691 hddLog(VOS_TRACE_LEVEL_FATAL,
8692 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008693 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008694 break;
8695 }
8696
8697 pr_info("%s: WCNSS hardware version %s\n",
8698 WLAN_MODULE_NAME, versionString);
8699
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008700 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8701 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008702 send the message only if it the riva is 1.1
8703 minor numbers for different riva branches:
8704 0 -> (1.0)Mainline Build
8705 1 -> (1.1)Mainline Build
8706 2->(1.04) Stability Build
8707 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008708 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008709 ((versionReported.minor>=1) && (versionReported.version>=1)))
8710 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8711 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008712
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008713 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008714 {
8715#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8716 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8717 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8718#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008719 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8720 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8721 {
8722 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8723 }
8724
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008725 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008726 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008727
8728 } while (0);
8729
8730}
Neelansh Mittaledafed22014-09-04 18:54:39 +05308731void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
8732{
8733 struct sk_buff *skb;
8734 struct nlmsghdr *nlh;
8735 tAniMsgHdr *ani_hdr;
8736
8737 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
8738
8739 if(skb == NULL) {
8740 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8741 "%s: alloc_skb failed", __func__);
8742 return;
8743 }
8744
8745 nlh = (struct nlmsghdr *)skb->data;
8746 nlh->nlmsg_pid = 0; /* from kernel */
8747 nlh->nlmsg_flags = 0;
8748 nlh->nlmsg_seq = 0;
8749 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
8750
8751 ani_hdr = NLMSG_DATA(nlh);
8752 ani_hdr->type = type;
8753
8754 switch(type) {
8755 case WLAN_SVC_SAP_RESTART_IND:
8756 ani_hdr->length = 0;
8757 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
8758 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
8759 break;
8760 default:
8761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8762 "Attempt to send unknown nlink message %d", type);
8763 kfree_skb(skb);
8764 return;
8765 }
8766
8767 nl_srv_bcast(skb);
8768
8769 return;
8770}
8771
8772
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008773
8774/**---------------------------------------------------------------------------
8775
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308776 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8777
8778 \param - pHddCtx - Pointer to the hdd context
8779
8780 \return - true if hardware supports 5GHz
8781
8782 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308783boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308784{
8785 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8786 * then hardware support 5Ghz.
8787 */
8788 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8789 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308791 return true;
8792 }
8793 else
8794 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308795 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308796 __func__);
8797 return false;
8798 }
8799}
8800
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308801/**---------------------------------------------------------------------------
8802
8803 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8804 generate function
8805
8806 This is generate the random mac address for WLAN interface
8807
8808 \param - pHddCtx - Pointer to HDD context
8809 idx - Start interface index to get auto
8810 generated mac addr.
8811 mac_addr - Mac address
8812
8813 \return - 0 for success, < 0 for failure
8814
8815 --------------------------------------------------------------------------*/
8816
8817static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8818 int idx, v_MACADDR_t mac_addr)
8819{
8820 int i;
8821 unsigned int serialno;
8822 serialno = wcnss_get_serial_number();
8823
8824 if (0 != serialno)
8825 {
8826 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8827 bytes of the serial number that can be used to generate
8828 the other 3 bytes of the MAC address. Mask off all but
8829 the lower 3 bytes (this will also make sure we don't
8830 overflow in the next step) */
8831 serialno &= 0x00FFFFFF;
8832
8833 /* we need a unique address for each session */
8834 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8835
8836 /* autogen other Mac addresses */
8837 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8838 {
8839 /* start with the entire default address */
8840 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8841 /* then replace the lower 3 bytes */
8842 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8843 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8844 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8845
8846 serialno++;
8847 hddLog(VOS_TRACE_LEVEL_ERROR,
8848 "%s: Derived Mac Addr: "
8849 MAC_ADDRESS_STR, __func__,
8850 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8851 }
8852
8853 }
8854 else
8855 {
8856 hddLog(LOGE, FL("Failed to Get Serial NO"));
8857 return -1;
8858 }
8859 return 0;
8860}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308861
8862/**---------------------------------------------------------------------------
8863
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308864 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8865 completed to flush out the scan results
8866
8867 11d scan is done during driver load and is a passive scan on all
8868 channels supported by the device, 11d scans may find some APs on
8869 frequencies which are forbidden to be used in the regulatory domain
8870 the device is operating in. If these APs are notified to the supplicant
8871 it may try to connect to these APs, thus flush out all the scan results
8872 which are present in SME after 11d scan is done.
8873
8874 \return - eHalStatus
8875
8876 --------------------------------------------------------------------------*/
8877static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8878 tANI_U32 scanId, eCsrScanStatus status)
8879{
8880 ENTER();
8881
8882 sme_ScanFlushResult(halHandle, 0);
8883
8884 EXIT();
8885
8886 return eHAL_STATUS_SUCCESS;
8887}
8888
8889/**---------------------------------------------------------------------------
8890
Jeff Johnson295189b2012-06-20 16:38:30 -07008891 \brief hdd_wlan_startup() - HDD init function
8892
8893 This is the driver startup code executed once a WLAN device has been detected
8894
8895 \param - dev - Pointer to the underlying device
8896
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008897 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008898
8899 --------------------------------------------------------------------------*/
8900
8901int hdd_wlan_startup(struct device *dev )
8902{
8903 VOS_STATUS status;
8904 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008905 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008906 hdd_context_t *pHddCtx = NULL;
8907 v_CONTEXT_t pVosContext= NULL;
8908#ifdef WLAN_BTAMP_FEATURE
8909 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8910 WLANBAP_ConfigType btAmpConfig;
8911 hdd_config_t *pConfig;
8912#endif
8913 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008914 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308915 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008916
8917 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008918 /*
8919 * cfg80211: wiphy allocation
8920 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308921 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008922
8923 if(wiphy == NULL)
8924 {
8925 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008926 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008927 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008928 pHddCtx = wiphy_priv(wiphy);
8929
Jeff Johnson295189b2012-06-20 16:38:30 -07008930 //Initialize the adapter context to zeros.
8931 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8932
Jeff Johnson295189b2012-06-20 16:38:30 -07008933 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008934 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308935 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008936
8937 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8938
8939 /*Get vos context here bcoz vos_open requires it*/
8940 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8941
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008942 if(pVosContext == NULL)
8943 {
8944 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8945 goto err_free_hdd_context;
8946 }
8947
Jeff Johnson295189b2012-06-20 16:38:30 -07008948 //Save the Global VOSS context in adapter context for future.
8949 pHddCtx->pvosContext = pVosContext;
8950
8951 //Save the adapter context in global context for future.
8952 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8953
Jeff Johnson295189b2012-06-20 16:38:30 -07008954 pHddCtx->parent_dev = dev;
8955
8956 init_completion(&pHddCtx->full_pwr_comp_var);
8957 init_completion(&pHddCtx->standby_comp_var);
8958 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008959 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008960 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308961 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308962 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008963
8964#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008965 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008966#else
8967 init_completion(&pHddCtx->driver_crda_req);
8968#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008969
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308970 spin_lock_init(&pHddCtx->schedScan_lock);
8971
Jeff Johnson295189b2012-06-20 16:38:30 -07008972 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8973
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308974#ifdef FEATURE_WLAN_TDLS
8975 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8976 * invoked by other instances also) to protect the concurrent
8977 * access for the Adapters by TDLS module.
8978 */
8979 mutex_init(&pHddCtx->tdls_lock);
8980#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05308981 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05308982 mutex_init(&pHddCtx->wmmLock);
8983
Agarwal Ashish1f422872014-07-22 00:11:55 +05308984 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308985
Agarwal Ashish1f422872014-07-22 00:11:55 +05308986 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008987 // Load all config first as TL config is needed during vos_open
8988 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8989 if(pHddCtx->cfg_ini == NULL)
8990 {
8991 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8992 goto err_free_hdd_context;
8993 }
8994
8995 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8996
8997 // Read and parse the qcom_cfg.ini file
8998 status = hdd_parse_config_ini( pHddCtx );
8999 if ( VOS_STATUS_SUCCESS != status )
9000 {
9001 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9002 __func__, WLAN_INI_FILE);
9003 goto err_config;
9004 }
Arif Hussaind5218912013-12-05 01:10:55 -08009005#ifdef MEMORY_DEBUG
9006 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9007 vos_mem_init();
9008
9009 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9010 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9011#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009012
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309013 /* INI has been read, initialise the configuredMcastBcastFilter with
9014 * INI value as this will serve as the default value
9015 */
9016 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9017 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9018 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309019
9020 if (false == hdd_is_5g_supported(pHddCtx))
9021 {
9022 //5Ghz is not supported.
9023 if (1 != pHddCtx->cfg_ini->nBandCapability)
9024 {
9025 hddLog(VOS_TRACE_LEVEL_INFO,
9026 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9027 pHddCtx->cfg_ini->nBandCapability = 1;
9028 }
9029 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309030
9031 /* If SNR Monitoring is enabled, FW has to parse all beacons
9032 * for calcaluting and storing the average SNR, so set Nth beacon
9033 * filter to 1 to enable FW to parse all the beaocons
9034 */
9035 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9036 {
9037 /* The log level is deliberately set to WARN as overriding
9038 * nthBeaconFilter to 1 will increase power cosumption and this
9039 * might just prove helpful to detect the power issue.
9040 */
9041 hddLog(VOS_TRACE_LEVEL_WARN,
9042 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9043 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9044 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009045 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309046 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009047 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009048 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009049 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009050 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9051 {
9052 hddLog(VOS_TRACE_LEVEL_FATAL,
9053 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9054 goto err_config;
9055 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009056 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009057
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009058 // Update VOS trace levels based upon the cfg.ini
9059 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9060 pHddCtx->cfg_ini->vosTraceEnableBAP);
9061 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9062 pHddCtx->cfg_ini->vosTraceEnableTL);
9063 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9064 pHddCtx->cfg_ini->vosTraceEnableWDI);
9065 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9066 pHddCtx->cfg_ini->vosTraceEnableHDD);
9067 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9068 pHddCtx->cfg_ini->vosTraceEnableSME);
9069 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9070 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309071 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9072 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009073 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9074 pHddCtx->cfg_ini->vosTraceEnableWDA);
9075 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9076 pHddCtx->cfg_ini->vosTraceEnableSYS);
9077 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9078 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009079 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9080 pHddCtx->cfg_ini->vosTraceEnableSAP);
9081 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9082 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009083
Jeff Johnson295189b2012-06-20 16:38:30 -07009084 // Update WDI trace levels based upon the cfg.ini
9085 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9086 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9087 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9088 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9089 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9090 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9091 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9092 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009093
Jeff Johnson88ba7742013-02-27 14:36:02 -08009094 if (VOS_FTM_MODE == hdd_get_conparam())
9095 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009096 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9097 {
9098 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9099 goto err_free_hdd_context;
9100 }
9101 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05309102
9103 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009104 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009105 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009106
Jeff Johnson88ba7742013-02-27 14:36:02 -08009107 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009108 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9109 {
9110 status = vos_watchdog_open(pVosContext,
9111 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9112
9113 if(!VOS_IS_STATUS_SUCCESS( status ))
9114 {
9115 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309116 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009117 }
9118 }
9119
9120 pHddCtx->isLogpInProgress = FALSE;
9121 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9122
Amar Singhala49cbc52013-10-08 18:37:44 -07009123#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009124 /* initialize the NV module. This is required so that
9125 we can initialize the channel information in wiphy
9126 from the NV.bin data. The channel information in
9127 wiphy needs to be initialized before wiphy registration */
9128
9129 status = vos_nv_open();
9130 if (!VOS_IS_STATUS_SUCCESS(status))
9131 {
9132 /* NV module cannot be initialized */
9133 hddLog( VOS_TRACE_LEVEL_FATAL,
9134 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309135 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009136 }
9137
9138 status = vos_init_wiphy_from_nv_bin();
9139 if (!VOS_IS_STATUS_SUCCESS(status))
9140 {
9141 /* NV module cannot be initialized */
9142 hddLog( VOS_TRACE_LEVEL_FATAL,
9143 "%s: vos_init_wiphy failed", __func__);
9144 goto err_vos_nv_close;
9145 }
9146
Amar Singhala49cbc52013-10-08 18:37:44 -07009147#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309148 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309149 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009150 if ( !VOS_IS_STATUS_SUCCESS( status ))
9151 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009152 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309153 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009154 }
9155
Jeff Johnson295189b2012-06-20 16:38:30 -07009156 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9157
9158 if ( NULL == pHddCtx->hHal )
9159 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009160 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009161 goto err_vosclose;
9162 }
9163
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009164 status = vos_preStart( pHddCtx->pvosContext );
9165 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9166 {
9167 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309168 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009169 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009170
Arif Hussaineaf68602013-12-30 23:10:44 -08009171 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9172 {
9173 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9174 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9175 __func__, enable_dfs_chan_scan);
9176 }
9177 if (0 == enable_11d || 1 == enable_11d)
9178 {
9179 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9180 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9181 __func__, enable_11d);
9182 }
9183
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009184 /* Note that the vos_preStart() sequence triggers the cfg download.
9185 The cfg download must occur before we update the SME config
9186 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009187 status = hdd_set_sme_config( pHddCtx );
9188
9189 if ( VOS_STATUS_SUCCESS != status )
9190 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009191 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309192 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009193 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009194
Jeff Johnson295189b2012-06-20 16:38:30 -07009195 /* In the integrated architecture we update the configuration from
9196 the INI file and from NV before vOSS has been started so that
9197 the final contents are available to send down to the cCPU */
9198
9199 // Apply the cfg.ini to cfg.dat
9200 if (FALSE == hdd_update_config_dat(pHddCtx))
9201 {
9202 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309203 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009204 }
9205
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309206 // Get mac addr from platform driver
9207 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9208
9209 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009210 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309211 /* Store the mac addr for first interface */
9212 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9213
9214 hddLog(VOS_TRACE_LEVEL_ERROR,
9215 "%s: WLAN Mac Addr: "
9216 MAC_ADDRESS_STR, __func__,
9217 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9218
9219 /* Here, passing Arg2 as 1 because we do not want to change the
9220 last 3 bytes (means non OUI bytes) of first interface mac
9221 addr.
9222 */
9223 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9224 {
9225 hddLog(VOS_TRACE_LEVEL_ERROR,
9226 "%s: Failed to generate wlan interface mac addr "
9227 "using MAC from ini file ", __func__);
9228 }
9229 }
9230 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9231 {
9232 // Apply the NV to cfg.dat
9233 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009234#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9235 /* There was not a valid set of MAC Addresses in NV. See if the
9236 default addresses were modified by the cfg.ini settings. If so,
9237 we'll use them, but if not, we'll autogenerate a set of MAC
9238 addresses based upon the device serial number */
9239
9240 static const v_MACADDR_t default_address =
9241 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009242
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309243 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9244 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009245 {
9246 /* cfg.ini has the default address, invoke autogen logic */
9247
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309248 /* Here, passing Arg2 as 0 because we want to change the
9249 last 3 bytes (means non OUI bytes) of all the interfaces
9250 mac addr.
9251 */
9252 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9253 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009254 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309255 hddLog(VOS_TRACE_LEVEL_ERROR,
9256 "%s: Failed to generate wlan interface mac addr "
9257 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9258 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009259 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009260 }
9261 else
9262#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9263 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009264 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009265 "%s: Invalid MAC address in NV, using MAC from ini file "
9266 MAC_ADDRESS_STR, __func__,
9267 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9268 }
9269 }
9270 {
9271 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309272
9273 /* Set the MAC Address Currently this is used by HAL to
9274 * add self sta. Remove this once self sta is added as
9275 * part of session open.
9276 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009277 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9278 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9279 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309280
Jeff Johnson295189b2012-06-20 16:38:30 -07009281 if (!HAL_STATUS_SUCCESS( halStatus ))
9282 {
9283 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9284 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309285 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009286 }
9287 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009288
9289 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9290 Note: Firmware image will be read and downloaded inside vos_start API */
9291 status = vos_start( pHddCtx->pvosContext );
9292 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9293 {
9294 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309295 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009296 }
9297
Leo Chang6cec3e22014-01-21 15:33:49 -08009298#ifdef FEATURE_WLAN_CH_AVOID
9299 /* Plug in avoid channel notification callback
9300 * This should happen before ADD_SELF_STA
9301 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309302
9303 /* check the Channel Avoidance is enabled */
9304 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9305 {
9306 sme_AddChAvoidCallback(pHddCtx->hHal,
9307 hdd_hostapd_ch_avoid_cb);
9308 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009309#endif /* FEATURE_WLAN_CH_AVOID */
9310
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009311 /* Exchange capability info between Host and FW and also get versioning info from FW */
9312 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009313
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309314#ifdef CONFIG_ENABLE_LINUX_REG
9315 status = wlan_hdd_init_channels(pHddCtx);
9316 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9317 {
9318 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9319 __func__);
9320 goto err_vosstop;
9321 }
9322#endif
9323
Jeff Johnson295189b2012-06-20 16:38:30 -07009324 status = hdd_post_voss_start_config( pHddCtx );
9325 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9326 {
9327 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9328 __func__);
9329 goto err_vosstop;
9330 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009331
9332#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309333 wlan_hdd_cfg80211_update_reg_info( wiphy );
9334
9335 /* registration of wiphy dev with cfg80211 */
9336 if (0 > wlan_hdd_cfg80211_register(wiphy))
9337 {
9338 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9339 goto err_vosstop;
9340 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009341#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009342
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309343#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309344 /* registration of wiphy dev with cfg80211 */
9345 if (0 > wlan_hdd_cfg80211_register(wiphy))
9346 {
9347 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9348 goto err_vosstop;
9349 }
9350
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309351 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309352 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9353 {
9354 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9355 __func__);
9356 goto err_unregister_wiphy;
9357 }
9358#endif
9359
c_hpothu4a298be2014-12-22 21:12:51 +05309360 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9361
Jeff Johnson295189b2012-06-20 16:38:30 -07009362 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9363 {
9364 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9365 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9366 }
9367 else
9368 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009369 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9370 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9371 if (pAdapter != NULL)
9372 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309373 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009374 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309375 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9376 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9377 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009378
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309379 /* Generate the P2P Device Address. This consists of the device's
9380 * primary MAC address with the locally administered bit set.
9381 */
9382 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009383 }
9384 else
9385 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309386 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9387 if (p2p_dev_addr != NULL)
9388 {
9389 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9390 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9391 }
9392 else
9393 {
9394 hddLog(VOS_TRACE_LEVEL_FATAL,
9395 "%s: Failed to allocate mac_address for p2p_device",
9396 __func__);
9397 goto err_close_adapter;
9398 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009399 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009400
9401 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9402 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9403 if ( NULL == pP2pAdapter )
9404 {
9405 hddLog(VOS_TRACE_LEVEL_FATAL,
9406 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009407 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009408 goto err_close_adapter;
9409 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009410 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009411 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009412
9413 if( pAdapter == NULL )
9414 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009415 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9416 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009417 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009418
Arif Hussain66559122013-11-21 10:11:40 -08009419 if (country_code)
9420 {
9421 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009422 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009423 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9424#ifndef CONFIG_ENABLE_LINUX_REG
9425 hdd_checkandupdate_phymode(pAdapter, country_code);
9426#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009427 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9428 (void *)(tSmeChangeCountryCallback)
9429 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009430 country_code,
9431 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309432 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009433 if (eHAL_STATUS_SUCCESS == ret)
9434 {
Arif Hussaincb607082013-12-20 11:57:42 -08009435 ret = wait_for_completion_interruptible_timeout(
9436 &pAdapter->change_country_code,
9437 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9438
9439 if (0 >= ret)
9440 {
9441 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9442 "%s: SME while setting country code timed out", __func__);
9443 }
Arif Hussain66559122013-11-21 10:11:40 -08009444 }
9445 else
9446 {
Arif Hussaincb607082013-12-20 11:57:42 -08009447 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9448 "%s: SME Change Country code from module param fail ret=%d",
9449 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009450 }
9451 }
9452
Jeff Johnson295189b2012-06-20 16:38:30 -07009453#ifdef WLAN_BTAMP_FEATURE
9454 vStatus = WLANBAP_Open(pVosContext);
9455 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9456 {
9457 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9458 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009459 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009460 }
9461
9462 vStatus = BSL_Init(pVosContext);
9463 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9464 {
9465 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9466 "%s: Failed to Init BSL",__func__);
9467 goto err_bap_close;
9468 }
9469 vStatus = WLANBAP_Start(pVosContext);
9470 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9471 {
9472 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9473 "%s: Failed to start TL",__func__);
9474 goto err_bap_close;
9475 }
9476
9477 pConfig = pHddCtx->cfg_ini;
9478 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9479 status = WLANBAP_SetConfig(&btAmpConfig);
9480
9481#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009482
Mihir Shete9c238772014-10-15 14:35:16 +05309483 /*
9484 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9485 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9486 * which is greater than 0xf. So the below check is safe to make
9487 * sure that there is no entry for UapsdMask in the ini
9488 */
9489 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9490 {
9491 if(IS_DYNAMIC_WMM_PS_ENABLED)
9492 {
9493 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9494 __func__);
9495 pHddCtx->cfg_ini->UapsdMask =
9496 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
9497 }
9498 else
9499 {
9500 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
9501 __func__);
9502 pHddCtx->cfg_ini->UapsdMask =
9503 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
9504 }
9505 }
9506
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07009507#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
9508 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
9509 {
9510 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
9511 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
9512 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
9513 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
9514 }
9515#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009516
Agarwal Ashish4b87f922014-06-18 03:03:21 +05309517 wlan_hdd_tdls_init(pHddCtx);
9518
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309519 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
9520
Jeff Johnson295189b2012-06-20 16:38:30 -07009521 /* Register with platform driver as client for Suspend/Resume */
9522 status = hddRegisterPmOps(pHddCtx);
9523 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9524 {
9525 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
9526#ifdef WLAN_BTAMP_FEATURE
9527 goto err_bap_stop;
9528#else
Jeff Johnsone7245742012-09-05 17:12:55 -07009529 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009530#endif //WLAN_BTAMP_FEATURE
9531 }
9532
Yue Ma0d4891e2013-08-06 17:01:45 -07009533 /* Open debugfs interface */
9534 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
9535 {
9536 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9537 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07009538 }
9539
Jeff Johnson295189b2012-06-20 16:38:30 -07009540 /* Register TM level change handler function to the platform */
9541 status = hddDevTmRegisterNotifyCallback(pHddCtx);
9542 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9543 {
9544 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
9545 goto err_unregister_pmops;
9546 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009547
9548 /* register for riva power on lock to platform driver */
9549 if (req_riva_power_on_lock("wlan"))
9550 {
9551 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9552 __func__);
9553 goto err_unregister_pmops;
9554 }
9555
Jeff Johnson295189b2012-06-20 16:38:30 -07009556 // register net device notifier for device change notification
9557 ret = register_netdevice_notifier(&hdd_netdev_notifier);
9558
9559 if(ret < 0)
9560 {
9561 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
9562 goto err_free_power_on_lock;
9563 }
9564
9565 //Initialize the nlink service
9566 if(nl_srv_init() != 0)
9567 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309568 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009569 goto err_reg_netdev;
9570 }
9571
Leo Chang4ce1cc52013-10-21 18:27:15 -07009572#ifdef WLAN_KD_READY_NOTIFIER
9573 pHddCtx->kd_nl_init = 1;
9574#endif /* WLAN_KD_READY_NOTIFIER */
9575
Jeff Johnson295189b2012-06-20 16:38:30 -07009576 //Initialize the BTC service
9577 if(btc_activate_service(pHddCtx) != 0)
9578 {
9579 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
9580 goto err_nl_srv;
9581 }
9582
9583#ifdef PTT_SOCK_SVC_ENABLE
9584 //Initialize the PTT service
9585 if(ptt_sock_activate_svc(pHddCtx) != 0)
9586 {
9587 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
9588 goto err_nl_srv;
9589 }
9590#endif
9591
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309592#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9593 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
9594 {
Deepthi Gowri78083a32014-11-04 12:55:51 +05309595 if(wlan_logging_sock_activate_svc(
9596 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
9597 pHddCtx->cfg_ini->wlanLoggingNumBuf))
9598 {
9599 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
9600 " failed", __func__);
9601 goto err_nl_srv;
9602 }
9603 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
9604 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +05309605 if (!pHddCtx->cfg_ini->gEnableDebugLog)
9606 pHddCtx->cfg_ini->gEnableDebugLog =
9607 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309608 }
9609#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009610 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009611 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009612 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07009613 /* Action frame registered in one adapter which will
9614 * applicable to all interfaces
9615 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309616 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009617 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009618
9619 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +05309620 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009621
Jeff Johnson295189b2012-06-20 16:38:30 -07009622
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009623#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07009624#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
9625 /* Initialize the wake lcok */
9626 wake_lock_init(&pHddCtx->rx_wake_lock,
9627 WAKE_LOCK_SUSPEND,
9628 "qcom_rx_wakelock");
9629#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08009630 /* Initialize the wake lcok */
9631 wake_lock_init(&pHddCtx->sap_wake_lock,
9632 WAKE_LOCK_SUSPEND,
9633 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009634#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009635
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009636 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
9637 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07009638
Katya Nigam5c306ea2014-06-19 15:39:54 +05309639 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009640 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9641 hdd_allow_suspend();
Katya Nigam5c306ea2014-06-19 15:39:54 +05309642
9643#ifdef FEATURE_WLAN_SCAN_PNO
9644 /*SME must send channel update configuration to RIVA*/
9645 sme_UpdateChannelConfig(pHddCtx->hHal);
9646#endif
Abhishek Singhf644b272014-08-21 02:59:39 +05309647 /* Send the update default channel list to the FW*/
9648 sme_UpdateChannelList(pHddCtx->hHal);
Abhishek Singha306a442013-11-07 18:39:01 +05309649#ifndef CONFIG_ENABLE_LINUX_REG
9650 /*updating wiphy so that regulatory user hints can be processed*/
9651 if (wiphy)
9652 {
9653 regulatory_hint(wiphy, "00");
9654 }
9655#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009656 // Initialize the restart logic
9657 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05309658
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07009659 //Register the traffic monitor timer now
9660 if ( pHddCtx->cfg_ini->dynSplitscan)
9661 {
9662 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
9663 VOS_TIMER_TYPE_SW,
9664 hdd_tx_rx_pkt_cnt_stat_timer_handler,
9665 (void *)pHddCtx);
9666 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05309667#ifdef WLAN_FEATURE_EXTSCAN
9668 sme_EXTScanRegisterCallback(pHddCtx->hHal,
9669 wlan_hdd_cfg80211_extscan_callback,
9670 pHddCtx);
9671#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309672
9673#ifdef WLAN_NS_OFFLOAD
9674 // Register IPv6 notifier to notify if any change in IP
9675 // So that we can reconfigure the offload parameters
9676 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
9677 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
9678 if (ret)
9679 {
9680 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
9681 }
9682 else
9683 {
9684 hddLog(LOGE, FL("Registered IPv6 notifier"));
9685 }
9686#endif
9687
9688 // Register IPv4 notifier to notify if any change in IP
9689 // So that we can reconfigure the offload parameters
9690 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
9691 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
9692 if (ret)
9693 {
9694 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
9695 }
9696 else
9697 {
9698 hddLog(LOGE, FL("Registered IPv4 notifier"));
9699 }
9700
Jeff Johnson295189b2012-06-20 16:38:30 -07009701 goto success;
9702
9703err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07009704#ifdef WLAN_KD_READY_NOTIFIER
9705 nl_srv_exit(pHddCtx->ptt_pid);
9706#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009707 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07009708#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07009709err_reg_netdev:
9710 unregister_netdevice_notifier(&hdd_netdev_notifier);
9711
9712err_free_power_on_lock:
9713 free_riva_power_on_lock("wlan");
9714
9715err_unregister_pmops:
9716 hddDevTmUnregisterNotifyCallback(pHddCtx);
9717 hddDeregisterPmOps(pHddCtx);
9718
Yue Ma0d4891e2013-08-06 17:01:45 -07009719 hdd_debugfs_exit(pHddCtx);
9720
Jeff Johnson295189b2012-06-20 16:38:30 -07009721#ifdef WLAN_BTAMP_FEATURE
9722err_bap_stop:
9723 WLANBAP_Stop(pVosContext);
9724#endif
9725
9726#ifdef WLAN_BTAMP_FEATURE
9727err_bap_close:
9728 WLANBAP_Close(pVosContext);
9729#endif
9730
Jeff Johnson295189b2012-06-20 16:38:30 -07009731err_close_adapter:
9732 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309733#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309734err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309735#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309736 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009737err_vosstop:
9738 vos_stop(pVosContext);
9739
Amar Singhala49cbc52013-10-08 18:37:44 -07009740err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07009741 status = vos_sched_close( pVosContext );
9742 if (!VOS_IS_STATUS_SUCCESS(status)) {
9743 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9744 "%s: Failed to close VOSS Scheduler", __func__);
9745 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9746 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009747 vos_close(pVosContext );
9748
Amar Singhal0a402232013-10-11 20:57:16 -07009749err_vos_nv_close:
9750
c_hpothue6a36282014-03-19 12:27:38 +05309751#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009752 vos_nv_close();
9753
c_hpothu70f8d812014-03-22 22:59:23 +05309754#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009755
9756err_wdclose:
9757 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9758 vos_watchdog_close(pVosContext);
9759
Jeff Johnson295189b2012-06-20 16:38:30 -07009760err_config:
9761 kfree(pHddCtx->cfg_ini);
9762 pHddCtx->cfg_ini= NULL;
9763
9764err_free_hdd_context:
9765 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009766 wiphy_free(wiphy) ;
9767 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009768 VOS_BUG(1);
9769
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009770 if (hdd_is_ssr_required())
9771 {
9772 /* WDI timeout had happened during load, so SSR is needed here */
9773 subsystem_restart("wcnss");
9774 msleep(5000);
9775 }
9776 hdd_set_ssr_required (VOS_FALSE);
9777
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009778 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009779
9780success:
9781 EXIT();
9782 return 0;
9783}
9784
9785/**---------------------------------------------------------------------------
9786
Jeff Johnson32d95a32012-09-10 13:15:23 -07009787 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009788
Jeff Johnson32d95a32012-09-10 13:15:23 -07009789 This is the driver entry point - called in different timeline depending
9790 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009791
9792 \param - None
9793
9794 \return - 0 for success, non zero for failure
9795
9796 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009797static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009798{
9799 VOS_STATUS status;
9800 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009801 struct device *dev = NULL;
9802 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009803#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9804 int max_retries = 0;
9805#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009806
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309807#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9808 wlan_logging_sock_init_svc();
9809#endif
9810
Jeff Johnson295189b2012-06-20 16:38:30 -07009811 ENTER();
9812
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009813#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009814 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009815#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009816
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309817 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009818 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9819 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9820
Jeff Johnson295189b2012-06-20 16:38:30 -07009821#ifdef ANI_BUS_TYPE_PCI
9822
9823 dev = wcnss_wlan_get_device();
9824
9825#endif // ANI_BUS_TYPE_PCI
9826
9827#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009828
9829#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9830 /* wait until WCNSS driver downloads NV */
9831 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9832 msleep(1000);
9833 }
9834 if (max_retries >= 5) {
9835 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309836#ifdef WLAN_OPEN_SOURCE
9837 wake_lock_destroy(&wlan_wake_lock);
9838#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309839
9840#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9841 wlan_logging_sock_deinit_svc();
9842#endif
9843
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009844 return -ENODEV;
9845 }
9846#endif
9847
Jeff Johnson295189b2012-06-20 16:38:30 -07009848 dev = wcnss_wlan_get_device();
9849#endif // ANI_BUS_TYPE_PLATFORM
9850
9851
9852 do {
9853 if (NULL == dev) {
9854 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9855 ret_status = -1;
9856 break;
9857 }
9858
Jeff Johnson295189b2012-06-20 16:38:30 -07009859#ifdef TIMER_MANAGER
9860 vos_timer_manager_init();
9861#endif
9862
9863 /* Preopen VOSS so that it is ready to start at least SAL */
9864 status = vos_preOpen(&pVosContext);
9865
9866 if (!VOS_IS_STATUS_SUCCESS(status))
9867 {
9868 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9869 ret_status = -1;
9870 break;
9871 }
9872
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009873#ifndef MODULE
9874 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9875 */
9876 hdd_set_conparam((v_UINT_t)con_mode);
9877#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009878
9879 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009880 if (hdd_wlan_startup(dev))
9881 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009882 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009883 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009884 vos_preClose( &pVosContext );
9885 ret_status = -1;
9886 break;
9887 }
9888
Jeff Johnson295189b2012-06-20 16:38:30 -07009889 } while (0);
9890
9891 if (0 != ret_status)
9892 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009893#ifdef TIMER_MANAGER
9894 vos_timer_exit();
9895#endif
9896#ifdef MEMORY_DEBUG
9897 vos_mem_exit();
9898#endif
9899
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009900#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009901 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009902#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309903
9904#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9905 wlan_logging_sock_deinit_svc();
9906#endif
9907
Jeff Johnson295189b2012-06-20 16:38:30 -07009908 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9909 }
9910 else
9911 {
9912 //Send WLAN UP indication to Nlink Service
9913 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9914
9915 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009916 }
9917
9918 EXIT();
9919
9920 return ret_status;
9921}
9922
Jeff Johnson32d95a32012-09-10 13:15:23 -07009923/**---------------------------------------------------------------------------
9924
9925 \brief hdd_module_init() - Init Function
9926
9927 This is the driver entry point (invoked when module is loaded using insmod)
9928
9929 \param - None
9930
9931 \return - 0 for success, non zero for failure
9932
9933 --------------------------------------------------------------------------*/
9934#ifdef MODULE
9935static int __init hdd_module_init ( void)
9936{
9937 return hdd_driver_init();
9938}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009939#else /* #ifdef MODULE */
9940static int __init hdd_module_init ( void)
9941{
9942 /* Driver initialization is delayed to fwpath_changed_handler */
9943 return 0;
9944}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009945#endif /* #ifdef MODULE */
9946
Jeff Johnson295189b2012-06-20 16:38:30 -07009947
9948/**---------------------------------------------------------------------------
9949
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009950 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009951
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009952 This is the driver exit point (invoked when module is unloaded using rmmod
9953 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009954
9955 \param - None
9956
9957 \return - None
9958
9959 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009960static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009961{
9962 hdd_context_t *pHddCtx = NULL;
9963 v_CONTEXT_t pVosContext = NULL;
Siddharth Bhala204f572015-01-17 02:03:36 +05309964 pVosWatchdogContext pVosWDCtx = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +05309965 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309966 unsigned long rc = 0;
Siddharth Bhala204f572015-01-17 02:03:36 +05309967 unsigned long flags;
Jeff Johnson295189b2012-06-20 16:38:30 -07009968
9969 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9970
9971 //Get the global vos context
9972 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9973
9974 if(!pVosContext)
9975 {
9976 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
9977 goto done;
9978 }
9979
9980 //Get the HDD context.
9981 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
9982
9983 if(!pHddCtx)
9984 {
9985 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
9986 }
9987 else
9988 {
Siddharth Bhala204f572015-01-17 02:03:36 +05309989 pVosWDCtx = get_vos_watchdog_ctxt();
9990 if(pVosWDCtx == NULL)
9991 {
9992 hddLog(VOS_TRACE_LEVEL_ERROR, FL("WD context is invalid"));
9993 goto done;
9994 }
Mahesh A Saptasagard477b092015-02-06 15:12:16 +05309995 rtnl_lock();
9996 hdd_nullify_netdev_ops(pHddCtx);
9997 rtnl_unlock();
Siddharth Bhala204f572015-01-17 02:03:36 +05309998 spin_lock_irqsave(&pVosWDCtx->wdLock, flags);
9999 if (!pHddCtx->isLogpInProgress || (TRUE ==
10000 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10001 {
10002 //SSR isn't in progress OR last wlan reinit wasn't successful
10003 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10004 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
10005 spin_unlock_irqrestore(&pVosWDCtx->wdLock, flags);
10006 }
10007 else
10008 {
10009 INIT_COMPLETION(pHddCtx->ssr_comp_var);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053010010
Siddharth Bhala204f572015-01-17 02:03:36 +053010011 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10012 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
10013 spin_unlock_irqrestore(&pVosWDCtx->wdLock, flags);
Jeff Johnson295189b2012-06-20 16:38:30 -070010014
Siddharth Bhala204f572015-01-17 02:03:36 +053010015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10016 "%s:SSR is in Progress; block rmmod !!!", __func__);
10017 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10018 msecs_to_jiffies(30000));
10019 if(!rc)
10020 {
10021 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10022 "%s:SSR timedout, fatal error", __func__);
10023 VOS_BUG(0);
10024 }
10025 }
10026
10027 /* We wait for active entry threads to exit from driver
10028 * by waiting until rtnl_lock is available.
10029 */
10030 rtnl_lock();
10031 rtnl_unlock();
Jeff Johnson295189b2012-06-20 16:38:30 -070010032
c_hpothu8adb97b2014-12-08 19:38:20 +053010033 /* Driver Need to send country code 00 in below condition
10034 * 1) If gCountryCodePriority is set to 1; and last country
10035 * code set is through 11d. This needs to be done in case
10036 * when NV country code is 00.
10037 * This Needs to be done as when kernel store last country
10038 * code and if stored country code is not through 11d,
10039 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10040 * in next load/unload as soon as we get any country through
10041 * 11d. In sme_HandleChangeCountryCodeByUser
10042 * pMsg->countryCode will be last countryCode and
10043 * pMac->scan.countryCode11d will be country through 11d so
10044 * due to mismatch driver will disable 11d.
10045 *
10046 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010047
c_hpothu8adb97b2014-12-08 19:38:20 +053010048 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010049 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010050 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010051 {
10052 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010053 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010054 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10055 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010056
c_hpothu8adb97b2014-12-08 19:38:20 +053010057 //Do all the cleanup before deregistering the driver
10058 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010059 }
10060
Jeff Johnson295189b2012-06-20 16:38:30 -070010061 vos_preClose( &pVosContext );
10062
10063#ifdef TIMER_MANAGER
10064 vos_timer_exit();
10065#endif
10066#ifdef MEMORY_DEBUG
10067 vos_mem_exit();
10068#endif
10069
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010070#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10071 wlan_logging_sock_deinit_svc();
10072#endif
10073
Jeff Johnson295189b2012-06-20 16:38:30 -070010074done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -080010075#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -070010076 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070010077#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010078
Jeff Johnson295189b2012-06-20 16:38:30 -070010079 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10080}
10081
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010082/**---------------------------------------------------------------------------
10083
10084 \brief hdd_module_exit() - Exit function
10085
10086 This is the driver exit point (invoked when module is unloaded using rmmod)
10087
10088 \param - None
10089
10090 \return - None
10091
10092 --------------------------------------------------------------------------*/
10093static void __exit hdd_module_exit(void)
10094{
10095 hdd_driver_exit();
10096}
10097
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010098#ifdef MODULE
10099static int fwpath_changed_handler(const char *kmessage,
10100 struct kernel_param *kp)
10101{
Jeff Johnson76052702013-04-16 13:55:05 -070010102 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010103}
10104
10105static int con_mode_handler(const char *kmessage,
10106 struct kernel_param *kp)
10107{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010108 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010109}
10110#else /* #ifdef MODULE */
10111/**---------------------------------------------------------------------------
10112
Jeff Johnson76052702013-04-16 13:55:05 -070010113 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010114
Jeff Johnson76052702013-04-16 13:55:05 -070010115 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010116 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010117 - invoked when module parameter fwpath is modified from userspace to signal
10118 initializing the WLAN driver or when con_mode is modified from userspace
10119 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010120
10121 \return - 0 for success, non zero for failure
10122
10123 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010124static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010125{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010126 int ret_status;
10127
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010128 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010129 ret_status = hdd_driver_init();
10130 wlan_hdd_inited = ret_status ? 0 : 1;
10131 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010132 }
10133
10134 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010135
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010136 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010137
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010138 ret_status = hdd_driver_init();
10139 wlan_hdd_inited = ret_status ? 0 : 1;
10140 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010141}
10142
Jeff Johnson295189b2012-06-20 16:38:30 -070010143/**---------------------------------------------------------------------------
10144
Jeff Johnson76052702013-04-16 13:55:05 -070010145 \brief fwpath_changed_handler() - Handler Function
10146
10147 Handle changes to the fwpath parameter
10148
10149 \return - 0 for success, non zero for failure
10150
10151 --------------------------------------------------------------------------*/
10152static int fwpath_changed_handler(const char *kmessage,
10153 struct kernel_param *kp)
10154{
10155 int ret;
10156
10157 ret = param_set_copystring(kmessage, kp);
10158 if (0 == ret)
10159 ret = kickstart_driver();
10160 return ret;
10161}
10162
10163/**---------------------------------------------------------------------------
10164
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010165 \brief con_mode_handler() -
10166
10167 Handler function for module param con_mode when it is changed by userspace
10168 Dynamically linked - do nothing
10169 Statically linked - exit and init driver, as in rmmod and insmod
10170
Jeff Johnson76052702013-04-16 13:55:05 -070010171 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010172
Jeff Johnson76052702013-04-16 13:55:05 -070010173 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010174
10175 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010176static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010177{
Jeff Johnson76052702013-04-16 13:55:05 -070010178 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010179
Jeff Johnson76052702013-04-16 13:55:05 -070010180 ret = param_set_int(kmessage, kp);
10181 if (0 == ret)
10182 ret = kickstart_driver();
10183 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010184}
10185#endif /* #ifdef MODULE */
10186
10187/**---------------------------------------------------------------------------
10188
Jeff Johnson295189b2012-06-20 16:38:30 -070010189 \brief hdd_get_conparam() -
10190
10191 This is the driver exit point (invoked when module is unloaded using rmmod)
10192
10193 \param - None
10194
10195 \return - tVOS_CON_MODE
10196
10197 --------------------------------------------------------------------------*/
10198tVOS_CON_MODE hdd_get_conparam ( void )
10199{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010200#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010201 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010202#else
10203 return (tVOS_CON_MODE)curr_con_mode;
10204#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010205}
10206void hdd_set_conparam ( v_UINT_t newParam )
10207{
10208 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010209#ifndef MODULE
10210 curr_con_mode = con_mode;
10211#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010212}
10213/**---------------------------------------------------------------------------
10214
10215 \brief hdd_softap_sta_deauth() - function
10216
10217 This to take counter measure to handle deauth req from HDD
10218
10219 \param - pAdapter - Pointer to the HDD
10220
10221 \param - enable - boolean value
10222
10223 \return - None
10224
10225 --------------------------------------------------------------------------*/
10226
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010227VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10228 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010229{
Jeff Johnson295189b2012-06-20 16:38:30 -070010230 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010231 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010232
10233 ENTER();
10234
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010235 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10236 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010237
10238 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010239 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010240 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010241
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010242 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010243
10244 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010245 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010246}
10247
10248/**---------------------------------------------------------------------------
10249
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010250 \brief hdd_del_all_sta() - function
10251
10252 This function removes all the stations associated on stopping AP/P2P GO.
10253
10254 \param - pAdapter - Pointer to the HDD
10255
10256 \return - None
10257
10258 --------------------------------------------------------------------------*/
10259
10260int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10261{
10262 v_U16_t i;
10263 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010264 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10265 ptSapContext pSapCtx = NULL;
10266 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10267 if(pSapCtx == NULL){
10268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10269 FL("psapCtx is NULL"));
10270 return 1;
10271 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010272 ENTER();
10273
10274 hddLog(VOS_TRACE_LEVEL_INFO,
10275 "%s: Delete all STAs associated.",__func__);
10276 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10277 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10278 )
10279 {
10280 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10281 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010282 if ((pSapCtx->aStaInfo[i].isUsed) &&
10283 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010284 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010285 struct tagCsrDelStaParams delStaParams;
10286
10287 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010288 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010289 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10290 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010291 &delStaParams);
10292 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010293 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010294 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010295 }
10296 }
10297 }
10298
10299 EXIT();
10300 return 0;
10301}
10302
10303/**---------------------------------------------------------------------------
10304
Jeff Johnson295189b2012-06-20 16:38:30 -070010305 \brief hdd_softap_sta_disassoc() - function
10306
10307 This to take counter measure to handle deauth req from HDD
10308
10309 \param - pAdapter - Pointer to the HDD
10310
10311 \param - enable - boolean value
10312
10313 \return - None
10314
10315 --------------------------------------------------------------------------*/
10316
10317void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10318{
10319 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10320
10321 ENTER();
10322
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010323 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010324
10325 //Ignore request to disassoc bcmc station
10326 if( pDestMacAddress[0] & 0x1 )
10327 return;
10328
10329 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10330}
10331
10332void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10333{
10334 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10335
10336 ENTER();
10337
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010338 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010339
10340 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10341}
10342
Jeff Johnson295189b2012-06-20 16:38:30 -070010343/**---------------------------------------------------------------------------
10344 *
10345 * \brief hdd_get__concurrency_mode() -
10346 *
10347 *
10348 * \param - None
10349 *
10350 * \return - CONCURRENCY MODE
10351 *
10352 * --------------------------------------------------------------------------*/
10353tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10354{
10355 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10356 hdd_context_t *pHddCtx;
10357
10358 if (NULL != pVosContext)
10359 {
10360 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10361 if (NULL != pHddCtx)
10362 {
10363 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10364 }
10365 }
10366
10367 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010368 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010369 return VOS_STA;
10370}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010371v_BOOL_t
10372wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10373{
10374 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010375
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010376 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10377 if (pAdapter == NULL)
10378 {
10379 hddLog(VOS_TRACE_LEVEL_INFO,
10380 FL("GO doesn't exist"));
10381 return TRUE;
10382 }
10383 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10384 {
10385 hddLog(VOS_TRACE_LEVEL_INFO,
10386 FL("GO started"));
10387 return TRUE;
10388 }
10389 else
10390 /* wait till GO changes its interface to p2p device */
10391 hddLog(VOS_TRACE_LEVEL_INFO,
10392 FL("Del_bss called, avoid apps suspend"));
10393 return FALSE;
10394
10395}
Jeff Johnson295189b2012-06-20 16:38:30 -070010396/* Decide whether to allow/not the apps power collapse.
10397 * Allow apps power collapse if we are in connected state.
10398 * if not, allow only if we are in IMPS */
10399v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10400{
10401 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010402 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010403 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010404 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10405 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10406 hdd_adapter_t *pAdapter = NULL;
10407 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010408 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010409
Jeff Johnson295189b2012-06-20 16:38:30 -070010410 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10411 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010412
Yathish9f22e662012-12-10 14:21:35 -080010413 concurrent_state = hdd_get_concurrency_mode();
10414
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010415 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10416 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10417 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010418#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010419
Yathish9f22e662012-12-10 14:21:35 -080010420 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010421 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010422 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10423 return TRUE;
10424#endif
10425
Jeff Johnson295189b2012-06-20 16:38:30 -070010426 /*loop through all adapters. TBD fix for Concurrency */
10427 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10428 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10429 {
10430 pAdapter = pAdapterNode->pAdapter;
10431 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10432 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10433 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010434 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010435 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010436 && pmcState != STOPPED && pmcState != STANDBY &&
10437 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010438 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10439 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010440 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010441 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010442 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10443 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010444 return FALSE;
10445 }
10446 }
10447 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10448 pAdapterNode = pNext;
10449 }
10450 return TRUE;
10451}
10452
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010453/* Decides whether to send suspend notification to Riva
10454 * if any adapter is in BMPS; then it is required */
10455v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10456{
10457 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10458 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10459
10460 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10461 {
10462 return TRUE;
10463 }
10464 return FALSE;
10465}
10466
Jeff Johnson295189b2012-06-20 16:38:30 -070010467void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10468{
10469 switch(mode)
10470 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010471 case VOS_STA_MODE:
10472 case VOS_P2P_CLIENT_MODE:
10473 case VOS_P2P_GO_MODE:
10474 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010475 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010476 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010477 break;
10478 default:
10479 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010480 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010481 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10482 "Number of open sessions for mode %d = %d"),
10483 pHddCtx->concurrency_mode, mode,
10484 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010485}
10486
10487
10488void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10489{
10490 switch(mode)
10491 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010492 case VOS_STA_MODE:
10493 case VOS_P2P_CLIENT_MODE:
10494 case VOS_P2P_GO_MODE:
10495 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053010496 pHddCtx->no_of_open_sessions[mode]--;
10497 if (!(pHddCtx->no_of_open_sessions[mode]))
10498 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070010499 break;
10500 default:
10501 break;
10502 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010503 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10504 "Number of open sessions for mode %d = %d"),
10505 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
10506
10507}
10508/**---------------------------------------------------------------------------
10509 *
10510 * \brief wlan_hdd_incr_active_session()
10511 *
10512 * This function increments the number of active sessions
10513 * maintained per device mode
10514 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
10515 * Incase of SAP/P2P GO upon bss start it is incremented
10516 *
10517 * \param pHddCtx - HDD Context
10518 * \param mode - device mode
10519 *
10520 * \return - None
10521 *
10522 * --------------------------------------------------------------------------*/
10523void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10524{
10525 switch (mode) {
10526 case VOS_STA_MODE:
10527 case VOS_P2P_CLIENT_MODE:
10528 case VOS_P2P_GO_MODE:
10529 case VOS_STA_SAP_MODE:
10530 pHddCtx->no_of_active_sessions[mode]++;
10531 break;
10532 default:
10533 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10534 break;
10535 }
10536 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10537 mode,
10538 pHddCtx->no_of_active_sessions[mode]);
10539}
10540
10541/**---------------------------------------------------------------------------
10542 *
10543 * \brief wlan_hdd_decr_active_session()
10544 *
10545 * This function decrements the number of active sessions
10546 * maintained per device mode
10547 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
10548 * Incase of SAP/P2P GO upon bss stop it is decremented
10549 *
10550 * \param pHddCtx - HDD Context
10551 * \param mode - device mode
10552 *
10553 * \return - None
10554 *
10555 * --------------------------------------------------------------------------*/
10556void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10557{
10558 switch (mode) {
10559 case VOS_STA_MODE:
10560 case VOS_P2P_CLIENT_MODE:
10561 case VOS_P2P_GO_MODE:
10562 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053010563 if (pHddCtx->no_of_active_sessions[mode] > 0)
10564 pHddCtx->no_of_active_sessions[mode]--;
10565 else
10566 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
10567 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053010568 break;
10569 default:
10570 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10571 break;
10572 }
10573 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10574 mode,
10575 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010576}
10577
Jeff Johnsone7245742012-09-05 17:12:55 -070010578/**---------------------------------------------------------------------------
10579 *
10580 * \brief wlan_hdd_restart_init
10581 *
10582 * This function initalizes restart timer/flag. An internal function.
10583 *
10584 * \param - pHddCtx
10585 *
10586 * \return - None
10587 *
10588 * --------------------------------------------------------------------------*/
10589
10590static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
10591{
10592 /* Initialize */
10593 pHddCtx->hdd_restart_retries = 0;
10594 atomic_set(&pHddCtx->isRestartInProgress, 0);
10595 vos_timer_init(&pHddCtx->hdd_restart_timer,
10596 VOS_TIMER_TYPE_SW,
10597 wlan_hdd_restart_timer_cb,
10598 pHddCtx);
10599}
10600/**---------------------------------------------------------------------------
10601 *
10602 * \brief wlan_hdd_restart_deinit
10603 *
10604 * This function cleans up the resources used. An internal function.
10605 *
10606 * \param - pHddCtx
10607 *
10608 * \return - None
10609 *
10610 * --------------------------------------------------------------------------*/
10611
10612static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
10613{
10614
10615 VOS_STATUS vos_status;
10616 /* Block any further calls */
10617 atomic_set(&pHddCtx->isRestartInProgress, 1);
10618 /* Cleanup */
10619 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
10620 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010621 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010622 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
10623 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010624 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010625
10626}
10627
10628/**---------------------------------------------------------------------------
10629 *
10630 * \brief wlan_hdd_framework_restart
10631 *
10632 * This function uses a cfg80211 API to start a framework initiated WLAN
10633 * driver module unload/load.
10634 *
10635 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
10636 *
10637 *
10638 * \param - pHddCtx
10639 *
10640 * \return - VOS_STATUS_SUCCESS: Success
10641 * VOS_STATUS_E_EMPTY: Adapter is Empty
10642 * VOS_STATUS_E_NOMEM: No memory
10643
10644 * --------------------------------------------------------------------------*/
10645
10646static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
10647{
10648 VOS_STATUS status = VOS_STATUS_SUCCESS;
10649 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010650 int len = (sizeof (struct ieee80211_mgmt));
10651 struct ieee80211_mgmt *mgmt = NULL;
10652
10653 /* Prepare the DEAUTH managment frame with reason code */
10654 mgmt = kzalloc(len, GFP_KERNEL);
10655 if(mgmt == NULL)
10656 {
10657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10658 "%s: memory allocation failed (%d bytes)", __func__, len);
10659 return VOS_STATUS_E_NOMEM;
10660 }
10661 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070010662
10663 /* Iterate over all adapters/devices */
10664 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10665 do
10666 {
10667 if( (status == VOS_STATUS_SUCCESS) &&
10668 pAdapterNode &&
10669 pAdapterNode->pAdapter)
10670 {
10671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10672 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
10673 pAdapterNode->pAdapter->dev->name,
10674 pAdapterNode->pAdapter->device_mode,
10675 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010676 /*
10677 * CFG80211 event to restart the driver
10678 *
10679 * 'cfg80211_send_unprot_deauth' sends a
10680 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
10681 * of SME(Linux Kernel) state machine.
10682 *
10683 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
10684 * the driver.
10685 *
10686 */
10687
10688 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070010689 }
10690 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10691 pAdapterNode = pNext;
10692 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
10693
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010694
10695 /* Free the allocated management frame */
10696 kfree(mgmt);
10697
Jeff Johnsone7245742012-09-05 17:12:55 -070010698 /* Retry until we unload or reach max count */
10699 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
10700 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
10701
10702 return status;
10703
10704}
10705/**---------------------------------------------------------------------------
10706 *
10707 * \brief wlan_hdd_restart_timer_cb
10708 *
10709 * Restart timer callback. An internal function.
10710 *
10711 * \param - User data:
10712 *
10713 * \return - None
10714 *
10715 * --------------------------------------------------------------------------*/
10716
10717void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
10718{
10719 hdd_context_t *pHddCtx = usrDataForCallback;
10720 wlan_hdd_framework_restart(pHddCtx);
10721 return;
10722
10723}
10724
10725
10726/**---------------------------------------------------------------------------
10727 *
10728 * \brief wlan_hdd_restart_driver
10729 *
10730 * This function sends an event to supplicant to restart the WLAN driver.
10731 *
10732 * This function is called from vos_wlanRestart.
10733 *
10734 * \param - pHddCtx
10735 *
10736 * \return - VOS_STATUS_SUCCESS: Success
10737 * VOS_STATUS_E_EMPTY: Adapter is Empty
10738 * VOS_STATUS_E_ALREADY: Request already in progress
10739
10740 * --------------------------------------------------------------------------*/
10741VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
10742{
10743 VOS_STATUS status = VOS_STATUS_SUCCESS;
10744
10745 /* A tight check to make sure reentrancy */
10746 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
10747 {
Mihir Shetefd528652014-06-23 19:07:50 +053010748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070010749 "%s: WLAN restart is already in progress", __func__);
10750
10751 return VOS_STATUS_E_ALREADY;
10752 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070010753 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080010754#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070010755 wcnss_reset_intr();
10756#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010757
Jeff Johnsone7245742012-09-05 17:12:55 -070010758 return status;
10759}
10760
Mihir Shetee1093ba2014-01-21 20:13:32 +053010761/**---------------------------------------------------------------------------
10762 *
10763 * \brief wlan_hdd_init_channels
10764 *
10765 * This function is used to initialize the channel list in CSR
10766 *
10767 * This function is called from hdd_wlan_startup
10768 *
10769 * \param - pHddCtx: HDD context
10770 *
10771 * \return - VOS_STATUS_SUCCESS: Success
10772 * VOS_STATUS_E_FAULT: Failure reported by SME
10773
10774 * --------------------------------------------------------------------------*/
10775static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
10776{
10777 eHalStatus status;
10778
10779 status = sme_InitChannels(pHddCtx->hHal);
10780 if (HAL_STATUS_SUCCESS(status))
10781 {
10782 return VOS_STATUS_SUCCESS;
10783 }
10784 else
10785 {
10786 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
10787 __func__, status);
10788 return VOS_STATUS_E_FAULT;
10789 }
10790}
10791
Mihir Shete04206452014-11-20 17:50:58 +053010792#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010793VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010794{
10795 eHalStatus status;
10796
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010797 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010798 if (HAL_STATUS_SUCCESS(status))
10799 {
10800 return VOS_STATUS_SUCCESS;
10801 }
10802 else
10803 {
10804 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
10805 __func__, status);
10806 return VOS_STATUS_E_FAULT;
10807 }
10808}
Mihir Shete04206452014-11-20 17:50:58 +053010809#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070010810/*
10811 * API to find if there is any STA or P2P-Client is connected
10812 */
10813VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
10814{
10815 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
10816}
Jeff Johnsone7245742012-09-05 17:12:55 -070010817
Agarwal Ashish57e84372014-12-05 18:26:53 +053010818/*
10819 * API to find if there is any session connected
10820 */
10821VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
10822{
10823 return sme_is_any_session_connected(pHddCtx->hHal);
10824}
10825
10826
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010827int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
10828{
10829 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10830 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053010831 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053010832 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010833
10834 pScanInfo = &pHddCtx->scan_info;
10835 if (pScanInfo->mScanPending)
10836 {
c_hpothua3d45d52015-01-05 14:11:17 +053010837 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
10838 eCSR_SCAN_ABORT_DEFAULT);
10839 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10840 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010841
c_hpothua3d45d52015-01-05 14:11:17 +053010842 /* If there is active scan command lets wait for the completion else
10843 * there is no need to wait as scan command might be in the SME pending
10844 * command list.
10845 */
10846 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
10847 {
10848 INIT_COMPLETION(pScanInfo->abortscan_event_var);
10849 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010850 &pScanInfo->abortscan_event_var,
10851 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053010852 if (0 >= status)
10853 {
10854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053010855 "%s: Timeout or Interrupt occurred while waiting for abort"
10856 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053010857 return -ETIMEDOUT;
10858 }
10859 }
10860 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
10861 {
10862 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10863 FL("hdd_abort_mac_scan failed"));
10864 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010865 }
10866 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053010867 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010868}
10869
c_hpothu225aa7c2014-10-22 17:45:13 +053010870VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
10871{
10872 hdd_adapter_t *pAdapter;
10873 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10874 VOS_STATUS vosStatus;
10875
10876 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10877 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
10878 {
10879 pAdapter = pAdapterNode->pAdapter;
10880 if (NULL != pAdapter)
10881 {
10882 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
10883 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
10884 WLAN_HDD_P2P_GO == pAdapter->device_mode)
10885 {
10886 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
10887 pAdapter->device_mode);
10888 if (VOS_STATUS_SUCCESS !=
10889 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
10890 {
10891 hddLog(LOGE, FL("failed to abort ROC"));
10892 return VOS_STATUS_E_FAILURE;
10893 }
10894 }
10895 }
10896 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10897 pAdapterNode = pNext;
10898 }
10899 return VOS_STATUS_SUCCESS;
10900}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053010901
Mihir Shete0be28772015-02-17 18:42:14 +053010902hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
10903{
10904 hdd_adapter_t *pAdapter;
10905 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10906 hdd_cfg80211_state_t *cfgState;
10907 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
10908 VOS_STATUS vosStatus;
10909
10910 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
10911 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
10912 {
10913 pAdapter = pAdapterNode->pAdapter;
10914 if (NULL != pAdapter)
10915 {
10916 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
10917 pRemainChanCtx = cfgState->remain_on_chan_ctx;
10918 if (pRemainChanCtx)
10919 break;
10920 }
10921 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
10922 pAdapterNode = pNext;
10923 }
10924 return pRemainChanCtx;
10925}
10926
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053010927void hdd_nullify_netdev_ops(hdd_context_t *pHddCtx)
10928{
10929 VOS_STATUS status;
10930 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10931 hdd_adapter_t *pAdapter;
10932
10933 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10934 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10935 {
10936 pAdapter = pAdapterNode->pAdapter;
10937 if (NULL != pAdapter)
10938 {
10939 /* Disable TX on the interface, after this hard_start_xmit() will
10940 * not be called on that interface
10941 */
10942 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10943 netif_tx_disable(pAdapter->dev);
10944 /* Mark the interface status as "down" for outside world */
10945 netif_carrier_off(pAdapter->dev);
10946 pAdapter->dev->netdev_ops = &nullify_netdev_ops;
10947 }
10948 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10949 pAdapterNode = pNext;
10950 }
10951}
10952
Jeff Johnson295189b2012-06-20 16:38:30 -070010953//Register the module init/exit functions
10954module_init(hdd_module_init);
10955module_exit(hdd_module_exit);
10956
10957MODULE_LICENSE("Dual BSD/GPL");
10958MODULE_AUTHOR("Qualcomm Atheros, Inc.");
10959MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
10960
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010961module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
10962 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010963
Jeff Johnson76052702013-04-16 13:55:05 -070010964module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010965 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080010966
10967module_param(enable_dfs_chan_scan, int,
10968 S_IRUSR | S_IRGRP | S_IROTH);
10969
10970module_param(enable_11d, int,
10971 S_IRUSR | S_IRGRP | S_IROTH);
10972
10973module_param(country_code, charp,
10974 S_IRUSR | S_IRGRP | S_IROTH);