blob: f356dedbbc422455e01ee07b5bb3093c4fa6be3b [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +05302 * Copyright (c) 2012-2016 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
Abhishek Singh00b71972016-01-07 10:51:04 +0530179#ifdef WLAN_FEATURE_RMC
180/*
181 * Ibss prop IE from command will be of size:
182 * size = sizeof(oui) + sizeof(oui_data) + 1(Element ID) + 1(EID Length)
183 * OUI_DATA should be at least 3 bytes long
184 */
185#define WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH (3)
186#endif
187
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800188#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700189#define TID_MIN_VALUE 0
190#define TID_MAX_VALUE 15
191static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
192 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800193static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
194 tCsrEseBeaconReq *pEseBcnReq);
195#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700196
Atul Mittal1d722422014-03-19 11:15:07 +0530197/*
198 * Maximum buffer size used for returning the data back to user space
199 */
200#define WLAN_MAX_BUF_SIZE 1024
201#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700202
Abhishek Singh00b71972016-01-07 10:51:04 +0530203/*
204 * When ever we need to print IBSSPEERINFOALL for morethan 16 STA
205 * we will split the printing.
206 */
207#define NUM_OF_STA_DATA_TO_PRINT 16
208
209#ifdef WLAN_FEATURE_RMC
210#define WLAN_NLINK_CESIUM 30
211#endif
212
c_hpothu92367912014-05-01 15:18:17 +0530213//wait time for beacon miss rate.
214#define BCN_MISS_RATE_TIME 500
215
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +0530216/*
217 * Android DRIVER command structures
218 */
219struct android_wifi_reassoc_params {
220 unsigned char bssid[18];
221 int channel;
222};
223
Sushant Kaushik83392fa2015-05-05 17:44:40 +0530224static vos_wake_lock_t wlan_wake_lock;
225
Jeff Johnson295189b2012-06-20 16:38:30 -0700226/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700227static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700228
229//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700230static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
231static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
232static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
Abhishek Singh00b71972016-01-07 10:51:04 +0530233
234#ifdef WLAN_FEATURE_RMC
235static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo);
236
237static int hdd_open_cesium_nl_sock(void);
238static void hdd_close_cesium_nl_sock(void);
239static struct sock *cesium_nl_srv_sock;
240static v_U16_t cesium_pid;
241
242static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
243 tANI_U8 *tx_fail_count,
244 tANI_U16 *pid);
245
246static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg);
247
248#endif /* WLAN_FEATURE_RMC */
Jeff Johnsone7245742012-09-05 17:12:55 -0700249void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800250void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700251
Jeff Johnson295189b2012-06-20 16:38:30 -0700252v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +0530253 struct sk_buff *skb
254#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
255 , void *accel_priv
256#endif
257#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
258 , select_queue_fallback_t fallback
259#endif
260);
Jeff Johnson295189b2012-06-20 16:38:30 -0700261
262#ifdef WLAN_FEATURE_PACKET_FILTERING
263static void hdd_set_multicast_list(struct net_device *dev);
264#endif
265
266void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
267
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800268#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800269void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
270static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700271static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
272 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
273 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +0530274static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
275 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800276#endif
Ratheesh S P21280412015-05-19 14:21:52 +0530277
278/* Store WLAN driver info in a global variable such that crash debugger
279 can extract it from driver debug symbol and crashdump for post processing */
280tANI_U8 g_wlan_driver[ ] = "pronto_driver";
281
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800282#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700283VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800284#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700285
Mihir Shetee1093ba2014-01-21 20:13:32 +0530286static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530287const char * hdd_device_modetoString(v_U8_t device_mode)
288{
289 switch(device_mode)
290 {
291 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
292 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
293 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
294 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
295 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
296 CASE_RETURN_STRING( WLAN_HDD_FTM );
297 CASE_RETURN_STRING( WLAN_HDD_IBSS );
298 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
299 default:
300 return "device_mode Unknown";
301 }
302}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530303
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530304static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700305 unsigned long state,
306 void *ndev)
307{
308 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700309 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700310 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700311#ifdef WLAN_BTAMP_FEATURE
312 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700313#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530314 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700315
316 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700317 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700318 (strncmp(dev->name, "p2p", 3)))
319 return NOTIFY_DONE;
320
Jeff Johnson295189b2012-06-20 16:38:30 -0700321 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700322 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700323
Jeff Johnson27cee452013-03-27 11:10:24 -0700324 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700325 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800326 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700327 VOS_ASSERT(0);
328 return NOTIFY_DONE;
329 }
330
Jeff Johnson27cee452013-03-27 11:10:24 -0700331 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
332 if (NULL == pHddCtx)
333 {
334 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
335 VOS_ASSERT(0);
336 return NOTIFY_DONE;
337 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800338 if (pHddCtx->isLogpInProgress)
339 return NOTIFY_DONE;
340
Jeff Johnson27cee452013-03-27 11:10:24 -0700341
342 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
343 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700344
345 switch (state) {
346 case NETDEV_REGISTER:
347 break;
348
349 case NETDEV_UNREGISTER:
350 break;
351
352 case NETDEV_UP:
353 break;
354
355 case NETDEV_DOWN:
356 break;
357
358 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700359 if(TRUE == pAdapter->isLinkUpSvcNeeded)
360 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700361 break;
362
363 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530364 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530365 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530366 {
367 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
368 "%s: Timeout occurred while waiting for abortscan %ld",
369 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700370 }
371 else
372 {
373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530374 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700375 }
376#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700377 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700378 status = WLANBAP_StopAmp();
379 if(VOS_STATUS_SUCCESS != status )
380 {
381 pHddCtx->isAmpAllowed = VOS_TRUE;
382 hddLog(VOS_TRACE_LEVEL_FATAL,
383 "%s: Failed to stop AMP", __func__);
384 }
385 else
386 {
387 //a state m/c implementation in PAL is TBD to avoid this delay
388 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700389 if ( pHddCtx->isAmpAllowed )
390 {
391 WLANBAP_DeregisterFromHCI();
392 pHddCtx->isAmpAllowed = VOS_FALSE;
393 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700394 }
395#endif //WLAN_BTAMP_FEATURE
396 break;
397
398 default:
399 break;
400 }
401
402 return NOTIFY_DONE;
403}
404
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530405static int hdd_netdev_notifier_call(struct notifier_block * nb,
406 unsigned long state,
407 void *ndev)
408{
409 int ret;
410 vos_ssr_protect(__func__);
411 ret = __hdd_netdev_notifier_call( nb, state, ndev);
412 vos_ssr_unprotect(__func__);
413 return ret;
414}
415
Jeff Johnson295189b2012-06-20 16:38:30 -0700416struct notifier_block hdd_netdev_notifier = {
417 .notifier_call = hdd_netdev_notifier_call,
418};
419
420/*---------------------------------------------------------------------------
421 * Function definitions
422 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700423void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
424void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700425//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700426static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700427#ifndef MODULE
428/* current con_mode - used only for statically linked driver
429 * con_mode is changed by userspace to indicate a mode change which will
430 * result in calling the module exit and init functions. The module
431 * exit function will clean up based on the value of con_mode prior to it
432 * being changed by userspace. So curr_con_mode records the current con_mode
433 * for exit when con_mode becomes the next mode for init
434 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700435static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700436#endif
437
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +0530438#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
439/**
440 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
441 * @hdd_ctx: hdd global context
442 *
443 * Return: none
444 */
445static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
446{
447 uint8_t i;
448
449 mutex_init(&hdd_ctx->op_ctx.op_lock);
450 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
451 {
452 hdd_ctx->op_ctx.op_table[i].request_id = 0;
453 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
454 }
455}
456#else
457static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
458{
459}
460#endif
461
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800462/**---------------------------------------------------------------------------
463
464 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
465
466 Called immediately after the cfg.ini is read in order to configure
467 the desired trace levels.
468
469 \param - moduleId - module whose trace level is being configured
470 \param - bitmask - bitmask of log levels to be enabled
471
472 \return - void
473
474 --------------------------------------------------------------------------*/
475static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
476{
477 wpt_tracelevel level;
478
479 /* if the bitmask is the default value, then a bitmask was not
480 specified in cfg.ini, so leave the logging level alone (it
481 will remain at the "compiled in" default value) */
482 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
483 {
484 return;
485 }
486
487 /* a mask was specified. start by disabling all logging */
488 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
489
490 /* now cycle through the bitmask until all "set" bits are serviced */
491 level = VOS_TRACE_LEVEL_FATAL;
492 while (0 != bitmask)
493 {
494 if (bitmask & 1)
495 {
496 vos_trace_setValue(moduleId, level, 1);
497 }
498 level++;
499 bitmask >>= 1;
500 }
501}
502
503
Jeff Johnson295189b2012-06-20 16:38:30 -0700504/**---------------------------------------------------------------------------
505
506 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
507
508 Called immediately after the cfg.ini is read in order to configure
509 the desired trace levels in the WDI.
510
511 \param - moduleId - module whose trace level is being configured
512 \param - bitmask - bitmask of log levels to be enabled
513
514 \return - void
515
516 --------------------------------------------------------------------------*/
517static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
518{
519 wpt_tracelevel level;
520
521 /* if the bitmask is the default value, then a bitmask was not
522 specified in cfg.ini, so leave the logging level alone (it
523 will remain at the "compiled in" default value) */
524 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
525 {
526 return;
527 }
528
529 /* a mask was specified. start by disabling all logging */
530 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
531
532 /* now cycle through the bitmask until all "set" bits are serviced */
533 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
534 while (0 != bitmask)
535 {
536 if (bitmask & 1)
537 {
538 wpalTraceSetLevel(moduleId, level, 1);
539 }
540 level++;
541 bitmask >>= 1;
542 }
543}
Jeff Johnson295189b2012-06-20 16:38:30 -0700544
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530545/*
546 * FUNCTION: wlan_hdd_validate_context
547 * This function is used to check the HDD context
548 */
549int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
550{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530551
552 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
553 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530555 "%s: HDD context is Null", __func__);
556 return -ENODEV;
557 }
558
559 if (pHddCtx->isLogpInProgress)
560 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530562 "%s: LOGP %s. Ignore!!", __func__,
563 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
564 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530565 return -EAGAIN;
566 }
567
Mihir Shete18156292014-03-11 15:38:30 +0530568 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530569 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530571 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
572 return -EAGAIN;
573 }
574 return 0;
575}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700576#ifdef CONFIG_ENABLE_LINUX_REG
577void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
578{
579 hdd_adapter_t *pAdapter = NULL;
580 hdd_station_ctx_t *pHddStaCtx = NULL;
581 eCsrPhyMode phyMode;
582 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530583
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700584 if (NULL == pHddCtx)
585 {
586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
587 "HDD Context is null !!");
588 return ;
589 }
590
591 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
592 if (NULL == pAdapter)
593 {
594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
595 "pAdapter is null !!");
596 return ;
597 }
598
599 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
600 if (NULL == pHddStaCtx)
601 {
602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
603 "pHddStaCtx is null !!");
604 return ;
605 }
606
607 cfg_param = pHddCtx->cfg_ini;
608 if (NULL == cfg_param)
609 {
610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
611 "cfg_params not available !!");
612 return ;
613 }
614
615 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
616
617 if (!pHddCtx->isVHT80Allowed)
618 {
619 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
620 (eCSR_DOT11_MODE_11ac == phyMode) ||
621 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
622 {
623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
624 "Setting phymode to 11n!!");
625 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
626 }
627 }
628 else
629 {
630 /*New country Supports 11ac as well resetting value back from .ini*/
631 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
632 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
633 return ;
634 }
635
636 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
637 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
638 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
639 {
640 VOS_STATUS vosStatus;
641
642 // need to issue a disconnect to CSR.
643 INIT_COMPLETION(pAdapter->disconnect_comp_var);
644 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
645 pAdapter->sessionId,
646 eCSR_DISCONNECT_REASON_UNSPECIFIED );
647
648 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530649 {
650 long ret;
651
652 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700653 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530654 if (0 >= ret)
655 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
656 ret);
657 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700658
659 }
660}
661#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530662void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
663{
664 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
665 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
666 hdd_config_t *cfg_param;
667 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530668 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530669
670 if (NULL == pHddCtx)
671 {
672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
673 "HDD Context is null !!");
674 return ;
675 }
676
677 cfg_param = pHddCtx->cfg_ini;
678
679 if (NULL == cfg_param)
680 {
681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
682 "cfg_params not available !!");
683 return ;
684 }
685
686 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
687
688 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
689 {
690 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
691 (eCSR_DOT11_MODE_11ac == phyMode) ||
692 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
693 {
694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
695 "Setting phymode to 11n!!");
696 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
697 }
698 }
699 else
700 {
701 /*New country Supports 11ac as well resetting value back from .ini*/
702 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
703 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
704 return ;
705 }
706
707 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
708 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
709 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
710 {
711 VOS_STATUS vosStatus;
712
713 // need to issue a disconnect to CSR.
714 INIT_COMPLETION(pAdapter->disconnect_comp_var);
715 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
716 pAdapter->sessionId,
717 eCSR_DISCONNECT_REASON_UNSPECIFIED );
718
719 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530720 {
721 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530722 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530723 if (ret <= 0)
724 {
725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
726 "wait on disconnect_comp_var is failed %ld", ret);
727 }
728 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530729
730 }
731}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700732#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530733
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700734void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
735{
736 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
737 hdd_config_t *cfg_param;
738
739 if (NULL == pHddCtx)
740 {
741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
742 "HDD Context is null !!");
743 return ;
744 }
745
746 cfg_param = pHddCtx->cfg_ini;
747
748 if (NULL == cfg_param)
749 {
750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
751 "cfg_params not available !!");
752 return ;
753 }
754
Agarwal Ashish738843c2014-09-25 12:27:56 +0530755 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
756 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700757 {
758 /*New country doesn't support DFS */
759 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
760 }
761 else
762 {
763 /*New country Supports DFS as well resetting value back from .ini*/
764 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
765 }
766
767}
768
Abhishek Singh00b71972016-01-07 10:51:04 +0530769#ifdef WLAN_FEATURE_RMC
770static int hdd_parse_setrmcenable_command(tANI_U8 *pValue, tANI_U8 *pRmcEnable)
771{
772 tANI_U8 *inPtr = pValue;
773 int tempInt;
774 int v = 0;
775 char buf[32];
776 *pRmcEnable = 0;
777
778 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
779 /*no argument after the command*/
780 if (NULL == inPtr)
781 {
782 return 0;
783 }
784
785 /*no space after the command*/
786 else if (SPACE_ASCII_VALUE != *inPtr)
787 {
788 return 0;
789 }
790
791 /*removing empty spaces*/
792 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
793
794 /*no argument followed by spaces*/
795 if ('\0' == *inPtr)
796 {
797 return 0;
798 }
799
800 /* getting the first argument which enables or disables RMC
801 * for input IP v4 address*/
802 sscanf(inPtr, "%32s ", buf);
803 v = kstrtos32(buf, 10, &tempInt);
804 if ( v < 0)
805 {
806 return -EINVAL;
807 }
808
809 *pRmcEnable = tempInt;
810
811 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
812 "ucRmcEnable: %d", *pRmcEnable);
813
814 return 0;
815}
816
817/* Function header left blank Intentionally */
818static int hdd_parse_setrmcactionperiod_command(tANI_U8 *pValue,
819 tANI_U32 *pActionPeriod)
820{
821 tANI_U8 *inPtr = pValue;
822 int tempInt;
823 int v = 0;
824 char buf[32];
825 *pActionPeriod = 0;
826
827 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
828 /*no argument after the command*/
829 if (NULL == inPtr)
830 {
831 return -EINVAL;
832 }
833
834 /*no space after the command*/
835 else if (SPACE_ASCII_VALUE != *inPtr)
836 {
837 return -EINVAL;
838 }
839
840 /*removing empty spaces*/
841 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
842
843 /*no argument followed by spaces*/
844 if ('\0' == *inPtr)
845 {
846 return 0;
847 }
848
849 /* getting the first argument which enables or disables RMC
850 * for input IP v4 address*/
851 sscanf(inPtr, "%32s ", buf);
852 v = kstrtos32(buf, 10, &tempInt);
853 if ( v < 0)
854 {
855 return -EINVAL;
856 }
857
858 /* Range checking for passed paramter */
859 if (tempInt < WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN ||
860 tempInt > WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX)
861 {
862 return -EINVAL;
863 }
864
865 *pActionPeriod = tempInt;
866
867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
868 "uActionPeriod: %d", *pActionPeriod);
869
870 return 0;
871}
872
873/* Function header left blank Intentionally */
874static int hdd_parse_setrmcrate_command(tANI_U8 *pValue,
875 tANI_U32 *pRate, tTxrateinfoflags *pTxFlags)
876{
877 tANI_U8 *inPtr = pValue;
878 int tempInt;
879 int v = 0;
880 char buf[32];
881 *pRate = 0;
882 *pTxFlags = 0;
883
884 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
885 /*no argument after the command*/
886 if (NULL == inPtr)
887 {
888 return -EINVAL;
889 }
890
891 /*no space after the command*/
892 else if (SPACE_ASCII_VALUE != *inPtr)
893 {
894 return -EINVAL;
895 }
896
897 /*removing empty spaces*/
898 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
899
900 /*no argument followed by spaces*/
901 if ('\0' == *inPtr)
902 {
903 return 0;
904 }
905
906 /*
907 * getting the first argument which sets multicast rate.
908 */
909 sscanf(inPtr, "%32s ", buf);
910 v = kstrtos32(buf, 10, &tempInt);
911 if ( v < 0)
912 {
913 return -EINVAL;
914 }
915
916 /*
917 * Validate the multicast rate.
918 */
919 switch (tempInt)
920 {
921 default:
922 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
923 "Unsupported rate: %d", tempInt);
924 return -EINVAL;
925 case 0:
926 case 6:
927 case 9:
928 case 12:
929 case 18:
930 case 24:
931 case 36:
932 case 48:
933 case 54:
934 *pTxFlags = eHAL_TX_RATE_LEGACY;
935 *pRate = tempInt * 10;
936 break;
937 case 65:
938 *pTxFlags = eHAL_TX_RATE_HT20;
939 *pRate = tempInt * 10;
940 break;
941 case 72:
942 *pTxFlags = eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;
943 *pRate = 722; /* fractional rate 72.2 Mbps */
944 break;
945 }
946
947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
948 "Rate: %d", *pRate);
949
950 return 0;
951}
952
953/**---------------------------------------------------------------------------
954
955 \brief hdd_cfg80211_get_ibss_peer_info_cb() - Callback function for IBSS
956 Peer Info request
957
958 This is an asynchronous callback function from SME when the peer info
959 is received
960
961 \pUserData -> Adapter private data
962 \pPeerInfoRsp -> Peer info response
963
964 \return - 0 for success non-zero for failure
965 --------------------------------------------------------------------------*/
966static void
967hdd_cfg80211_get_ibss_peer_info_cb(v_VOID_t *pUserData, v_VOID_t *pPeerInfoRsp)
968{
969 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pUserData;
970 tSirPeerInfoRspParams *pPeerInfo = (tSirPeerInfoRspParams *)pPeerInfoRsp;
971 hdd_station_ctx_t *pStaCtx;
972 v_U8_t i;
973
974 /*Sanity check*/
975 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
976 {
977 hddLog(LOGE,
978 FL("invalid adapter or adapter has invalid magic"));
979 return;
980 }
981
982 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
983 if (NULL != pStaCtx && NULL != pPeerInfo &&
984 eHAL_STATUS_SUCCESS == pPeerInfo->status)
985 {
986 pStaCtx->ibss_peer_info.status = pPeerInfo->status;
987 pStaCtx->ibss_peer_info.numIBSSPeers = pPeerInfo->numPeers;
988
989 /* Paranoia check */
990 if (pPeerInfo->numPeers < HDD_MAX_NUM_IBSS_STA)
991 {
992 for (i = 0; i < pPeerInfo->numPeers; i++)
993 {
994 memcpy(&pStaCtx->ibss_peer_info.ibssPeerList[i],
995 &pPeerInfo->peerInfoParams[i],
996 sizeof(hdd_ibss_peer_info_params_t));
997 }
998 hddLog(LOG1,
999 FL("Peer Info copied in HDD"));
1000 }
1001 else
1002 {
1003 hddLog(LOGE,
1004 FL(" Number of peers %d returned is more than limit %d"),
1005 pPeerInfo->numPeers, HDD_MAX_NUM_IBSS_STA);
1006 }
1007 }
1008 else
1009 {
1010 hddLog(LOG1,
1011 FL("peerInfo returned is NULL"));
1012 }
1013
1014 complete(&pAdapter->ibss_peer_info_comp);
1015}
1016
1017/**---------------------------------------------------------------------------
1018
1019 \brief hdd_cfg80211_get_ibss_peer_info_all() -
1020
1021 Request function to get IBSS peer info from lower layers
1022
1023 \pAdapter -> Adapter context
1024
1025 \return - 0 for success non-zero for failure
1026 --------------------------------------------------------------------------*/
1027static
1028VOS_STATUS hdd_cfg80211_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
1029{
1030 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1031 long status;
1032 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1033
1034 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1035
1036 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1037 hdd_cfg80211_get_ibss_peer_info_cb,
1038 VOS_TRUE, 0xFF);
1039
1040 if (VOS_STATUS_SUCCESS == retStatus)
1041 {
1042 status = wait_for_completion_interruptible_timeout
1043 (&pAdapter->ibss_peer_info_comp,
1044 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1045
1046 /* status will be 0 if timed out */
1047 if (status <= 0)
1048 {
1049 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1050 __func__, status);
1051 retStatus = VOS_STATUS_E_FAILURE;
1052 return retStatus;
1053 }
1054 }
1055 else
1056 {
1057 hddLog(VOS_TRACE_LEVEL_WARN,
1058 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1059 }
1060
1061 return retStatus;
1062}
1063
1064/**---------------------------------------------------------------------------
1065
1066 \brief hdd_cfg80211_get_ibss_peer_info() -
1067
1068 Request function to get IBSS peer info from lower layers
1069
1070 \pAdapter -> Adapter context
1071 \staIdx -> Sta index for which the peer info is requested
1072
1073 \return - 0 for success non-zero for failure
1074 --------------------------------------------------------------------------*/
1075static VOS_STATUS
1076hdd_cfg80211_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx)
1077{
1078 long status;
1079 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1080 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1081
1082 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1083
1084 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1085 hdd_cfg80211_get_ibss_peer_info_cb,
1086 VOS_FALSE, staIdx);
1087
1088 if (VOS_STATUS_SUCCESS == retStatus)
1089 {
1090 status = wait_for_completion_interruptible_timeout
1091 (&pAdapter->ibss_peer_info_comp,
1092 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1093
1094 /* status = 0 on timeout */
1095 if (status <= 0)
1096 {
1097 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1098 __func__, status);
1099 retStatus = VOS_STATUS_E_FAILURE;
1100 return retStatus;
1101 }
1102 }
1103 else
1104 {
1105 hddLog(VOS_TRACE_LEVEL_WARN,
1106 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1107 }
1108
1109 return retStatus;
1110}
1111
1112/* Function header left blank Intentionally */
1113VOS_STATUS
1114hdd_parse_get_ibss_peer_info(tANI_U8 *pValue, v_MACADDR_t *pPeerMacAddr)
1115{
1116 tANI_U8 *inPtr = pValue;
1117 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1118
1119 /*no argument after the command*/
1120 if (NULL == inPtr)
1121 {
1122 return VOS_STATUS_E_FAILURE;;
1123 }
1124
1125 /*no space after the command*/
1126 else if (SPACE_ASCII_VALUE != *inPtr)
1127 {
1128 return VOS_STATUS_E_FAILURE;;
1129 }
1130
1131 /*removing empty spaces*/
1132 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
1133
1134 /*no argument followed by spaces*/
1135 if ('\0' == *inPtr)
1136 {
1137 return VOS_STATUS_E_FAILURE;;
1138 }
1139
1140 /*getting the first argument ie the peer mac address */
1141 if (inPtr[2] != ':' || inPtr[5] != ':' || inPtr[8] != ':' ||
1142 inPtr[11] != ':' || inPtr[14] != ':')
1143 {
1144 return VOS_STATUS_E_FAILURE;;
1145 }
1146 sscanf(inPtr, "%2x:%2x:%2x:%2x:%2x:%2x",
1147 (unsigned int *)&pPeerMacAddr->bytes[0],
1148 (unsigned int *)&pPeerMacAddr->bytes[1],
1149 (unsigned int *)&pPeerMacAddr->bytes[2],
1150 (unsigned int *)&pPeerMacAddr->bytes[3],
1151 (unsigned int *)&pPeerMacAddr->bytes[4],
1152 (unsigned int *)&pPeerMacAddr->bytes[5]);
1153
1154 /* The command buffer seems to be fine */
1155 return VOS_STATUS_SUCCESS;
1156}
1157
1158/* Function header left blank Intentionally */
1159static int hdd_parse_set_ibss_oui_data_command(tANI_U8 *command, tANI_U8 *ie,
1160 tANI_U32 limit)
1161{
1162 tANI_U8 len;
1163 tANI_U8 data;
1164
1165 /* skip white space */
1166 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1167 {
1168 command++;
1169 limit--;
1170 }
1171
1172 /* skip element id and element length */
1173 len = 2;
1174
1175 /* extract oui */
1176 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1177 (limit > 1))
1178 {
1179 /* Convert ASCII to decimal */
1180 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1181 ie[len++] = data;
1182 command += 2;
1183 limit -= 2;
1184 }
1185
1186 /* skip white space */
1187 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1188 {
1189 command++;
1190 limit--;
1191 }
1192
1193 /* extract data */
1194 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1195 (limit > 1))
1196 {
1197 /* Convert ASCII to decimal */
1198 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1199 ie[len++] = data;
1200 command += 2;
1201 limit -= 2;
1202 }
1203
1204 /* fill element id and element length */
1205 ie[0] = IE_EID_VENDOR;
1206 ie[1] = len - 2;
1207
1208 return len;
1209}
1210
1211static tANI_U32 hdd_find_ibss_wpa_ie_pos(tANI_U8 *addIePtr, tANI_U32 addIeLen)
1212{
1213 tANI_U32 ieLenPresent = 0;
1214 int left = addIeLen;
1215 v_U8_t *ptr = addIePtr;
1216 v_U8_t elem_id,elem_len;
1217
1218 while(left >= 2)
1219 {
1220 elem_id = ptr[0];
1221 elem_len = ptr[1];
1222 left -= 2;
1223 if(elem_len > left)
1224 {
1225 hddLog(LOGE,
1226 FL("****Invalid elem_len=%d left=%d*****"),
1227 elem_len,left);
1228 return 0;
1229 }
1230 if ((elem_id == IE_EID_VENDOR) &&
1231 (left >= WPA_OUI_TYPE_SIZE))
1232 {
1233 if (!memcmp(&ptr[2], WPA_OUI_TYPE,
1234 WPA_OUI_TYPE_SIZE))
1235 {
1236 ieLenPresent += elem_len + 2;
1237 return ieLenPresent;
1238 }
1239 }
1240 ieLenPresent += (elem_len + 2);
1241 left -= elem_len;
1242 ptr += (elem_len + 2);
1243 }
1244 return 0;
1245}
1246
1247#endif /* WLAN_FEATURE_RMC */
1248
Rajeev79dbe4c2013-10-05 11:03:42 +05301249#ifdef FEATURE_WLAN_BATCH_SCAN
1250
1251/**---------------------------------------------------------------------------
1252
1253 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
1254 input string
1255
1256 This function extracts assigned integer from string in below format:
1257 "STRING=10" : extracts integer 10 from this string
1258
1259 \param - pInPtr Pointer to input string
1260 \param - base Base for string to int conversion(10 for decimal 16 for hex)
1261 \param - pOutPtr Pointer to variable in which extracted integer needs to be
1262 assigned
1263 \param - pLastArg to tell whether it is last arguement in input string or
1264 not
1265
1266 \return - NULL for failure cases
1267 pointer to next arguement in input string for success cases
1268 --------------------------------------------------------------------------*/
1269static tANI_U8 *
1270hdd_extract_assigned_int_from_str
1271(
1272 tANI_U8 *pInPtr,
1273 tANI_U8 base,
1274 tANI_U32 *pOutPtr,
1275 tANI_U8 *pLastArg
1276)
1277{
1278 int tempInt;
1279 int v = 0;
1280 char buf[32];
1281 int val = 0;
1282 *pLastArg = FALSE;
1283
1284 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1285 if (NULL == pInPtr)
1286 {
1287 return NULL;
1288 }
1289
1290 pInPtr++;
1291
1292 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1293
1294 val = sscanf(pInPtr, "%32s ", buf);
1295 if (val < 0 && val > strlen(pInPtr))
1296 {
1297 return NULL;
1298 }
1299 pInPtr += val;
1300 v = kstrtos32(buf, base, &tempInt);
1301 if (v < 0)
1302 {
1303 return NULL;
1304 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -08001305 if (tempInt < 0)
1306 {
1307 tempInt = 0;
1308 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301309 *pOutPtr = tempInt;
1310
1311 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1312 if (NULL == pInPtr)
1313 {
1314 *pLastArg = TRUE;
1315 return NULL;
1316 }
1317 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1318
1319 return pInPtr;
1320}
1321
1322/**---------------------------------------------------------------------------
1323
1324 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
1325 input string
1326
1327 This function extracts assigned character from string in below format:
1328 "STRING=A" : extracts char 'A' from this string
1329
1330 \param - pInPtr Pointer to input string
1331 \param - pOutPtr Pointer to variable in which extracted char needs to be
1332 assigned
1333 \param - pLastArg to tell whether it is last arguement in input string or
1334 not
1335
1336 \return - NULL for failure cases
1337 pointer to next arguement in input string for success cases
1338 --------------------------------------------------------------------------*/
1339static tANI_U8 *
1340hdd_extract_assigned_char_from_str
1341(
1342 tANI_U8 *pInPtr,
1343 tANI_U8 *pOutPtr,
1344 tANI_U8 *pLastArg
1345)
1346{
1347 *pLastArg = FALSE;
1348
1349 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1350 if (NULL == pInPtr)
1351 {
1352 return NULL;
1353 }
1354
1355 pInPtr++;
1356
1357 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1358
1359 *pOutPtr = *pInPtr;
1360
1361 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1362 if (NULL == pInPtr)
1363 {
1364 *pLastArg = TRUE;
1365 return NULL;
1366 }
1367 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1368
1369 return pInPtr;
1370}
1371
1372
1373/**---------------------------------------------------------------------------
1374
1375 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
1376
1377 This function parses set batch scan command in below format:
1378 WLS_BATCHING_SET <space> followed by below arguements
1379 "SCANFREQ=XX" : Optional defaults to 30 sec
1380 "MSCAN=XX" : Required number of scans to attempt to batch
1381 "BESTN=XX" : Best Network (RSSI) defaults to 16
1382 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
1383 A. implies only 5 GHz , B. implies only 2.4GHz
1384 "RTT=X" : optional defaults to 0
1385 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
1386 error
1387
1388 For example input commands:
1389 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
1390 translated into set batch scan with following parameters:
1391 a) Frequence 60 seconds
1392 b) Batch 10 scans together
1393 c) Best RSSI to be 20
1394 d) 5GHz band only
1395 e) RTT is equal to 0
1396
1397 \param - pValue Pointer to input channel list
1398 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
1399
1400 \return - 0 for success non-zero for failure
1401
1402 --------------------------------------------------------------------------*/
1403static int
1404hdd_parse_set_batchscan_command
1405(
1406 tANI_U8 *pValue,
1407 tSirSetBatchScanReq *pHddSetBatchScanReq
1408)
1409{
1410 tANI_U8 *inPtr = pValue;
1411 tANI_U8 val = 0;
1412 tANI_U8 lastArg = 0;
Abhishek Singh00b71972016-01-07 10:51:04 +05301413 tANI_U32 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001414 tANI_U32 nMscan;
Abhishek Singh00b71972016-01-07 10:51:04 +05301415 tANI_U32 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
1416 tANI_U8 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1417 tANI_U32 nRtt = 0;
Rajeev Kumarc933d982013-11-18 20:04:20 -08001418 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +05301419
Rajeev79dbe4c2013-10-05 11:03:42 +05301420 /*go to space after WLS_BATCHING_SET command*/
1421 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1422 /*no argument after the command*/
1423 if (NULL == inPtr)
1424 {
1425 return -EINVAL;
1426 }
1427
1428 /*no space after the command*/
1429 else if (SPACE_ASCII_VALUE != *inPtr)
1430 {
1431 return -EINVAL;
1432 }
1433
1434 /*removing empty spaces*/
1435 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
1436
1437 /*no argument followed by spaces*/
1438 if ('\0' == *inPtr)
1439 {
1440 return -EINVAL;
1441 }
1442
1443 /*check and parse SCANFREQ*/
1444 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
1445 {
1446 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001447 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001448
Rajeev Kumarc933d982013-11-18 20:04:20 -08001449 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001450 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001451 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001452 }
1453
Rajeev79dbe4c2013-10-05 11:03:42 +05301454 if ( (NULL == inPtr) || (TRUE == lastArg))
1455 {
1456 return -EINVAL;
1457 }
1458 }
1459
1460 /*check and parse MSCAN*/
1461 if ((strncmp(inPtr, "MSCAN", 5) == 0))
1462 {
1463 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001464 &nMscan, &lastArg);
1465
1466 if (0 == nMscan)
1467 {
1468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1469 "invalid MSCAN=%d", nMscan);
1470 return -EINVAL;
1471 }
1472
Rajeev79dbe4c2013-10-05 11:03:42 +05301473 if (TRUE == lastArg)
1474 {
1475 goto done;
1476 }
1477 else if (NULL == inPtr)
1478 {
1479 return -EINVAL;
1480 }
1481 }
1482 else
1483 {
1484 return -EINVAL;
1485 }
1486
1487 /*check and parse BESTN*/
1488 if ((strncmp(inPtr, "BESTN", 5) == 0))
1489 {
1490 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001491 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001492
Rajeev Kumarc933d982013-11-18 20:04:20 -08001493 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001494 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001495 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001496 }
1497
Rajeev79dbe4c2013-10-05 11:03:42 +05301498 if (TRUE == lastArg)
1499 {
1500 goto done;
1501 }
1502 else if (NULL == inPtr)
1503 {
1504 return -EINVAL;
1505 }
1506 }
1507
1508 /*check and parse CHANNEL*/
1509 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
1510 {
1511 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -08001512
Rajeev79dbe4c2013-10-05 11:03:42 +05301513 if (('A' == val) || ('a' == val))
1514 {
c_hpothuebf89732014-02-25 13:00:24 +05301515 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301516 }
1517 else if (('B' == val) || ('b' == val))
1518 {
c_hpothuebf89732014-02-25 13:00:24 +05301519 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301520 }
1521 else
1522 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001523 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1524 }
1525
1526 if (TRUE == lastArg)
1527 {
1528 goto done;
1529 }
1530 else if (NULL == inPtr)
1531 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301532 return -EINVAL;
1533 }
1534 }
1535
1536 /*check and parse RTT*/
1537 if ((strncmp(inPtr, "RTT", 3) == 0))
1538 {
1539 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001540 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +05301541 if (TRUE == lastArg)
1542 {
1543 goto done;
1544 }
1545 if (NULL == inPtr)
1546 {
1547 return -EINVAL;
1548 }
1549 }
1550
1551
1552done:
1553
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001554 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1555 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1556 pHddSetBatchScanReq->bestNetwork = nBestN;
1557 pHddSetBatchScanReq->rfBand = ucRfBand;
1558 pHddSetBatchScanReq->rtt = nRtt;
1559
Rajeev79dbe4c2013-10-05 11:03:42 +05301560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1561 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1562 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1563 pHddSetBatchScanReq->scanFrequency,
1564 pHddSetBatchScanReq->numberOfScansToBatch,
1565 pHddSetBatchScanReq->bestNetwork,
1566 pHddSetBatchScanReq->rfBand,
1567 pHddSetBatchScanReq->rtt);
1568
1569 return 0;
1570}/*End of hdd_parse_set_batchscan_command*/
1571
1572/**---------------------------------------------------------------------------
1573
1574 \brief hdd_set_batch_scan_req_callback () - This function is called after
1575 receiving set batch scan response from FW and it saves set batch scan
1576 response data FW to HDD context and sets the completion event on
1577 which hdd_ioctl is waiting
1578
1579 \param - callbackContext Pointer to HDD adapter
1580 \param - pRsp Pointer to set batch scan response data received from FW
1581
1582 \return - nothing
1583
1584 --------------------------------------------------------------------------*/
1585static void hdd_set_batch_scan_req_callback
1586(
1587 void *callbackContext,
1588 tSirSetBatchScanRsp *pRsp
1589)
1590{
1591 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1592 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1593
1594 /*sanity check*/
1595 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1596 {
1597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1598 "%s: Invalid pAdapter magic", __func__);
1599 VOS_ASSERT(0);
1600 return;
1601 }
1602 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1603
1604 /*save set batch scan response*/
1605 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1606
1607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1608 "Received set batch scan rsp from FW with nScansToBatch=%d",
1609 pHddSetBatchScanRsp->nScansToBatch);
1610
1611 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1612 complete(&pAdapter->hdd_set_batch_scan_req_var);
1613
1614 return;
1615}/*End of hdd_set_batch_scan_req_callback*/
1616
1617
1618/**---------------------------------------------------------------------------
1619
1620 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1621 info in hdd batch scan response queue
1622
1623 \param - pAdapter Pointer to hdd adapter
1624 \param - pAPMetaInfo Pointer to access point meta info
1625 \param - scanId scan ID of batch scan response
1626 \param - isLastAp tells whether AP is last AP in batch scan response or not
1627
1628 \return - nothing
1629
1630 --------------------------------------------------------------------------*/
1631static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1632 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1633{
1634 tHddBatchScanRsp *pHead;
1635 tHddBatchScanRsp *pNode;
1636 tHddBatchScanRsp *pPrev;
1637 tHddBatchScanRsp *pTemp;
1638 tANI_U8 ssidLen;
1639
1640 /*head of hdd batch scan response queue*/
1641 pHead = pAdapter->pBatchScanRsp;
1642
1643 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1644 if (NULL == pNode)
1645 {
1646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1647 "%s: Could not allocate memory", __func__);
1648 VOS_ASSERT(0);
1649 return;
1650 }
1651
1652 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1653 sizeof(pNode->ApInfo.bssid));
1654 ssidLen = strlen(pApMetaInfo->ssid);
1655 if (SIR_MAX_SSID_SIZE < ssidLen)
1656 {
1657 /*invalid scan result*/
1658 vos_mem_free(pNode);
1659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1660 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1661 return;
1662 }
1663 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1664 /*null terminate ssid*/
1665 pNode->ApInfo.ssid[ssidLen] = '\0';
1666 pNode->ApInfo.ch = pApMetaInfo->ch;
1667 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1668 pNode->ApInfo.age = pApMetaInfo->timestamp;
1669 pNode->ApInfo.batchId = scanId;
1670 pNode->ApInfo.isLastAp = isLastAp;
1671
1672 pNode->pNext = NULL;
1673 if (NULL == pHead)
1674 {
1675 pAdapter->pBatchScanRsp = pNode;
1676 }
1677 else
1678 {
1679 pTemp = pHead;
1680 while (NULL != pTemp)
1681 {
1682 pPrev = pTemp;
1683 pTemp = pTemp->pNext;
1684 }
1685 pPrev->pNext = pNode;
1686 }
1687
1688 return;
1689}/*End of hdd_populate_batch_scan_rsp_queue*/
1690
1691/**---------------------------------------------------------------------------
1692
1693 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1694 receiving batch scan response indication from FW. It saves get batch scan
1695 response data in HDD batch scan response queue. This callback sets the
1696 completion event on which hdd_ioctl is waiting only after getting complete
1697 batch scan response data from FW
1698
1699 \param - callbackContext Pointer to HDD adapter
1700 \param - pRsp Pointer to get batch scan response data received from FW
1701
1702 \return - nothing
1703
1704 --------------------------------------------------------------------------*/
1705static void hdd_batch_scan_result_ind_callback
1706(
1707 void *callbackContext,
1708 void *pRsp
1709)
1710{
1711 v_BOOL_t isLastAp;
1712 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001713 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301714 tANI_U32 numberScanList;
1715 tANI_U32 nextScanListOffset;
1716 tANI_U32 nextApMetaInfoOffset;
1717 hdd_adapter_t* pAdapter;
1718 tpSirBatchScanList pScanList;
1719 tpSirBatchScanNetworkInfo pApMetaInfo;
1720 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1721 tSirSetBatchScanReq *pReq;
1722
1723 pAdapter = (hdd_adapter_t *)callbackContext;
1724 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001725 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301726 {
1727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1728 "%s: Invalid pAdapter magic", __func__);
1729 VOS_ASSERT(0);
1730 return;
1731 }
1732
1733 /*initialize locals*/
1734 pReq = &pAdapter->hddSetBatchScanReq;
1735 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1736 isLastAp = FALSE;
1737 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001738 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301739 numberScanList = 0;
1740 nextScanListOffset = 0;
1741 nextApMetaInfoOffset = 0;
1742 pScanList = NULL;
1743 pApMetaInfo = NULL;
1744
1745 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1746 {
1747 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1748 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1749 isLastAp = TRUE;
1750 goto done;
1751 }
1752
1753 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1755 "Batch scan rsp: numberScalList %d", numberScanList);
1756
1757 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1758 {
1759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1760 "%s: numberScanList %d", __func__, numberScanList);
1761 isLastAp = TRUE;
1762 goto done;
1763 }
1764
1765 while (numberScanList)
1766 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001767 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301768 nextScanListOffset);
1769 if (NULL == pScanList)
1770 {
1771 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1772 "%s: pScanList is %p", __func__, pScanList);
1773 isLastAp = TRUE;
1774 goto done;
1775 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001776 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001778 "Batch scan rsp: numApMetaInfo %d scanId %d",
1779 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301780
1781 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1782 {
1783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1784 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1785 isLastAp = TRUE;
1786 goto done;
1787 }
1788
Rajeev Kumarce651e42013-10-21 18:57:15 -07001789 /*Initialize next AP meta info offset for next scan list*/
1790 nextApMetaInfoOffset = 0;
1791
Rajeev79dbe4c2013-10-05 11:03:42 +05301792 while (numApMetaInfo)
1793 {
1794 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1795 nextApMetaInfoOffset);
1796 if (NULL == pApMetaInfo)
1797 {
1798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1799 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1800 isLastAp = TRUE;
1801 goto done;
1802 }
1803 /*calculate AP age*/
1804 pApMetaInfo->timestamp =
1805 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1806
1807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001808 "%s: bssId "MAC_ADDRESS_STR
1809 " ch %d rssi %d timestamp %d", __func__,
1810 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1811 pApMetaInfo->ch, pApMetaInfo->rssi,
1812 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301813
1814 /*mark last AP in batch scan response*/
1815 if ((TRUE == pBatchScanRsp->isLastResult) &&
1816 (1 == numberScanList) && (1 == numApMetaInfo))
1817 {
1818 isLastAp = TRUE;
1819 }
1820
1821 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1822 /*store batch scan repsonse in hdd queue*/
1823 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1824 pScanList->scanId, isLastAp);
1825 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1826
1827 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1828 numApMetaInfo--;
1829 }
1830
Rajeev Kumarce651e42013-10-21 18:57:15 -07001831 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1832 + (sizeof(tSirBatchScanNetworkInfo)
1833 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301834 numberScanList--;
1835 }
1836
1837done:
1838
1839 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1840 requested from hdd_ioctl*/
1841 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1842 (TRUE == isLastAp))
1843 {
1844 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1845 complete(&pAdapter->hdd_get_batch_scan_req_var);
1846 }
1847
1848 return;
1849}/*End of hdd_batch_scan_result_ind_callback*/
1850
1851/**---------------------------------------------------------------------------
1852
1853 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1854 response as per batch scan FR request format by putting proper markers
1855
1856 \param - pDest pointer to destination buffer
1857 \param - cur_len current length
1858 \param - tot_len total remaining size which can be written to user space
1859 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1860 \param - pAdapter Pointer to HDD adapter
1861
1862 \return - ret no of characters written
1863
1864 --------------------------------------------------------------------------*/
1865static tANI_U32
1866hdd_format_batch_scan_rsp
1867(
1868 tANI_U8 *pDest,
1869 tANI_U32 cur_len,
1870 tANI_U32 tot_len,
1871 tHddBatchScanRsp *pApMetaInfo,
1872 hdd_adapter_t* pAdapter
1873)
1874{
1875 tANI_U32 ret = 0;
1876 tANI_U32 rem_len = 0;
1877 tANI_U8 temp_len = 0;
1878 tANI_U8 temp_total_len = 0;
1879 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1880 tANI_U8 *pTemp = temp;
1881
1882 /*Batch scan reponse needs to be returned to user space in
1883 following format:
1884 "scancount=X\n" where X is the number of scans in current batch
1885 batch
1886 "trunc\n" optional present if current scan truncated
1887 "bssid=XX:XX:XX:XX:XX:XX\n"
1888 "ssid=XXXX\n"
1889 "freq=X\n" frequency in Mhz
1890 "level=XX\n"
1891 "age=X\n" ms
1892 "dist=X\n" cm (-1 if not available)
1893 "errror=X\n" (-1if not available)
1894 "====\n" (end of ap marker)
1895 "####\n" (end of scan marker)
1896 "----\n" (end of results)*/
1897 /*send scan result in above format to user space based on
1898 available length*/
1899 /*The GET response may have more data than the driver can return in its
1900 buffer. In that case the buffer should be filled to the nearest complete
1901 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1902 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1903 The final buffer should end with "----\n"*/
1904
1905 /*sanity*/
1906 if (cur_len > tot_len)
1907 {
1908 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1909 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1910 return 0;
1911 }
1912 else
1913 {
1914 rem_len = (tot_len - cur_len);
1915 }
1916
1917 /*end scan marker*/
1918 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1919 {
1920 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1921 pTemp += temp_len;
1922 temp_total_len += temp_len;
1923 }
1924
1925 /*bssid*/
1926 temp_len = snprintf(pTemp, sizeof(temp),
1927 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1928 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1929 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1930 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1931 pTemp += temp_len;
1932 temp_total_len += temp_len;
1933
1934 /*ssid*/
1935 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1936 pApMetaInfo->ApInfo.ssid);
1937 pTemp += temp_len;
1938 temp_total_len += temp_len;
1939
1940 /*freq*/
1941 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001942 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301943 pTemp += temp_len;
1944 temp_total_len += temp_len;
1945
1946 /*level*/
1947 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1948 pApMetaInfo->ApInfo.rssi);
1949 pTemp += temp_len;
1950 temp_total_len += temp_len;
1951
1952 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001953 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301954 pApMetaInfo->ApInfo.age);
1955 pTemp += temp_len;
1956 temp_total_len += temp_len;
1957
1958 /*dist*/
1959 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1960 pTemp += temp_len;
1961 temp_total_len += temp_len;
1962
1963 /*error*/
1964 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1965 pTemp += temp_len;
1966 temp_total_len += temp_len;
1967
1968 /*end AP marker*/
1969 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1970 pTemp += temp_len;
1971 temp_total_len += temp_len;
1972
1973 /*last AP in batch scan response*/
1974 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1975 {
1976 /*end scan marker*/
1977 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1978 pTemp += temp_len;
1979 temp_total_len += temp_len;
1980
1981 /*end batch scan result marker*/
1982 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1983 pTemp += temp_len;
1984 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001985
Rajeev79dbe4c2013-10-05 11:03:42 +05301986 }
1987
1988 if (temp_total_len < rem_len)
1989 {
1990 ret = temp_total_len + 1;
1991 strlcpy(pDest, temp, ret);
1992 pAdapter->isTruncated = FALSE;
1993 }
1994 else
1995 {
1996 pAdapter->isTruncated = TRUE;
1997 if (rem_len >= strlen("%%%%"))
1998 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001999 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05302000 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08002001 else
Rajeev79dbe4c2013-10-05 11:03:42 +05302002 {
2003 ret = 0;
2004 }
2005 }
2006
2007 return ret;
2008
2009}/*End of hdd_format_batch_scan_rsp*/
2010
2011/**---------------------------------------------------------------------------
2012
2013 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
2014 buffer starting with head of hdd batch scan response queue
2015
2016 \param - pAdapter Pointer to HDD adapter
2017 \param - pDest Pointer to user data buffer
2018 \param - cur_len current offset in user buffer
2019 \param - rem_len remaining no of bytes in user buffer
2020
2021 \return - number of bytes written in user buffer
2022
2023 --------------------------------------------------------------------------*/
2024
2025tANI_U32 hdd_populate_user_batch_scan_rsp
2026(
2027 hdd_adapter_t* pAdapter,
2028 tANI_U8 *pDest,
2029 tANI_U32 cur_len,
2030 tANI_U32 rem_len
2031)
2032{
2033 tHddBatchScanRsp *pHead;
2034 tHddBatchScanRsp *pPrev;
2035 tANI_U32 len;
2036
Rajeev79dbe4c2013-10-05 11:03:42 +05302037 pAdapter->isTruncated = FALSE;
2038
2039 /*head of hdd batch scan response queue*/
2040 pHead = pAdapter->pBatchScanRsp;
2041 while (pHead)
2042 {
2043 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
2044 pAdapter);
2045 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07002046 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05302047 cur_len += len;
2048 if(TRUE == pAdapter->isTruncated)
2049 {
2050 /*result is truncated return rest of scan rsp in next req*/
2051 cur_len = rem_len;
2052 break;
2053 }
2054 pPrev = pHead;
2055 pHead = pHead->pNext;
2056 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08002057 if (TRUE == pPrev->ApInfo.isLastAp)
2058 {
2059 pAdapter->prev_batch_id = 0;
2060 }
2061 else
2062 {
2063 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
2064 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302065 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002066 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05302067 }
2068
2069 return cur_len;
2070}/*End of hdd_populate_user_batch_scan_rsp*/
2071
2072/**---------------------------------------------------------------------------
2073
2074 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
2075 scan response data from HDD queue to user space
2076 It does following in detail:
2077 a) if HDD has enough data in its queue then it 1st copies data to user
2078 space and then send get batch scan indication message to FW. In this
2079 case it does not wait on any event and batch scan response data will
2080 be populated in HDD response queue in MC thread context after receiving
2081 indication from FW
2082 b) else send get batch scan indication message to FW and wait on an event
2083 which will be set once HDD receives complete batch scan response from
2084 FW and then this function returns batch scan response to user space
2085
2086 \param - pAdapter Pointer to HDD adapter
2087 \param - pPrivData Pointer to priv_data
2088
2089 \return - 0 for success -EFAULT for failure
2090
2091 --------------------------------------------------------------------------*/
2092
2093int hdd_return_batch_scan_rsp_to_user
2094(
2095 hdd_adapter_t* pAdapter,
2096 hdd_priv_data_t *pPrivData,
2097 tANI_U8 *command
2098)
2099{
2100 tANI_U8 *pDest;
2101 tANI_U32 count = 0;
2102 tANI_U32 len = 0;
2103 tANI_U32 cur_len = 0;
2104 tANI_U32 rem_len = 0;
2105 eHalStatus halStatus;
2106 unsigned long rc;
2107 tSirTriggerBatchScanResultInd *pReq;
2108
2109 pReq = &pAdapter->hddTriggerBatchScanResultInd;
2110 pReq->param = 0;/*batch scan client*/
2111 pDest = (tANI_U8 *)(command + pPrivData->used_len);
2112 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
2113
2114 cur_len = pPrivData->used_len;
2115 if (pPrivData->total_len > pPrivData->used_len)
2116 {
2117 rem_len = pPrivData->total_len - pPrivData->used_len;
2118 }
2119 else
2120 {
2121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2122 "%s: Invalid user data buffer total_len %d used_len %d",
2123 __func__, pPrivData->total_len, pPrivData->used_len);
2124 return -EFAULT;
2125 }
2126
2127 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2128 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2129 cur_len, rem_len);
2130 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2131
2132 /*enough scan result available in cache to return to user space or
2133 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08002134 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05302135 {
2136 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
2137 halStatus = sme_TriggerBatchScanResultInd(
2138 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2139 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
2140 pAdapter);
2141 if ( eHAL_STATUS_SUCCESS == halStatus )
2142 {
2143 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
2144 {
2145 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
2146 rc = wait_for_completion_timeout(
2147 &pAdapter->hdd_get_batch_scan_req_var,
2148 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
Abhishek Singh00b71972016-01-07 10:51:04 +05302149 if (0 >= rc)
Rajeev79dbe4c2013-10-05 11:03:42 +05302150 {
2151 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Abhishek Singh00b71972016-01-07 10:51:04 +05302152 "%s: wait on hdd_get_batch_scan_req_var failed %ld",
2153 __func__, rc);
Rajeev79dbe4c2013-10-05 11:03:42 +05302154 return -EFAULT;
2155 }
2156 }
2157
2158 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07002159 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05302160 pDest += len;
2161 cur_len += len;
2162
2163 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2164 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2165 cur_len, rem_len);
2166 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2167
2168 count = 0;
2169 len = (len - pPrivData->used_len);
2170 pDest = (command + pPrivData->used_len);
2171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002172 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302173 while(count < len)
2174 {
2175 printk("%c", *(pDest + count));
2176 count++;
2177 }
2178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2179 "%s: copy %d data to user buffer", __func__, len);
2180 if (copy_to_user(pPrivData->buf, pDest, len))
2181 {
2182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2183 "%s: failed to copy data to user buffer", __func__);
2184 return -EFAULT;
2185 }
2186 }
2187 else
2188 {
2189 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2190 "sme_GetBatchScanScan returned failure halStatus %d",
2191 halStatus);
2192 return -EINVAL;
2193 }
2194 }
2195 else
2196 {
Rajeev79dbe4c2013-10-05 11:03:42 +05302197 count = 0;
2198 len = (len - pPrivData->used_len);
2199 pDest = (command + pPrivData->used_len);
2200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002201 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302202 while(count < len)
2203 {
2204 printk("%c", *(pDest + count));
2205 count++;
2206 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08002207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2208 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05302209 if (copy_to_user(pPrivData->buf, pDest, len))
2210 {
2211 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2212 "%s: failed to copy data to user buffer", __func__);
2213 return -EFAULT;
2214 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302215 }
2216
2217 return 0;
2218} /*End of hdd_return_batch_scan_rsp_to_user*/
2219
Rajeev Kumar8b373292014-01-08 20:36:55 -08002220/**---------------------------------------------------------------------------
2221
2222 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
2223 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
2224 WLS_BATCHING VERSION
2225 WLS_BATCHING SET
2226 WLS_BATCHING GET
2227 WLS_BATCHING STOP
2228
2229 \param - pAdapter Pointer to HDD adapter
2230 \param - pPrivdata Pointer to priv_data
2231 \param - command Pointer to command
2232
2233 \return - 0 for success -EFAULT for failure
2234
2235 --------------------------------------------------------------------------*/
2236
2237int hdd_handle_batch_scan_ioctl
2238(
2239 hdd_adapter_t *pAdapter,
2240 hdd_priv_data_t *pPrivdata,
2241 tANI_U8 *command
2242)
2243{
2244 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08002245 hdd_context_t *pHddCtx;
2246
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302247 ENTER();
2248
Yue Mae36e3552014-03-05 17:06:20 -08002249 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2250 ret = wlan_hdd_validate_context(pHddCtx);
2251 if (ret)
2252 {
Yue Mae36e3552014-03-05 17:06:20 -08002253 goto exit;
2254 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002255
2256 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
2257 {
2258 char extra[32];
2259 tANI_U8 len = 0;
2260 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
2261
2262 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2263 {
2264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2265 "%s: Batch scan feature is not supported by FW", __func__);
2266 ret = -EINVAL;
2267 goto exit;
2268 }
2269
2270 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
2271 version);
2272 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2273 {
2274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2275 "%s: failed to copy data to user buffer", __func__);
2276 ret = -EFAULT;
2277 goto exit;
2278 }
2279 ret = HDD_BATCH_SCAN_VERSION;
2280 }
2281 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
2282 {
2283 int status;
2284 tANI_U8 *value = (command + 16);
2285 eHalStatus halStatus;
2286 unsigned long rc;
2287 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
2288 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
2289
2290 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2291 {
2292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2293 "%s: Batch scan feature is not supported by FW", __func__);
2294 ret = -EINVAL;
2295 goto exit;
2296 }
2297
2298 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
2299 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
2300 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
2301 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
2302 {
2303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302304 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08002305 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302306 hdd_device_modetoString(pAdapter->device_mode),
2307 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002308 ret = -EINVAL;
2309 goto exit;
2310 }
2311
2312 status = hdd_parse_set_batchscan_command(value, pReq);
2313 if (status)
2314 {
2315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2316 "Invalid WLS_BATCHING SET command");
2317 ret = -EINVAL;
2318 goto exit;
2319 }
2320
2321
2322 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
2323 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2324 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
2325 pAdapter);
2326
2327 if ( eHAL_STATUS_SUCCESS == halStatus )
2328 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302329 char extra[32];
2330 tANI_U8 len = 0;
2331 tANI_U8 mScan = 0;
2332
Rajeev Kumar8b373292014-01-08 20:36:55 -08002333 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2334 "sme_SetBatchScanReq returned success halStatus %d",
2335 halStatus);
2336 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
2337 {
2338 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
2339 rc = wait_for_completion_timeout(
2340 &pAdapter->hdd_set_batch_scan_req_var,
2341 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
2342 if (0 == rc)
2343 {
2344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2345 "%s: Timeout waiting for set batch scan to complete",
2346 __func__);
2347 ret = -EINVAL;
2348 goto exit;
2349 }
2350 }
2351 if ( !pRsp->nScansToBatch )
2352 {
2353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2354 "%s: Received set batch scan failure response from FW",
2355 __func__);
2356 ret = -EINVAL;
2357 goto exit;
2358 }
2359 /*As per the Batch Scan Framework API we should return the MIN of
2360 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302361 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002362
2363 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
2364
2365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2366 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302367 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
2368 len = scnprintf(extra, sizeof(extra), "%d", mScan);
2369 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2370 {
2371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2372 "%s: failed to copy MSCAN value to user buffer", __func__);
2373 ret = -EFAULT;
2374 goto exit;
2375 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002376 }
2377 else
2378 {
2379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2380 "sme_SetBatchScanReq returned failure halStatus %d",
2381 halStatus);
2382 ret = -EINVAL;
2383 goto exit;
2384 }
2385 }
2386 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
2387 {
2388 eHalStatus halStatus;
2389 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
2390 pInd->param = 0;
2391
2392 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2393 {
2394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2395 "%s: Batch scan feature is not supported by FW", __func__);
2396 ret = -EINVAL;
2397 goto exit;
2398 }
2399
2400 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2401 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002403 "Batch scan is not yet enabled batch scan state %d",
2404 pAdapter->batchScanState);
2405 ret = -EINVAL;
2406 goto exit;
2407 }
2408
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002409 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2410 hdd_deinit_batch_scan(pAdapter);
2411 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2412
Rajeev Kumar8b373292014-01-08 20:36:55 -08002413 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
2414
2415 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
2416 pAdapter->sessionId);
2417 if ( eHAL_STATUS_SUCCESS == halStatus )
2418 {
2419 ret = 0;
2420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2421 "sme_StopBatchScanInd returned success halStatus %d",
2422 halStatus);
2423 }
2424 else
2425 {
2426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2427 "sme_StopBatchScanInd returned failure halStatus %d",
2428 halStatus);
2429 ret = -EINVAL;
2430 goto exit;
2431 }
2432 }
2433 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
2434 {
2435 tANI_U32 remain_len;
2436
2437 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2438 {
2439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2440 "%s: Batch scan feature is not supported by FW", __func__);
2441 ret = -EINVAL;
2442 goto exit;
2443 }
2444
2445 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2446 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002448 "Batch scan is not yet enabled could not return results"
2449 "Batch Scan state %d",
2450 pAdapter->batchScanState);
2451 ret = -EINVAL;
2452 goto exit;
2453 }
2454
2455 pPrivdata->used_len = 16;
2456 remain_len = pPrivdata->total_len - pPrivdata->used_len;
2457 if (remain_len < pPrivdata->total_len)
2458 {
2459 /*Clear previous batch scan response data if any*/
2460 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
2461 }
2462 else
2463 {
2464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2465 "Invalid total length from user space can't fetch batch"
2466 " scan response total_len %d used_len %d remain len %d",
2467 pPrivdata->total_len, pPrivdata->used_len, remain_len);
2468 ret = -EINVAL;
2469 goto exit;
2470 }
2471 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
2472 }
2473
2474exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302475 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08002476 return ret;
2477}
2478
2479
Rajeev79dbe4c2013-10-05 11:03:42 +05302480#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
2481
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302482#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
2483/**
2484 * hdd_assign_handoff_src_reassoc - Set handoff source as REASSOC
2485 * to Handoff request
2486 * @handoffInfo: Pointer to Handoff request
2487 * @src: enum of handoff_src
2488 * Return: None
2489 */
2490#ifndef QCA_WIFI_ISOC
2491static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2492 *handoffInfo, handoff_src src)
2493{
2494 handoffInfo->src = src;
2495}
2496#else
2497static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2498 *handoffInfo, handoff_src src)
2499{
2500}
2501#endif
2502
2503/**
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302504 * hdd_reassoc() - perform a user space-directed reassoc
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302505 *
2506 * @pAdapter: Adapter upon which the command was received
2507 * @bssid: BSSID with which to reassociate
2508 * @channel: channel upon which to reassociate
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302509 * @src: The source for the trigger of this action
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302510 *
2511 * Return: 0 for success non-zero for failure
2512 */
2513#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302514int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302515 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302516{
2517 hdd_station_ctx_t *pHddStaCtx;
2518 tCsrHandoffRequest handoffInfo;
2519 hdd_context_t *pHddCtx = NULL;
2520 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2521
2522 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2523
2524 /* if not associated, no need to proceed with reassoc */
2525 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2526 hddLog(LOG1, FL("Not associated"));
2527 return -EINVAL;
2528 }
2529
2530 /* if the target bssid is same as currently associated AP,
2531 then no need to proceed with reassoc */
2532 if (!memcmp(bssid, pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr))) {
2533 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
2534 return -EINVAL;
2535 }
2536
2537 /* Check channel number is a valid channel number */
2538 if (VOS_STATUS_SUCCESS !=
2539 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
2540 hddLog(LOGE, FL("Invalid Channel %d"), channel);
2541 return -EINVAL;
2542 }
2543
2544 /* Proceed with reassoc */
2545 handoffInfo.channel = channel;
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302546 hdd_assign_handoff_src_reassoc(&handoffInfo, src);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302547 memcpy(handoffInfo.bssid, bssid, sizeof(tSirMacAddr));
2548 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
2549 return 0;
2550}
2551#else
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302552int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302553 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302554{
2555 return -EPERM;
2556}
2557#endif
2558
2559/**
2560 * hdd_parse_reassoc_v1() - parse version 1 of the REASSOC command
2561 * This function parses the v1 REASSOC command with the format
2562 * REASSOC xx:xx:xx:xx:xx:xx CH where "xx:xx:xx:xx:xx:xx" is the
2563 * Hex-ASCII representation of the BSSID and CH is the ASCII
2564 * representation of the channel. For example
2565 * REASSOC 00:0a:0b:11:22:33 48
2566 *
2567 * @pAdapter: Adapter upon which the command was received
2568 * @command: ASCII text command that was received
2569 *
2570 * Return: 0 for success non-zero for failure
2571 */
2572static int
2573hdd_parse_reassoc_v1(hdd_adapter_t *pAdapter, const char *command)
2574{
2575 tANI_U8 channel = 0;
2576 tSirMacAddr bssid;
2577 int ret;
2578
2579 ret = hdd_parse_reassoc_command_v1_data(command, bssid, &channel);
2580 if (ret)
2581 hddLog(LOGE, FL("Failed to parse reassoc command data"));
2582 else
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302583 ret = hdd_reassoc(pAdapter, bssid, channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302584
2585 return ret;
2586}
2587
2588/**
2589 * hdd_parse_reassoc_v2() - parse version 2 of the REASSOC command
2590 * This function parses the v2 REASSOC command with the format
2591 * REASSOC <android_wifi_reassoc_params>
2592 *
2593 * @pAdapter: Adapter upon which the command was received
2594 * @command: command that was received, ASCII command followed
2595 * by binary data
2596 *
2597 * Return: 0 for success non-zero for failure
2598 */
2599static int
2600hdd_parse_reassoc_v2(hdd_adapter_t *pAdapter, const char *command)
2601{
2602 struct android_wifi_reassoc_params params;
2603 tSirMacAddr bssid;
2604 int ret;
2605
2606 /* The params are located after "REASSOC " */
2607 memcpy(&params, command + 8, sizeof(params));
2608
2609 if (!mac_pton(params.bssid, (u8 *)&bssid)) {
2610 hddLog(LOGE, FL("MAC address parsing failed"));
2611 ret = -EINVAL;
2612 } else {
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302613 ret = hdd_reassoc(pAdapter, bssid, params.channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302614 }
2615 return ret;
2616}
2617
2618/**
2619 * hdd_parse_reassoc() - parse the REASSOC command
2620 * There are two different versions of the REASSOC command.Version 1
2621 * of the command contains a parameter list that is ASCII characters
2622 * whereas version 2 contains a combination of ASCII and binary
2623 * payload. Determine if a version 1 or a version 2 command is being
2624 * parsed by examining the parameters, and then dispatch the parser
2625 * that is appropriate for the command.
2626 *
2627 * @pAdapter: Adapter upon which the command was received
2628 * @command: command that was received
2629 *
2630 * Return: 0 for success non-zero for failure
2631 */
2632static int
2633hdd_parse_reassoc(hdd_adapter_t *pAdapter, const char *command)
2634{
2635 int ret;
2636
2637 /*
2638 * both versions start with "REASSOC"
2639 * v1 has a bssid and channel # as an ASCII string
2640 * REASSOC xx:xx:xx:xx:xx:xx CH
2641 * v2 has a C struct
2642 * REASSOC <binary c struct>
2643 *
2644 * The first field in the v2 struct is also the bssid in ASCII.
2645 * But in the case of a v2 message the BSSID is NUL-terminated.
2646 * Hence we can peek at that offset to see if this is V1 or V2
2647 * REASSOC xx:xx:xx:xx:xx:xx*
2648 * 1111111111222222
2649 * 01234567890123456789012345
2650 */
2651 if (command[25])
2652 ret = hdd_parse_reassoc_v1(pAdapter, command);
2653 else
2654 ret = hdd_parse_reassoc_v2(pAdapter, command);
2655
2656 return ret;
2657}
2658#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE FEATURE_WLAN_LFR */
2659
c_hpothu92367912014-05-01 15:18:17 +05302660static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
2661{
c_hpothu39eb1e32014-06-26 16:31:50 +05302662 bcnMissRateContext_t *pCBCtx;
2663
2664 if (NULL == data)
2665 {
2666 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
2667 return;
2668 }
c_hpothu92367912014-05-01 15:18:17 +05302669
2670 /* there is a race condition that exists between this callback
2671 function and the caller since the caller could time out either
2672 before or while this code is executing. we use a spinlock to
2673 serialize these actions */
2674 spin_lock(&hdd_context_lock);
2675
c_hpothu39eb1e32014-06-26 16:31:50 +05302676 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05302677 gbcnMissRate = -1;
2678
c_hpothu39eb1e32014-06-26 16:31:50 +05302679 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05302680 {
2681 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05302682 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05302683 spin_unlock(&hdd_context_lock);
2684 return ;
2685 }
2686
2687 if (VOS_STATUS_SUCCESS == status)
2688 {
c_hpothu39eb1e32014-06-26 16:31:50 +05302689 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05302690 }
c_hpothu39eb1e32014-06-26 16:31:50 +05302691 else
2692 {
2693 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
2694 }
2695
c_hpothu92367912014-05-01 15:18:17 +05302696 complete(&(pCBCtx->completion));
2697 spin_unlock(&hdd_context_lock);
2698
2699 return;
2700}
2701
Abhishek Singh08aa7762014-12-16 13:59:03 +05302702void hdd_FWStatisCB( VOS_STATUS status,
2703 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05302704{
2705 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302706 hdd_adapter_t *pAdapter;
2707
2708 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
2709
Abhishek Singh08aa7762014-12-16 13:59:03 +05302710 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05302711 {
2712 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
2713 return;
2714 }
2715 /* there is a race condition that exists between this callback
2716 function and the caller since the caller could time out either
2717 before or while this code is executing. we use a spinlock to
2718 serialize these actions */
2719 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05302720 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302721 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
2722 {
2723 hddLog(VOS_TRACE_LEVEL_ERROR,
2724 FL("invalid context magic: %08x"), fwStatsCtx->magic);
2725 spin_unlock(&hdd_context_lock);
2726 return;
2727 }
2728 pAdapter = fwStatsCtx->pAdapter;
2729 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
2730 {
2731 hddLog(VOS_TRACE_LEVEL_ERROR,
2732 FL("pAdapter returned is NULL or invalid"));
2733 spin_unlock(&hdd_context_lock);
2734 return;
2735 }
2736 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05302737 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05302738 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302739 switch( fwStatsResult->type )
2740 {
2741 case FW_UBSP_STATS:
2742 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302743 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302744 hddLog(VOS_TRACE_LEVEL_INFO,
2745 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302746 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2747 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302748 }
2749 break;
2750 default:
2751 {
2752 hddLog(VOS_TRACE_LEVEL_ERROR,
2753 FL(" No handling for stats type %d"),fwStatsResult->type);
2754 }
2755 }
2756 }
2757 complete(&(fwStatsCtx->completion));
2758 spin_unlock(&hdd_context_lock);
2759 return;
2760}
2761
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302762static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2763{
2764 int ret = 0;
2765
2766 if (!pCfg || !command || !extra || !len)
2767 {
2768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2769 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2770 ret = -EINVAL;
2771 return ret;
2772 }
2773
2774 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2775 {
2776 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2777 (int)pCfg->nActiveMaxChnTime);
2778 return ret;
2779 }
2780 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2781 {
2782 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2783 (int)pCfg->nActiveMinChnTime);
2784 return ret;
2785 }
2786 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2787 {
2788 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2789 (int)pCfg->nPassiveMaxChnTime);
2790 return ret;
2791 }
2792 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2793 {
2794 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2795 (int)pCfg->nPassiveMinChnTime);
2796 return ret;
2797 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302798 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2799 {
2800 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2801 (int)pCfg->nActiveMaxChnTime);
2802 return ret;
2803 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302804 else
2805 {
2806 ret = -EINVAL;
2807 }
2808
2809 return ret;
2810}
2811
2812static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2813{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302814 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302815 hdd_config_t *pCfg;
2816 tANI_U8 *value = command;
2817 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302818 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302819
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302820 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2821 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302822 {
2823 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2824 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2825 ret = -EINVAL;
2826 return ret;
2827 }
2828
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302829 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2830 sme_GetConfigParam(hHal, &smeConfig);
2831
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302832 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2833 {
2834 value = value + 24;
2835 temp = kstrtou32(value, 10, &val);
2836 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2837 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2838 {
2839 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2840 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2841 ret = -EFAULT;
2842 return ret;
2843 }
2844 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302845 smeConfig.csrConfig.nActiveMaxChnTime = val;
2846 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302847 }
2848 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2849 {
2850 value = value + 24;
2851 temp = kstrtou32(value, 10, &val);
2852 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2853 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2854 {
2855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2856 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2857 ret = -EFAULT;
2858 return ret;
2859 }
2860 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302861 smeConfig.csrConfig.nActiveMinChnTime = val;
2862 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302863 }
2864 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2865 {
2866 value = value + 25;
2867 temp = kstrtou32(value, 10, &val);
2868 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2869 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2870 {
2871 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2872 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2873 ret = -EFAULT;
2874 return ret;
2875 }
2876 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302877 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2878 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302879 }
2880 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2881 {
2882 value = value + 25;
2883 temp = kstrtou32(value, 10, &val);
2884 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2885 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2886 {
2887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2888 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2889 ret = -EFAULT;
2890 return ret;
2891 }
2892 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302893 smeConfig.csrConfig.nPassiveMinChnTime = val;
2894 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302895 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302896 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2897 {
2898 value = value + 13;
2899 temp = kstrtou32(value, 10, &val);
2900 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2901 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2902 {
2903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2904 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2905 ret = -EFAULT;
2906 return ret;
2907 }
2908 pCfg->nActiveMaxChnTime = val;
2909 smeConfig.csrConfig.nActiveMaxChnTime = val;
2910 sme_UpdateConfig(hHal, &smeConfig);
2911 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302912 else
2913 {
2914 ret = -EINVAL;
2915 }
2916
2917 return ret;
2918}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302919static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
2920 tANI_U8 cmd_len)
2921{
2922 tANI_U8 *value;
2923 tANI_U8 fcc_constraint;
2924
2925 eHalStatus status;
2926 int ret = 0;
2927 value = cmd + cmd_len + 1;
2928
2929 ret = kstrtou8(value, 10, &fcc_constraint);
2930 if ((ret < 0) || (fcc_constraint > 1)) {
2931 /*
2932 * If the input value is greater than max value of datatype,
2933 * then also it is a failure
2934 */
2935 hddLog(VOS_TRACE_LEVEL_ERROR,
2936 "%s: value out of range", __func__);
2937 return -EINVAL;
2938 }
2939
Agrawal Ashish842eea82016-02-04 17:56:16 +05302940 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint,
2941 pHddCtx->scan_info.mScanPending);
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302942 if (status != eHAL_STATUS_SUCCESS)
2943 ret = -EPERM;
2944
2945 return ret;
2946}
2947
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05302948/**---------------------------------------------------------------------------
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302949
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05302950 \brief hdd_enable_disable_ca_event() - When Host sends IOCTL (enabled),
2951 FW will send *ONE* CA ind to Host(even though it is duplicate).
2952 When Host send IOCTL (disable), FW doesn't perform any action.
2953 Whenever any change in CA *and* WLAN is in SAP/P2P-GO mode, FW
2954 sends CA ind to host. (regard less of IOCTL status)
2955 \param - pHddCtx - HDD context
2956 \param - command - command received from framework
2957 \param - cmd_len - len of the command
2958
2959 \return - 0 on success, appropriate error values on failure.
2960
2961 --------------------------------------------------------------------------*/
2962int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, tANI_U8* command, tANI_U8 cmd_len)
2963{
2964 tANI_U8 set_value;
2965 int ret = 0;
2966 eHalStatus status;
2967
2968 ret = wlan_hdd_validate_context(pHddCtx);
2969 if (0 != ret)
2970 {
2971 ret = -EINVAL;
2972 goto exit;
2973 }
2974
2975 if (pHddCtx->cfg_ini->gOptimizeCAevent == 0)
2976 {
2977 hddLog(VOS_TRACE_LEVEL_ERROR, "Enable gOptimizeCAevent"
2978 " ini param to control channel avooidance indication");
2979 ret = 0;
2980 goto exit;
2981 }
2982
2983 set_value = command[cmd_len + 1] - '0';
2984 status = sme_enableDisableChanAvoidIndEvent(pHddCtx->hHal, set_value);
2985 if (status != eHAL_STATUS_SUCCESS)
2986 {
2987 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to send"
2988 " enableDisableChanAoidance command to SME\n", __func__);
2989 ret = -EINVAL;
2990 }
2991
2992exit:
2993 return ret;
2994}
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302995
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05302996/**
2997 * wlan_hdd_fastreassoc_handoff_request() - Post Handoff request to SME
2998 * @pHddCtx: Pointer to the HDD context
2999 * @channel: channel to reassociate
3000 * @targetApBssid: Target AP/BSSID to reassociate
3001 *
3002 * Return: None
3003 */
3004#if defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) && !defined(QCA_WIFI_ISOC)
3005static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3006 uint8_t channel, tSirMacAddr targetApBssid)
3007{
3008 tCsrHandoffRequest handoffInfo;
3009 handoffInfo.channel = channel;
3010 handoffInfo.src = FASTREASSOC;
3011 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3012 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3013}
3014#else
3015static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3016 uint8_t channel, tSirMacAddr targetApBssid)
3017{
3018}
3019#endif
3020
3021/**
3022 * csr_fastroam_neighbor_ap_event() - Function to trigger scan/roam
3023 * @pAdapter: Pointer to HDD adapter
3024 * @channel: Channel to scan/roam
3025 * @targetApBssid: BSSID to roam
3026 *
3027 * Return: None
3028 */
3029#ifdef QCA_WIFI_ISOC
3030static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3031 uint8_t channel, tSirMacAddr targetApBssid)
3032{
3033 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3034 &targetApBssid[0], eSME_ROAM_TRIGGER_SCAN, channel);
3035}
3036#else
3037static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3038 uint8_t channel, tSirMacAddr targetApBssid)
3039{
3040}
3041#endif
3042
3043/**
3044 * wlan_hdd_handle_fastreassoc() - Handle fastreassoc command
3045 * @pAdapter: pointer to hdd adapter
3046 * @command: pointer to the command received
3047 *
3048 * Return: VOS_STATUS enum
3049 */
3050static VOS_STATUS wlan_hdd_handle_fastreassoc(hdd_adapter_t *pAdapter,
3051 uint8_t *command)
3052{
3053 tANI_U8 *value = command;
3054 tANI_U8 channel = 0;
3055 tSirMacAddr targetApBssid;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303056 hdd_station_ctx_t *pHddStaCtx = NULL;
3057 hdd_context_t *pHddCtx = NULL;
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303058 int ret;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303059 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3060 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3061
3062 /* if not associated, no need to proceed with reassoc */
3063 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
3064 hddLog(LOG1, FL("Not associated!"));
3065 return eHAL_STATUS_FAILURE;
3066 }
3067
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303068 ret = hdd_parse_reassoc_command_v1_data(value, targetApBssid, &channel);
3069 if (ret) {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303070 hddLog(LOGE, FL("Failed to parse reassoc command data"));
3071 return eHAL_STATUS_FAILURE;
3072 }
3073
3074 /* if the target bssid is same as currently associated AP,
3075 then no need to proceed with reassoc */
3076 if (vos_mem_compare(targetApBssid,
3077 pHddStaCtx->conn_info.bssId,
3078 sizeof(tSirMacAddr))) {
3079 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
3080 return eHAL_STATUS_FAILURE;
3081 }
3082
3083 /* Check channel number is a valid channel number */
3084 if (VOS_STATUS_SUCCESS !=
3085 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
3086 hddLog(LOGE, FL("Invalid Channel [%d]"), channel);
3087 return eHAL_STATUS_FAILURE;
3088 }
3089
3090 /* Proceed with reassoc */
3091 wlan_hdd_fastreassoc_handoff_request(pHddCtx, channel, targetApBssid);
3092
3093 /* Proceed with scan/roam */
3094 csr_fastroam_neighbor_ap_event(pAdapter, channel, targetApBssid);
3095
3096 return eHAL_STATUS_SUCCESS;
3097}
3098
3099/**
3100 * hdd_assign_reassoc_handoff - Set handoff source as REASSOC
3101 * @handoffInfo: Pointer to the csr Handoff Request.
3102 *
3103 * Return: None
3104 */
3105#ifndef QCA_WIFI_ISOC
3106static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3107{
3108 handoffInfo->src = REASSOC;
3109}
3110#else
3111static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3112{
3113}
3114#endif
3115
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003116static int hdd_driver_command(hdd_adapter_t *pAdapter,
3117 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07003118{
Jeff Johnson295189b2012-06-20 16:38:30 -07003119 hdd_priv_data_t priv_data;
3120 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303121 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3122 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003123 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303124 int status;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303125#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3126 struct cfg80211_mgmt_tx_params params;
3127#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303128
3129 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003130 /*
3131 * Note that valid pointers are provided by caller
3132 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003133
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003134 /* copy to local struct to avoid numerous changes to legacy code */
3135 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07003136
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003137 if (priv_data.total_len <= 0 ||
3138 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07003139 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003140 hddLog(VOS_TRACE_LEVEL_WARN,
3141 "%s:invalid priv_data.total_len(%d)!!!", __func__,
3142 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003143 ret = -EINVAL;
3144 goto exit;
3145 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05303146 status = wlan_hdd_validate_context(pHddCtx);
3147 if (0 != status)
3148 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303149 ret = -EINVAL;
3150 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303151 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003152 /* Allocate +1 for '\0' */
3153 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07003154 if (!command)
3155 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003156 hddLog(VOS_TRACE_LEVEL_ERROR,
3157 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003158 ret = -ENOMEM;
3159 goto exit;
3160 }
3161
3162 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
3163 {
3164 ret = -EFAULT;
3165 goto exit;
3166 }
3167
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003168 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003169 command[priv_data.total_len] = '\0';
3170
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003171 /* at one time the following block of code was conditional. braces
3172 * have been retained to avoid re-indenting the legacy code
3173 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003174 {
3175 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
3176
3177 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003178 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07003179
3180 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
3181 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303182 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3183 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
3184 pAdapter->sessionId, (unsigned)
3185 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
3186 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
3187 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
3188 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07003189 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
3190 sizeof(tSirMacAddr)))
3191 {
3192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003193 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003194 ret = -EFAULT;
3195 }
3196 }
Amar Singhal0974e402013-02-12 14:27:46 -08003197 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07003198 {
Amar Singhal0974e402013-02-12 14:27:46 -08003199 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003200
Jeff Johnson295189b2012-06-20 16:38:30 -07003201 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003202
3203 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07003204 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07003205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08003206 "%s: SetBandCommand Info comm %s UL %d, TL %d", __func__, command, priv_data.used_len, priv_data.total_len);
Anand N Sunkad27354cf2015-07-13 14:39:11 +05303207 if(VOS_FTM_MODE != hdd_get_conparam())
3208 {
3209 /* Change band request received */
3210 ret = hdd_setBand_helper(pAdapter->dev, ptr);
3211 if(ret < 0)
3212 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3213 "%s: failed to set band ret=%d", __func__, ret);
3214 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003215 }
Kiet Lamf040f472013-11-20 21:15:23 +05303216 else if(strncmp(command, "SETWMMPS", 8) == 0)
3217 {
3218 tANI_U8 *ptr = command;
3219 ret = hdd_wmmps_helper(pAdapter, ptr);
3220 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05303221
3222 else if(strncmp(command, "TDLSSCAN", 8) == 0)
3223 {
3224 tANI_U8 *ptr = command;
3225 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
3226 }
3227
Jeff Johnson32d95a32012-09-10 13:15:23 -07003228 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
3229 {
3230 char *country_code;
3231
3232 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07003233
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003234 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07003235 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003236#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05303237 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003238#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003239 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
3240 (void *)(tSmeChangeCountryCallback)
3241 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05303242 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003243 if (eHAL_STATUS_SUCCESS == ret)
3244 {
3245 ret = wait_for_completion_interruptible_timeout(
3246 &pAdapter->change_country_code,
3247 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
3248 if (0 >= ret)
3249 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003250 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303251 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003252 }
3253 }
3254 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07003255 {
3256 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003257 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003258 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07003259 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003260
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003261 }
3262 /*
3263 command should be a string having format
3264 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
3265 */
Amar Singhal0974e402013-02-12 14:27:46 -08003266 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003267 {
Amar Singhal0974e402013-02-12 14:27:46 -08003268 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003269
3270 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003271 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003272
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08003273 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07003274 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08003275 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
3276 {
3277 int suspend = 0;
3278 tANI_U8 *ptr = (tANI_U8*)command + 15;
3279
3280 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303281 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3282 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
3283 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08003284 hdd_set_wlan_suspend_mode(suspend);
3285 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003286#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
3287 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
3288 {
3289 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003290 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003291 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
3292 eHalStatus status = eHAL_STATUS_SUCCESS;
3293
3294 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
3295 value = value + 15;
3296
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003297 /* Convert the value from ascii to integer */
3298 ret = kstrtos8(value, 10, &rssi);
3299 if (ret < 0)
3300 {
3301 /* If the input value is greater than max value of datatype, then also
3302 kstrtou8 fails */
3303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3304 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07003305 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003306 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
3307 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
3308 ret = -EINVAL;
3309 goto exit;
3310 }
3311
Srinivas Girigowdade697412013-02-14 16:31:48 -08003312 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003313
Srinivas Girigowdade697412013-02-14 16:31:48 -08003314 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
3315 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
3316 {
3317 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3318 "Neighbor lookup threshold value %d is out of range"
3319 " (Min: %d Max: %d)", lookUpThreshold,
3320 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
3321 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
3322 ret = -EINVAL;
3323 goto exit;
3324 }
3325
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303326 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3327 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
3328 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3330 "%s: Received Command to Set Roam trigger"
3331 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
3332
3333 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
3334 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
3335 if (eHAL_STATUS_SUCCESS != status)
3336 {
3337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3338 "%s: Failed to set roam trigger, try again", __func__);
3339 ret = -EPERM;
3340 goto exit;
3341 }
3342
3343 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05303344 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003345 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
3346 }
3347 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
3348 {
3349 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
3350 int rssi = (-1) * lookUpThreshold;
3351 char extra[32];
3352 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303353 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3354 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
3355 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003356 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05303357 len = VOS_MIN(priv_data.total_len, len + 1);
3358 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003359 {
3360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3361 "%s: failed to copy data to user buffer", __func__);
3362 ret = -EFAULT;
3363 goto exit;
3364 }
3365 }
3366 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
3367 {
3368 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003369 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003370 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003371
Srinivas Girigowdade697412013-02-14 16:31:48 -08003372 /* input refresh period is in terms of seconds */
3373 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
3374 value = value + 18;
3375 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003376 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003377 if (ret < 0)
3378 {
3379 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003380 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003381 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003382 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08003383 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07003384 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
3385 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003386 ret = -EINVAL;
3387 goto exit;
3388 }
3389
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003390 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
3391 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003392 {
3393 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003394 "Roam scan period value %d is out of range"
3395 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07003396 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
3397 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003398 ret = -EINVAL;
3399 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303400 }
3401 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3402 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
3403 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003404 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003405
3406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3407 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003408 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003409
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003410 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
3411 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003412 }
3413 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
3414 {
3415 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
3416 char extra[32];
3417 tANI_U8 len = 0;
3418
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303419 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3420 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
3421 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003422 len = scnprintf(extra, sizeof(extra), "%s %d",
3423 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003424 /* Returned value is in units of seconds */
Ratnam Rachuria72ba112015-07-17 13:27:03 +05303425 len = VOS_MIN(priv_data.total_len, len + 1);
3426 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08003427 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 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003433 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
3434 {
3435 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003436 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003437 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003438
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003439 /* input refresh period is in terms of seconds */
3440 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
3441 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003442
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003443 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003444 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003445 if (ret < 0)
3446 {
3447 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003448 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003449 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003450 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003451 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003452 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
3453 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
3454 ret = -EINVAL;
3455 goto exit;
3456 }
3457
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003458 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
3459 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
3460 {
3461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3462 "Neighbor scan results refresh period value %d is out of range"
3463 " (Min: %d Max: %d)", roamScanRefreshPeriod,
3464 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
3465 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
3466 ret = -EINVAL;
3467 goto exit;
3468 }
3469 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
3470
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003471 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3472 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003473 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003474
3475 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
3476 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
3477 }
3478 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
3479 {
3480 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
3481 char extra[32];
3482 tANI_U8 len = 0;
3483
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003484 len = scnprintf(extra, sizeof(extra), "%s %d",
3485 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003486 /* Returned value is in units of seconds */
Ratnam Rachuri2c9d6702015-07-17 13:25:16 +05303487 len = VOS_MIN(priv_data.total_len, len + 1);
3488 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3490 "%s: failed to copy data to user buffer", __func__);
3491 ret = -EFAULT;
3492 goto exit;
3493 }
3494 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003495#ifdef FEATURE_WLAN_LFR
3496 /* SETROAMMODE */
3497 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
3498 {
3499 tANI_U8 *value = command;
3500 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3501
3502 /* Move pointer to ahead of SETROAMMODE<delimiter> */
3503 value = value + SIZE_OF_SETROAMMODE + 1;
3504
3505 /* Convert the value from ascii to integer */
3506 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
3507 if (ret < 0)
3508 {
3509 /* If the input value is greater than max value of datatype, then also
3510 kstrtou8 fails */
3511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3512 "%s: kstrtou8 failed range [%d - %d]", __func__,
3513 CFG_LFR_FEATURE_ENABLED_MIN,
3514 CFG_LFR_FEATURE_ENABLED_MAX);
3515 ret = -EINVAL;
3516 goto exit;
3517 }
3518 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3519 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
3520 {
3521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3522 "Roam Mode value %d is out of range"
3523 " (Min: %d Max: %d)", roamMode,
3524 CFG_LFR_FEATURE_ENABLED_MIN,
3525 CFG_LFR_FEATURE_ENABLED_MAX);
3526 ret = -EINVAL;
3527 goto exit;
3528 }
3529
3530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3531 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
3532 /*
3533 * Note that
3534 * SETROAMMODE 0 is to enable LFR while
3535 * SETROAMMODE 1 is to disable LFR, but
3536 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
3537 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
3538 */
3539 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
3540 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
3541 else
3542 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
3543
3544 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
3545 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
3546 }
3547 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303548 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003549 {
3550 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
3551 char extra[32];
3552 tANI_U8 len = 0;
3553
3554 /*
3555 * roamMode value shall be inverted because the sementics is different.
3556 */
3557 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
3558 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
3559 else
3560 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
3561
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003562 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Ratnam Rachuri28693eb2015-07-17 13:23:42 +05303563 len = VOS_MIN(priv_data.total_len, len + 1);
3564 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3566 "%s: failed to copy data to user buffer", __func__);
3567 ret = -EFAULT;
3568 goto exit;
3569 }
3570 }
3571#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08003572#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003573#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003574 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
3575 {
3576 tANI_U8 *value = command;
3577 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
3578
3579 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
3580 value = value + 13;
3581 /* Convert the value from ascii to integer */
3582 ret = kstrtou8(value, 10, &roamRssiDiff);
3583 if (ret < 0)
3584 {
3585 /* If the input value is greater than max value of datatype, then also
3586 kstrtou8 fails */
3587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3588 "%s: kstrtou8 failed range [%d - %d]", __func__,
3589 CFG_ROAM_RSSI_DIFF_MIN,
3590 CFG_ROAM_RSSI_DIFF_MAX);
3591 ret = -EINVAL;
3592 goto exit;
3593 }
3594
3595 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
3596 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
3597 {
3598 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3599 "Roam rssi diff value %d is out of range"
3600 " (Min: %d Max: %d)", roamRssiDiff,
3601 CFG_ROAM_RSSI_DIFF_MIN,
3602 CFG_ROAM_RSSI_DIFF_MAX);
3603 ret = -EINVAL;
3604 goto exit;
3605 }
3606
3607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3608 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
3609
3610 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
3611 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
3612 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303613 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003614 {
3615 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
3616 char extra[32];
3617 tANI_U8 len = 0;
3618
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303619 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3620 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
3621 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003622 len = scnprintf(extra, sizeof(extra), "%s %d",
3623 command, roamRssiDiff);
Ratnam Rachuri22a3b402015-07-17 13:21:49 +05303624 len = VOS_MIN(priv_data.total_len, len + 1);
3625 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08003626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3627 "%s: failed to copy data to user buffer", __func__);
3628 ret = -EFAULT;
3629 goto exit;
3630 }
3631 }
3632#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003633#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003634 else if (strncmp(command, "GETBAND", 7) == 0)
3635 {
3636 int band = -1;
3637 char extra[32];
3638 tANI_U8 len = 0;
3639 hdd_getBand_helper(pHddCtx, &band);
3640
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303641 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3642 TRACE_CODE_HDD_GETBAND_IOCTL,
3643 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003644 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Ratnam Rachuri52139592015-07-17 13:17:29 +05303645 len = VOS_MIN(priv_data.total_len, len + 1);
3646 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08003647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3648 "%s: failed to copy data to user buffer", __func__);
3649 ret = -EFAULT;
3650 goto exit;
3651 }
3652 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003653 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
3654 {
3655 tANI_U8 *value = command;
3656 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3657 tANI_U8 numChannels = 0;
3658 eHalStatus status = eHAL_STATUS_SUCCESS;
3659
3660 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3661 if (eHAL_STATUS_SUCCESS != status)
3662 {
3663 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3664 "%s: Failed to parse channel list information", __func__);
3665 ret = -EINVAL;
3666 goto exit;
3667 }
3668
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303669 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3670 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
3671 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003672 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3673 {
3674 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3675 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3676 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3677 ret = -EINVAL;
3678 goto exit;
3679 }
3680 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
3681 numChannels);
3682 if (eHAL_STATUS_SUCCESS != status)
3683 {
3684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3685 "%s: Failed to update channel list information", __func__);
3686 ret = -EINVAL;
3687 goto exit;
3688 }
3689 }
3690 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
3691 {
3692 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3693 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07003694 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003695 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07003696 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003697
3698 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
3699 ChannelList, &numChannels ))
3700 {
3701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3702 "%s: failed to get roam scan channel list", __func__);
3703 ret = -EFAULT;
3704 goto exit;
3705 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303706 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3707 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
3708 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003709 /* output channel list is of the format
3710 [Number of roam scan channels][Channel1][Channel2]... */
3711 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003712 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Sushant Kaushika08ca192015-09-16 15:52:04 +05303713 for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003714 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003715 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
3716 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003717 }
3718
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05303719 len = VOS_MIN(priv_data.total_len, len + 1);
3720 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003721 {
3722 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3723 "%s: failed to copy data to user buffer", __func__);
3724 ret = -EFAULT;
3725 goto exit;
3726 }
3727 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003728 else if (strncmp(command, "GETCCXMODE", 10) == 0)
3729 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003730 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003731 char extra[32];
3732 tANI_U8 len = 0;
3733
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003734 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003735 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003736 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003737 hdd_is_okc_mode_enabled(pHddCtx) &&
3738 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3739 {
3740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003741 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003742 " hence this operation is not permitted!", __func__);
3743 ret = -EPERM;
3744 goto exit;
3745 }
3746
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003747 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003748 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05303749 len = VOS_MIN(priv_data.total_len, len + 1);
3750 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003751 {
3752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3753 "%s: failed to copy data to user buffer", __func__);
3754 ret = -EFAULT;
3755 goto exit;
3756 }
3757 }
3758 else if (strncmp(command, "GETOKCMODE", 10) == 0)
3759 {
3760 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
3761 char extra[32];
3762 tANI_U8 len = 0;
3763
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003764 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003765 then this operation is not permitted (return FAILURE) */
3766 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003767 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003768 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3769 {
3770 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003771 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003772 " hence this operation is not permitted!", __func__);
3773 ret = -EPERM;
3774 goto exit;
3775 }
3776
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003777 len = scnprintf(extra, sizeof(extra), "%s %d",
3778 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05303779 len = VOS_MIN(priv_data.total_len, len + 1);
3780 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003781 {
3782 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3783 "%s: failed to copy data to user buffer", __func__);
3784 ret = -EFAULT;
3785 goto exit;
3786 }
3787 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003788 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003789 {
3790 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
3791 char extra[32];
3792 tANI_U8 len = 0;
3793
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003794 len = scnprintf(extra, sizeof(extra), "%s %d",
3795 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05303796 len = VOS_MIN(priv_data.total_len, len + 1);
3797 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003798 {
3799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3800 "%s: failed to copy data to user buffer", __func__);
3801 ret = -EFAULT;
3802 goto exit;
3803 }
3804 }
3805 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
3806 {
3807 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
3808 char extra[32];
3809 tANI_U8 len = 0;
3810
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003811 len = scnprintf(extra, sizeof(extra), "%s %d",
3812 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05303813 len = VOS_MIN(priv_data.total_len, len + 1);
3814 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003815 {
3816 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3817 "%s: failed to copy data to user buffer", __func__);
3818 ret = -EFAULT;
3819 goto exit;
3820 }
3821 }
3822 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
3823 {
3824 tANI_U8 *value = command;
3825 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
3826
3827 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
3828 value = value + 26;
3829 /* Convert the value from ascii to integer */
3830 ret = kstrtou8(value, 10, &minTime);
3831 if (ret < 0)
3832 {
3833 /* If the input value is greater than max value of datatype, then also
3834 kstrtou8 fails */
3835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3836 "%s: kstrtou8 failed range [%d - %d]", __func__,
3837 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
3838 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
3839 ret = -EINVAL;
3840 goto exit;
3841 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003842 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
3843 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
3844 {
3845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3846 "scan min channel time value %d is out of range"
3847 " (Min: %d Max: %d)", minTime,
3848 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
3849 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
3850 ret = -EINVAL;
3851 goto exit;
3852 }
3853
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303854 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3855 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
3856 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3858 "%s: Received Command to change channel min time = %d", __func__, minTime);
3859
3860 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
3861 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
3862 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003863 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
3864 {
3865 tANI_U8 *value = command;
3866 tANI_U8 channel = 0;
3867 tANI_U8 dwellTime = 0;
3868 tANI_U8 bufLen = 0;
3869 tANI_U8 *buf = NULL;
3870 tSirMacAddr targetApBssid;
3871 eHalStatus status = eHAL_STATUS_SUCCESS;
3872 struct ieee80211_channel chan;
3873 tANI_U8 finalLen = 0;
3874 tANI_U8 *finalBuf = NULL;
3875 tANI_U8 temp = 0;
3876 u64 cookie;
3877 hdd_station_ctx_t *pHddStaCtx = NULL;
3878 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3879
3880 /* if not associated, no need to send action frame */
3881 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3882 {
3883 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3884 ret = -EINVAL;
3885 goto exit;
3886 }
3887
3888 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
3889 &dwellTime, &buf, &bufLen);
3890 if (eHAL_STATUS_SUCCESS != status)
3891 {
3892 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3893 "%s: Failed to parse send action frame data", __func__);
3894 ret = -EINVAL;
3895 goto exit;
3896 }
3897
3898 /* if the target bssid is different from currently associated AP,
3899 then no need to send action frame */
3900 if (VOS_TRUE != vos_mem_compare(targetApBssid,
3901 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3902 {
3903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
3904 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003905 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003906 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003907 goto exit;
3908 }
3909
3910 /* if the channel number is different from operating channel then
3911 no need to send action frame */
3912 if (channel != pHddStaCtx->conn_info.operationChannel)
3913 {
3914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3915 "%s: channel(%d) is different from operating channel(%d)",
3916 __func__, channel, pHddStaCtx->conn_info.operationChannel);
3917 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003918 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003919 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003920 goto exit;
3921 }
3922 chan.center_freq = sme_ChnToFreq(channel);
3923
3924 finalLen = bufLen + 24;
3925 finalBuf = vos_mem_malloc(finalLen);
3926 if (NULL == finalBuf)
3927 {
3928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
3929 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07003930 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003931 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003932 goto exit;
3933 }
3934 vos_mem_zero(finalBuf, finalLen);
3935
3936 /* Fill subtype */
3937 temp = SIR_MAC_MGMT_ACTION << 4;
3938 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3939
3940 /* Fill type */
3941 temp = SIR_MAC_MGMT_FRAME;
3942 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3943
3944 /* Fill destination address (bssid of the AP) */
3945 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3946
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003947 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003948 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3949
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003950 /* Fill BSSID (AP mac address) */
3951 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003952
3953 /* Fill received buffer from 24th address */
3954 vos_mem_copy(finalBuf + 24, buf, bufLen);
3955
Jeff Johnson11c33152013-04-16 17:52:40 -07003956 /* done with the parsed buffer */
3957 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003958 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003959
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303960#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3961 params.chan = &chan;
3962 params.offchan = 0;
3963 params.wait = dwellTime;
3964 params.buf = finalBuf;
3965 params.len = finalLen;
3966 params.no_cck = 1;
3967 params.dont_wait_for_ack = 1;
3968 ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
3969#else
DARAM SUDHA39eede62014-02-12 11:16:40 +05303970 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003971#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3972 &(pAdapter->wdev),
3973#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003974 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003975#endif
3976 &chan, 0,
3977#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3978 NL80211_CHAN_HT20, 1,
3979#endif
3980 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003981 1, &cookie );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303982#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003983 vos_mem_free(finalBuf);
3984 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003985 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3986 {
3987 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3988 char extra[32];
3989 tANI_U8 len = 0;
3990
3991 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003992 len = scnprintf(extra, sizeof(extra), "%s %d",
3993 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303994 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3995 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3996 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05303997 len = VOS_MIN(priv_data.total_len, len + 1);
3998 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003999 {
4000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4001 "%s: failed to copy data to user buffer", __func__);
4002 ret = -EFAULT;
4003 goto exit;
4004 }
4005 }
4006 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
4007 {
4008 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004009 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004010
4011 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
4012 value = value + 19;
4013 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004014 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004015 if (ret < 0)
4016 {
4017 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004018 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004019 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004020 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004021 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4022 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4023 ret = -EINVAL;
4024 goto exit;
4025 }
4026
4027 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
4028 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
4029 {
4030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4031 "lfr mode value %d is out of range"
4032 " (Min: %d Max: %d)", maxTime,
4033 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4034 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4035 ret = -EINVAL;
4036 goto exit;
4037 }
4038
4039 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4040 "%s: Received Command to change channel max time = %d", __func__, maxTime);
4041
4042 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
4043 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
4044 }
4045 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
4046 {
4047 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
4048 char extra[32];
4049 tANI_U8 len = 0;
4050
4051 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004052 len = scnprintf(extra, sizeof(extra), "%s %d",
4053 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05304054 len = VOS_MIN(priv_data.total_len, len + 1);
4055 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004056 {
4057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4058 "%s: failed to copy data to user buffer", __func__);
4059 ret = -EFAULT;
4060 goto exit;
4061 }
4062 }
4063 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
4064 {
4065 tANI_U8 *value = command;
4066 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
4067
4068 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
4069 value = value + 16;
4070 /* Convert the value from ascii to integer */
4071 ret = kstrtou16(value, 10, &val);
4072 if (ret < 0)
4073 {
4074 /* If the input value is greater than max value of datatype, then also
4075 kstrtou16 fails */
4076 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4077 "%s: kstrtou16 failed range [%d - %d]", __func__,
4078 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4079 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4080 ret = -EINVAL;
4081 goto exit;
4082 }
4083
4084 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
4085 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
4086 {
4087 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4088 "scan home time value %d is out of range"
4089 " (Min: %d Max: %d)", val,
4090 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4091 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4092 ret = -EINVAL;
4093 goto exit;
4094 }
4095
4096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4097 "%s: Received Command to change scan home time = %d", __func__, val);
4098
4099 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
4100 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
4101 }
4102 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
4103 {
4104 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
4105 char extra[32];
4106 tANI_U8 len = 0;
4107
4108 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004109 len = scnprintf(extra, sizeof(extra), "%s %d",
4110 "GETSCANHOMETIME", val);
Ratheesh S P728d7c62015-07-16 15:38:58 +05304111 len = VOS_MIN(priv_data.total_len, len + 1);
4112 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004113 {
4114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4115 "%s: failed to copy data to user buffer", __func__);
4116 ret = -EFAULT;
4117 goto exit;
4118 }
4119 }
4120 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
4121 {
4122 tANI_U8 *value = command;
4123 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
4124
4125 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
4126 value = value + 17;
4127 /* Convert the value from ascii to integer */
4128 ret = kstrtou8(value, 10, &val);
4129 if (ret < 0)
4130 {
4131 /* If the input value is greater than max value of datatype, then also
4132 kstrtou8 fails */
4133 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4134 "%s: kstrtou8 failed range [%d - %d]", __func__,
4135 CFG_ROAM_INTRA_BAND_MIN,
4136 CFG_ROAM_INTRA_BAND_MAX);
4137 ret = -EINVAL;
4138 goto exit;
4139 }
4140
4141 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
4142 (val > CFG_ROAM_INTRA_BAND_MAX))
4143 {
4144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4145 "intra band mode value %d is out of range"
4146 " (Min: %d Max: %d)", val,
4147 CFG_ROAM_INTRA_BAND_MIN,
4148 CFG_ROAM_INTRA_BAND_MAX);
4149 ret = -EINVAL;
4150 goto exit;
4151 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4153 "%s: Received Command to change intra band = %d", __func__, val);
4154
4155 pHddCtx->cfg_ini->nRoamIntraBand = val;
4156 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
4157 }
4158 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
4159 {
4160 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
4161 char extra[32];
4162 tANI_U8 len = 0;
4163
4164 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004165 len = scnprintf(extra, sizeof(extra), "%s %d",
4166 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +05304167 len = VOS_MIN(priv_data.total_len, len + 1);
4168 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004169 {
4170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4171 "%s: failed to copy data to user buffer", __func__);
4172 ret = -EFAULT;
4173 goto exit;
4174 }
4175 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004176 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
4177 {
4178 tANI_U8 *value = command;
4179 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
4180
4181 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
4182 value = value + 15;
4183 /* Convert the value from ascii to integer */
4184 ret = kstrtou8(value, 10, &nProbes);
4185 if (ret < 0)
4186 {
4187 /* If the input value is greater than max value of datatype, then also
4188 kstrtou8 fails */
4189 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4190 "%s: kstrtou8 failed range [%d - %d]", __func__,
4191 CFG_ROAM_SCAN_N_PROBES_MIN,
4192 CFG_ROAM_SCAN_N_PROBES_MAX);
4193 ret = -EINVAL;
4194 goto exit;
4195 }
4196
4197 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
4198 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
4199 {
4200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4201 "NProbes value %d is out of range"
4202 " (Min: %d Max: %d)", nProbes,
4203 CFG_ROAM_SCAN_N_PROBES_MIN,
4204 CFG_ROAM_SCAN_N_PROBES_MAX);
4205 ret = -EINVAL;
4206 goto exit;
4207 }
4208
4209 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4210 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
4211
4212 pHddCtx->cfg_ini->nProbes = nProbes;
4213 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
4214 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304215 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004216 {
4217 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
4218 char extra[32];
4219 tANI_U8 len = 0;
4220
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004221 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri6da525d2015-08-07 13:55:54 +05304222 len = VOS_MIN(priv_data.total_len, len + 1);
4223 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4225 "%s: failed to copy data to user buffer", __func__);
4226 ret = -EFAULT;
4227 goto exit;
4228 }
4229 }
4230 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
4231 {
4232 tANI_U8 *value = command;
4233 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
4234
4235 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
4236 /* input value is in units of msec */
4237 value = value + 20;
4238 /* Convert the value from ascii to integer */
4239 ret = kstrtou16(value, 10, &homeAwayTime);
4240 if (ret < 0)
4241 {
4242 /* If the input value is greater than max value of datatype, then also
4243 kstrtou8 fails */
4244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4245 "%s: kstrtou8 failed range [%d - %d]", __func__,
4246 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
4247 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
4248 ret = -EINVAL;
4249 goto exit;
4250 }
4251
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004252 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
4253 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
4254 {
4255 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4256 "homeAwayTime value %d is out of range"
4257 " (Min: %d Max: %d)", homeAwayTime,
4258 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
4259 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
4260 ret = -EINVAL;
4261 goto exit;
4262 }
4263
4264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4265 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07004266 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
4267 {
4268 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
4269 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
4270 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004271 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304272 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004273 {
4274 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
4275 char extra[32];
4276 tANI_U8 len = 0;
4277
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004278 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri51a5ad12015-08-07 14:06:37 +05304279 len = VOS_MIN(priv_data.total_len, len + 1);
4280 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004281 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4282 "%s: failed to copy data to user buffer", __func__);
4283 ret = -EFAULT;
4284 goto exit;
4285 }
4286 }
4287 else if (strncmp(command, "REASSOC", 7) == 0)
4288 {
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05304289 ret = hdd_parse_reassoc(pAdapter, command);
4290 if (!ret)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004291 goto exit;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004292 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004293 else if (strncmp(command, "SETWESMODE", 10) == 0)
4294 {
4295 tANI_U8 *value = command;
4296 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
4297
4298 /* Move pointer to ahead of SETWESMODE<delimiter> */
4299 value = value + 11;
4300 /* Convert the value from ascii to integer */
4301 ret = kstrtou8(value, 10, &wesMode);
4302 if (ret < 0)
4303 {
4304 /* If the input value is greater than max value of datatype, then also
4305 kstrtou8 fails */
4306 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4307 "%s: kstrtou8 failed range [%d - %d]", __func__,
4308 CFG_ENABLE_WES_MODE_NAME_MIN,
4309 CFG_ENABLE_WES_MODE_NAME_MAX);
4310 ret = -EINVAL;
4311 goto exit;
4312 }
4313
4314 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
4315 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
4316 {
4317 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4318 "WES Mode value %d is out of range"
4319 " (Min: %d Max: %d)", wesMode,
4320 CFG_ENABLE_WES_MODE_NAME_MIN,
4321 CFG_ENABLE_WES_MODE_NAME_MAX);
4322 ret = -EINVAL;
4323 goto exit;
4324 }
4325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4326 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
4327
4328 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
4329 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
4330 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304331 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004332 {
4333 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
4334 char extra[32];
4335 tANI_U8 len = 0;
4336
Arif Hussain826d9412013-11-12 16:44:54 -08004337 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05304338 len = VOS_MIN(priv_data.total_len, len + 1);
4339 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4341 "%s: failed to copy data to user buffer", __func__);
4342 ret = -EFAULT;
4343 goto exit;
4344 }
4345 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004346#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004347#ifdef FEATURE_WLAN_LFR
4348 else if (strncmp(command, "SETFASTROAM", 11) == 0)
4349 {
4350 tANI_U8 *value = command;
4351 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
4352
4353 /* Move pointer to ahead of SETFASTROAM<delimiter> */
4354 value = value + 12;
4355 /* Convert the value from ascii to integer */
4356 ret = kstrtou8(value, 10, &lfrMode);
4357 if (ret < 0)
4358 {
4359 /* If the input value is greater than max value of datatype, then also
4360 kstrtou8 fails */
4361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4362 "%s: kstrtou8 failed range [%d - %d]", __func__,
4363 CFG_LFR_FEATURE_ENABLED_MIN,
4364 CFG_LFR_FEATURE_ENABLED_MAX);
4365 ret = -EINVAL;
4366 goto exit;
4367 }
4368
4369 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
4370 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
4371 {
4372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4373 "lfr mode value %d is out of range"
4374 " (Min: %d Max: %d)", lfrMode,
4375 CFG_LFR_FEATURE_ENABLED_MIN,
4376 CFG_LFR_FEATURE_ENABLED_MAX);
4377 ret = -EINVAL;
4378 goto exit;
4379 }
4380
4381 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4382 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
4383
4384 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
4385 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
4386 }
4387#endif
4388#ifdef WLAN_FEATURE_VOWIFI_11R
4389 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
4390 {
4391 tANI_U8 *value = command;
4392 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
4393
4394 /* Move pointer to ahead of SETFASTROAM<delimiter> */
4395 value = value + 18;
4396 /* Convert the value from ascii to integer */
4397 ret = kstrtou8(value, 10, &ft);
4398 if (ret < 0)
4399 {
4400 /* If the input value is greater than max value of datatype, then also
4401 kstrtou8 fails */
4402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4403 "%s: kstrtou8 failed range [%d - %d]", __func__,
4404 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
4405 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
4406 ret = -EINVAL;
4407 goto exit;
4408 }
4409
4410 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
4411 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
4412 {
4413 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4414 "ft mode value %d is out of range"
4415 " (Min: %d Max: %d)", ft,
4416 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
4417 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
4418 ret = -EINVAL;
4419 goto exit;
4420 }
4421
4422 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4423 "%s: Received Command to change ft mode = %d", __func__, ft);
4424
4425 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
4426 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
4427 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304428 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
4429 {
4430 tANI_U8 *value = command;
4431 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304432
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304433 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
4434 value = value + 15;
4435 /* Convert the value from ascii to integer */
4436 ret = kstrtou8(value, 10, &dfsScanMode);
4437 if (ret < 0)
4438 {
4439 /* If the input value is greater than max value of
4440 datatype, then also kstrtou8 fails
4441 */
4442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4443 "%s: kstrtou8 failed range [%d - %d]", __func__,
4444 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
4445 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
4446 ret = -EINVAL;
4447 goto exit;
4448 }
4449
4450 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
4451 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
4452 {
4453 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4454 "dfsScanMode value %d is out of range"
4455 " (Min: %d Max: %d)", dfsScanMode,
4456 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
4457 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
4458 ret = -EINVAL;
4459 goto exit;
4460 }
4461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4462 "%s: Received Command to Set DFS Scan Mode = %d",
4463 __func__, dfsScanMode);
4464
4465 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
4466 }
4467 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
4468 {
4469 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
4470 char extra[32];
4471 tANI_U8 len = 0;
4472
4473 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05304474 len = VOS_MIN(priv_data.total_len, len + 1);
4475 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304476 {
4477 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4478 "%s: failed to copy data to user buffer", __func__);
4479 ret = -EFAULT;
4480 goto exit;
4481 }
4482 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304483 else if (strncmp(command, "FASTREASSOC", 11) == 0)
4484 {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05304485 ret = wlan_hdd_handle_fastreassoc(pAdapter, command);
4486 if (!ret)
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304487 goto exit;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304488 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004489#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004490#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004491 else if (strncmp(command, "SETCCXMODE", 10) == 0)
4492 {
4493 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004494 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004495
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004496 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004497 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004498 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004499 hdd_is_okc_mode_enabled(pHddCtx) &&
4500 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4501 {
4502 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004503 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004504 " hence this operation is not permitted!", __func__);
4505 ret = -EPERM;
4506 goto exit;
4507 }
4508
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004509 /* Move pointer to ahead of SETCCXMODE<delimiter> */
4510 value = value + 11;
4511 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004512 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004513 if (ret < 0)
4514 {
4515 /* If the input value is greater than max value of datatype, then also
4516 kstrtou8 fails */
4517 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4518 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004519 CFG_ESE_FEATURE_ENABLED_MIN,
4520 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004521 ret = -EINVAL;
4522 goto exit;
4523 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004524 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
4525 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004526 {
4527 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004528 "Ese mode value %d is out of range"
4529 " (Min: %d Max: %d)", eseMode,
4530 CFG_ESE_FEATURE_ENABLED_MIN,
4531 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004532 ret = -EINVAL;
4533 goto exit;
4534 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004536 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004537
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004538 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
4539 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004540 }
4541#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004542 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
4543 {
4544 tANI_U8 *value = command;
4545 tANI_BOOLEAN roamScanControl = 0;
4546
4547 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
4548 value = value + 19;
4549 /* Convert the value from ascii to integer */
4550 ret = kstrtou8(value, 10, &roamScanControl);
4551 if (ret < 0)
4552 {
4553 /* If the input value is greater than max value of datatype, then also
4554 kstrtou8 fails */
4555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4556 "%s: kstrtou8 failed ", __func__);
4557 ret = -EINVAL;
4558 goto exit;
4559 }
4560
4561 if (0 != roamScanControl)
4562 {
4563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4564 "roam scan control invalid value = %d",
4565 roamScanControl);
4566 ret = -EINVAL;
4567 goto exit;
4568 }
4569 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4570 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
4571
4572 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
4573 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004574#ifdef FEATURE_WLAN_OKC
4575 else if (strncmp(command, "SETOKCMODE", 10) == 0)
4576 {
4577 tANI_U8 *value = command;
4578 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
4579
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004580 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004581 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004582 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004583 hdd_is_okc_mode_enabled(pHddCtx) &&
4584 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4585 {
4586 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004587 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004588 " hence this operation is not permitted!", __func__);
4589 ret = -EPERM;
4590 goto exit;
4591 }
4592
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004593 /* Move pointer to ahead of SETOKCMODE<delimiter> */
4594 value = value + 11;
4595 /* Convert the value from ascii to integer */
4596 ret = kstrtou8(value, 10, &okcMode);
4597 if (ret < 0)
4598 {
4599 /* If the input value is greater than max value of datatype, then also
4600 kstrtou8 fails */
4601 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4602 "%s: kstrtou8 failed range [%d - %d]", __func__,
4603 CFG_OKC_FEATURE_ENABLED_MIN,
4604 CFG_OKC_FEATURE_ENABLED_MAX);
4605 ret = -EINVAL;
4606 goto exit;
4607 }
4608
4609 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
4610 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
4611 {
4612 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4613 "Okc mode value %d is out of range"
4614 " (Min: %d Max: %d)", okcMode,
4615 CFG_OKC_FEATURE_ENABLED_MIN,
4616 CFG_OKC_FEATURE_ENABLED_MAX);
4617 ret = -EINVAL;
4618 goto exit;
4619 }
4620
4621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4622 "%s: Received Command to change okc mode = %d", __func__, okcMode);
4623
4624 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
4625 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004626#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304627 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004628 {
4629 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
4630 char extra[32];
4631 tANI_U8 len = 0;
4632
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004633 len = scnprintf(extra, sizeof(extra), "%s %d",
4634 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05304635 len = VOS_MIN(priv_data.total_len, len + 1);
4636 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004637 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4638 "%s: failed to copy data to user buffer", __func__);
4639 ret = -EFAULT;
4640 goto exit;
4641 }
4642 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05304643#ifdef WLAN_FEATURE_PACKET_FILTERING
4644 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
4645 {
4646 tANI_U8 filterType = 0;
4647 tANI_U8 *value = command;
4648
4649 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
4650 value = value + 22;
4651
4652 /* Convert the value from ascii to integer */
4653 ret = kstrtou8(value, 10, &filterType);
4654 if (ret < 0)
4655 {
4656 /* If the input value is greater than max value of datatype,
4657 * then also kstrtou8 fails
4658 */
4659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4660 "%s: kstrtou8 failed range ", __func__);
4661 ret = -EINVAL;
4662 goto exit;
4663 }
4664
4665 if (filterType != 0 && filterType != 1)
4666 {
4667 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4668 "%s: Accepted Values are 0 and 1 ", __func__);
4669 ret = -EINVAL;
4670 goto exit;
4671 }
4672 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
4673 pAdapter->sessionId);
4674 }
4675#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304676 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
4677 {
Kiet Lamad161252014-07-22 11:23:32 -07004678 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05304679 int ret;
4680
Kiet Lamad161252014-07-22 11:23:32 -07004681 dhcpPhase = command + 11;
4682 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304683 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05304684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07004685 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05304686
4687 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07004688
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05304689 ret = wlan_hdd_scan_abort(pAdapter);
4690 if (ret < 0)
4691 {
4692 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4693 FL("failed to abort existing scan %d"), ret);
4694 }
4695
Kiet Lamad161252014-07-22 11:23:32 -07004696 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
4697 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304698 }
Kiet Lamad161252014-07-22 11:23:32 -07004699 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304700 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05304701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07004702 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05304703
4704 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07004705
4706 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
4707 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304708 }
4709 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004710 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
4711 {
Abhishek Singh58749d62016-02-03 15:27:20 +05304712 hddLog(LOG1,
4713 FL("making default scan to ACTIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05304714 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004715 }
4716 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
4717 {
Abhishek Singh58749d62016-02-03 15:27:20 +05304718 hddLog(LOG1,
4719 FL("making default scan to PASSIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05304720 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004721 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304722 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
4723 {
4724 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4725 char extra[32];
4726 tANI_U8 len = 0;
4727
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05304728 memset(extra, 0, sizeof(extra));
4729 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05304730 len = VOS_MIN(priv_data.total_len, len + 1);
4731 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4733 "%s: failed to copy data to user buffer", __func__);
4734 ret = -EFAULT;
4735 goto exit;
4736 }
4737 ret = len;
4738 }
4739 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
4740 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05304741 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304742 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004743 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
4744 {
4745 tANI_U8 filterType = 0;
4746 tANI_U8 *value;
4747 value = command + 9;
4748
4749 /* Convert the value from ascii to integer */
4750 ret = kstrtou8(value, 10, &filterType);
4751 if (ret < 0)
4752 {
4753 /* If the input value is greater than max value of datatype,
4754 * then also kstrtou8 fails
4755 */
4756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4757 "%s: kstrtou8 failed range ", __func__);
4758 ret = -EINVAL;
4759 goto exit;
4760 }
4761 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
4762 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
4763 {
4764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4765 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
4766 " 2-Sink ", __func__);
4767 ret = -EINVAL;
4768 goto exit;
4769 }
4770 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
4771 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05304772 pScanInfo = &pHddCtx->scan_info;
4773 if (filterType && pScanInfo != NULL &&
4774 pHddCtx->scan_info.mScanPending)
4775 {
4776 /*Miracast Session started. Abort Scan */
4777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4778 "%s, Aborting Scan For Miracast",__func__);
4779 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
4780 eCSR_SCAN_ABORT_DEFAULT);
4781 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004782 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05304783 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004784 }
Leo Chang614d2072013-08-22 14:59:44 -07004785 else if (strncmp(command, "SETMCRATE", 9) == 0)
4786 {
Leo Chang614d2072013-08-22 14:59:44 -07004787 tANI_U8 *value = command;
4788 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07004789 tSirRateUpdateInd *rateUpdate;
4790 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07004791
4792 /* Only valid for SAP mode */
4793 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
4794 {
4795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4796 "%s: SAP mode is not running", __func__);
4797 ret = -EFAULT;
4798 goto exit;
4799 }
4800
4801 /* Move pointer to ahead of SETMCRATE<delimiter> */
4802 /* input value is in units of hundred kbps */
4803 value = value + 10;
4804 /* Convert the value from ascii to integer, decimal base */
4805 ret = kstrtouint(value, 10, &targetRate);
4806
Leo Chang1f98cbd2013-10-17 15:03:52 -07004807 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
4808 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07004809 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07004810 hddLog(VOS_TRACE_LEVEL_ERROR,
4811 "%s: SETMCRATE indication alloc fail", __func__);
4812 ret = -EFAULT;
4813 goto exit;
4814 }
4815 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
4816
4817 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4818 "MC Target rate %d", targetRate);
4819 /* Ignore unicast */
4820 rateUpdate->ucastDataRate = -1;
4821 rateUpdate->mcastDataRate24GHz = targetRate;
4822 rateUpdate->mcastDataRate5GHz = targetRate;
4823 rateUpdate->mcastDataRate24GHzTxFlag = 0;
4824 rateUpdate->mcastDataRate5GHzTxFlag = 0;
4825 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
4826 if (eHAL_STATUS_SUCCESS != status)
4827 {
4828 hddLog(VOS_TRACE_LEVEL_ERROR,
4829 "%s: SET_MC_RATE failed", __func__);
4830 vos_mem_free(rateUpdate);
4831 ret = -EFAULT;
4832 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07004833 }
4834 }
Rajeev79dbe4c2013-10-05 11:03:42 +05304835#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08004836 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05304837 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08004838 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05304839 }
4840#endif
Abhishek Singh00b71972016-01-07 10:51:04 +05304841#ifdef WLAN_FEATURE_RMC
4842 else if ((strncasecmp(command, "SETIBSSBEACONOUIDATA", 20) == 0) &&
4843 (WLAN_HDD_IBSS == pAdapter->device_mode))
4844 {
4845 int i = 0;
4846 tANI_U8 *ibss_ie;
4847 tANI_U32 command_len;
4848 tANI_U8 *value = command;
4849 tHalHandle hHal = pHddCtx->hHal;
4850 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4851 tANI_U32 ibss_ie_length;
4852 tANI_U32 len, present;
4853 tANI_U8 *addIE;
4854 tANI_U8 *addIEData;
4855
4856 hddLog(LOG1,
4857 FL(" received command %s"),((char *) value));
4858 /* validate argument of command */
4859 if (strlen(value) <= 21)
4860 {
4861 hddLog(LOGE,
4862 FL("No arguements in command length %zu"), strlen(value));
4863 ret = -EFAULT;
4864 goto exit;
4865 }
4866
4867 /* moving to arguments of commands */
4868 value = value + 21;
4869 command_len = strlen(value);
4870
4871 /* oui_data can't be less than 3 bytes */
4872 if (command_len <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH))
4873 {
4874 hddLog(LOGE,
4875 FL("Invalid SETIBSSBEACONOUIDATA command length %d"),
4876 command_len);
4877 ret = -EFAULT;
4878 goto exit;
4879 }
4880 ibss_ie = vos_mem_malloc(command_len);
4881 if (!ibss_ie) {
4882 hddLog(LOGE,
4883 FL("Could not allocate memory for command length %d"),
4884 command_len);
4885 ret = -ENOMEM;
4886 goto exit;
4887 }
4888 vos_mem_zero(ibss_ie, command_len);
4889
4890 ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie,
4891 command_len);
4892 if (ibss_ie_length < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
4893 hddLog(LOGE, FL("Could not parse command %s return length %d"),
4894 value, ibss_ie_length);
4895 ret = -EFAULT;
4896 vos_mem_free(ibss_ie);
4897 goto exit;
4898 }
4899
4900 hddLog(LOG1, FL("ibss_ie length %d ibss_ie:"), ibss_ie_length);
4901 while (i < ibss_ie_length)
4902 hddLog(LOG1, FL("0x%x"), ibss_ie[i++]);
4903
4904 /* Populate Vendor IE in Beacon */
4905 if ((ccmCfgGetInt(hHal,
4906 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
4907 &present)) != eHAL_STATUS_SUCCESS)
4908 {
4909 hddLog(LOGE,
4910 FL("unable to ftch WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
4911 ret = -EFAULT;
4912 vos_mem_free(ibss_ie);
4913 goto exit;
4914 }
4915
4916 addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
4917 if (!addIE) {
4918 hddLog(LOGE,
4919 FL("Could not allocate memory for command length %d"),
4920 command_len);
4921 vos_mem_free(ibss_ie);
4922 ret = -ENOMEM;
4923 goto exit;
4924 }
4925 vos_mem_zero(addIE, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
4926
4927 if (present)
4928 {
4929 if ((wlan_cfgGetStrLen(pMac,
4930 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &len)) != eSIR_SUCCESS)
4931 {
4932 hddLog(LOGE,
4933 FL("unable to fetch WNI_CFG_PROBE_RSP_BCN_ADDNIE_LEN"));
4934 ret = -EFAULT;
4935 vos_mem_free(ibss_ie);
4936 vos_mem_free(addIE);
4937 goto exit;
4938 }
4939
4940 if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
4941 ((len + ibss_ie_length) <=
4942 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN))
4943 {
4944 if ((ccmCfgGetStr(hHal,
4945 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, &len))
4946 != eHAL_STATUS_SUCCESS)
4947 {
4948 hddLog(LOGE,
4949 FL("unable to fetch WNI_PROBE_RSP_BCN_ADDNIE_DATA"));
4950 ret = -EFAULT;
4951 vos_mem_free(ibss_ie);
4952 vos_mem_free(addIE);
4953 goto exit;
4954 }
4955 else
4956 {
4957 /* Curruntly only WPA IE is added before Vendor IE
4958 * so we can blindly place the Vendor IE after WPA
4959 * IE. If no WPA IE found replace all with Vendor IE.
4960 */
4961 len = hdd_find_ibss_wpa_ie_pos(addIE, len);
4962 }
4963 }
4964 else
4965 {
4966 hddLog(LOGE,
4967 FL("IE len exceed limit len %d,ibss_ie_length %d "),
4968 len, ibss_ie_length);
4969 ret = -EFAULT;
4970 vos_mem_free(addIE);
4971 vos_mem_free(ibss_ie);
4972 goto exit;
4973 }
4974 }
4975 else {
4976 len = 0;
4977 }
4978
4979 vos_mem_copy (addIE + len , ibss_ie, ibss_ie_length);
4980 len += ibss_ie_length;
4981
4982 if (ccmCfgSetStr(hHal,
4983 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, len, NULL,
4984 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
4985 {
4986 hddLog(LOGE,
4987 FL("unable to set WNI_CFG_PRBE_RSP_BCN_ADDNIE_DATA"));
4988 ret = -EFAULT;
4989 vos_mem_free(ibss_ie);
4990 vos_mem_free(addIE);
4991 goto exit;
4992 }
4993 vos_mem_free(addIE);
4994 if (ccmCfgSetInt(hHal,
4995 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
4996 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
4997 {
4998 hddLog(LOGE,
4999 FL("unble to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
5000 ret = -EFAULT;
5001 vos_mem_free(ibss_ie);
5002 goto exit;
5003 }
5004
5005 /* Populate Vendor IE in probe resp */
5006 if ((ccmCfgGetInt(hHal,
5007 WNI_CFG_PROBE_RSP_ADDNIE_FLAG,
5008 &present)) != eHAL_STATUS_SUCCESS)
5009 {
5010 hddLog(LOGE,
5011 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
5012 ret = -EFAULT;
5013 vos_mem_free(ibss_ie);
5014 goto exit;
5015 }
5016
5017 addIEData = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
5018 if (!addIEData) {
5019 hddLog(LOGE,
5020 FL("Could not allocate memory for command length %d"),
5021 command_len);
5022 vos_mem_free(ibss_ie);
5023 ret = -ENOMEM;
5024 goto exit;
5025 }
5026 vos_mem_zero(addIEData, WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
5027
5028 if (present) {
5029 if (eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
5030 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &len)) {
5031 hddLog(LOGE,
5032 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
5033 ret = -EFAULT;
5034 vos_mem_free(ibss_ie);
5035 vos_mem_free(addIEData);
5036 goto exit;
5037 }
5038 if (len < WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && len &&
5039 (ibss_ie_length + len) <=
5040 WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN) {
5041
5042 if ((ccmCfgGetStr(hHal,
5043 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, addIEData, &len))
5044 != eHAL_STATUS_SUCCESS) {
5045 hddLog(LOGE,
5046 FL("unable fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
5047 ret = -EFAULT;
5048 vos_mem_free(ibss_ie);
5049 vos_mem_free(addIEData);
5050 goto exit;
5051 }
5052 else {
5053 /* Curruntly only WPA IE is added before Vendor IE
5054 * so we can blindly place the Vendor IE after WPA
5055 * IE. If no WPA IE found replace all with Vendor IE.
5056 */
5057 len = hdd_find_ibss_wpa_ie_pos(addIEData, len);
5058 }
5059 }
5060 else
5061 {
5062 hddLog(LOGE,
5063 FL("IE len exceed limit len %d,ibss_ie_length %d "),
5064 len, ibss_ie_length);
5065 ret = -EFAULT;
5066 vos_mem_free(addIEData);
5067 vos_mem_free(ibss_ie);
5068 goto exit;
5069 }
5070 } /* probe rsp ADD IE present */
5071 else {
5072 /* probe rsp add IE is not present */
5073 len = 0;
5074 }
5075
5076 vos_mem_copy(addIEData +len , ibss_ie, ibss_ie_length);
5077 len += ibss_ie_length;
5078
5079 vos_mem_free(ibss_ie);
5080
5081 if (ccmCfgSetStr(hHal,
5082 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
5083 (tANI_U8*)(addIEData),
5084 len, NULL,
5085 eANI_BOOLEAN_FALSE)
5086 == eHAL_STATUS_FAILURE) {
5087 hddLog(LOGE,
5088 FL("unable to copy to WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
5089 ret = -EFAULT;
5090 vos_mem_free(addIEData);
5091 goto exit;
5092 }
5093 vos_mem_free(addIEData);
5094 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
5095 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5096 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5097 {
5098 hddLog(LOGE,
5099 FL("unable to copy WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
5100 ret = -EFAULT;
5101 goto exit;
5102 }
5103 }
5104 else if (strncasecmp(command, "SETRMCENABLE", 12) == 0)
5105 {
5106 tANI_U8 *value = command;
5107 tANI_U8 ucRmcEnable = 0;
5108 int status;
5109
5110 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
5111 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
5112 {
5113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5114 "Received SETRMCENABLE command in invalid mode %d "
5115 "SETRMCENABLE command is only allowed in IBSS or SOFTAP mode",
5116 pAdapter->device_mode);
5117 ret = -EINVAL;
5118 goto exit;
5119 }
5120
5121 status = hdd_parse_setrmcenable_command(value, &ucRmcEnable);
5122 if (status)
5123 {
5124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5125 "Invalid SETRMCENABLE command ");
5126 ret = -EINVAL;
5127 goto exit;
5128 }
5129
5130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5131 "%s: ucRmcEnable %d ", __func__, ucRmcEnable);
5132
5133 if (TRUE == ucRmcEnable)
5134 {
5135 status = sme_EnableRMC( (tHalHandle)(pHddCtx->hHal),
5136 pAdapter->sessionId );
5137 }
5138 else if(FALSE == ucRmcEnable)
5139 {
5140 status = sme_DisableRMC( (tHalHandle)(pHddCtx->hHal),
5141 pAdapter->sessionId );
5142 }
5143 else
5144 {
5145 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5146 "Invalid SETRMCENABLE command %d", ucRmcEnable);
5147 ret = -EINVAL;
5148 goto exit;
5149 }
5150
5151 if (VOS_STATUS_SUCCESS != status)
5152 {
5153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5154 "%s: SETRMC %d failed status %d", __func__, ucRmcEnable,
5155 status);
5156 ret = -EINVAL;
5157 goto exit;
5158 }
5159 }
5160 else if (strncasecmp(command, "SETRMCACTIONPERIOD", 18) == 0)
5161 {
5162 tANI_U8 *value = command;
5163 tANI_U32 uActionPeriod = 0;
5164 int status;
5165
5166 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
5167 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
5168 {
5169 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5170 "Received SETRMC command in invalid mode %d "
5171 "SETRMC command is only allowed in IBSS or SOFTAP mode",
5172 pAdapter->device_mode);
5173 ret = -EINVAL;
5174 goto exit;
5175 }
5176
5177 status = hdd_parse_setrmcactionperiod_command(value, &uActionPeriod);
5178 if (status)
5179 {
5180 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5181 "Invalid SETRMCACTIONPERIOD command ");
5182 ret = -EINVAL;
5183 goto exit;
5184 }
5185
5186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5187 "%s: uActionPeriod %d ", __func__, uActionPeriod);
5188
5189 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
5190 uActionPeriod, NULL, eANI_BOOLEAN_FALSE))
5191 {
5192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5193 "%s: Could not set SETRMCACTIONPERIOD %d", __func__, uActionPeriod);
5194 ret = -EINVAL;
5195 goto exit;
5196 }
5197
5198 }
5199 else if (strncasecmp(command, "GETIBSSPEERINFOALL", 18) == 0)
5200 {
5201 /* Peer Info All Command */
5202 int status = eHAL_STATUS_SUCCESS;
5203 hdd_station_ctx_t *pHddStaCtx = NULL;
5204 char *extra = NULL;
5205 int idx = 0, length = 0;
5206 v_MACADDR_t *macAddr;
5207 v_U32_t txRateMbps = 0, numOfBytestoPrint = 0;
5208
5209 if (WLAN_HDD_IBSS == pAdapter->device_mode)
5210 {
5211 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5212 }
5213 else
5214 {
5215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5216 "%s: pAdapter is not valid for this device mode",
5217 __func__);
5218 ret = -EINVAL;
5219 goto exit;
5220 }
5221
5222 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5223 "%s: Received GETIBSSPEERINFOALL Command", __func__);
5224
5225
5226 /* Handle the command */
5227 status = hdd_cfg80211_get_ibss_peer_info_all(pAdapter);
5228 if (VOS_STATUS_SUCCESS == status)
5229 {
5230 /* The variable extra needed to be allocated on the heap since
5231 * amount of memory required to copy the data for 32 devices
5232 * exceeds the size of 1024 bytes of default stack size. On
5233 * 64 bit devices, the default max stack size of 2048 bytes
5234 */
5235 extra = kmalloc(WLAN_MAX_BUF_SIZE, GFP_KERNEL);
5236
5237 if (NULL == extra)
5238 {
5239 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5240 "%s:kmalloc failed", __func__);
5241 ret = -EINVAL;
5242 goto exit;
5243 }
5244
5245 /* Copy number of stations */
5246 length = scnprintf( extra, WLAN_MAX_BUF_SIZE, "%d ",
5247 pHddStaCtx->ibss_peer_info.numIBSSPeers);
5248 numOfBytestoPrint = length;
5249 for (idx = 0; idx < pHddStaCtx->ibss_peer_info.numIBSSPeers; idx++)
5250 {
5251 macAddr =
5252 hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
5253 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
5254 if (NULL != macAddr)
5255 {
5256 txRateMbps =
5257 ((pHddStaCtx->ibss_peer_info.ibssPeerList[idx].txRate)*500*1000)/1000000;
5258
5259 length += scnprintf( (extra + length), WLAN_MAX_BUF_SIZE - length,
5260 "%02x:%02x:%02x:%02x:%02x:%02x %d %d ",
5261 macAddr->bytes[0], macAddr->bytes[1], macAddr->bytes[2],
5262 macAddr->bytes[3], macAddr->bytes[4], macAddr->bytes[5],
5263 (int)txRateMbps,
5264 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[idx].rssi);
5265 }
5266 else
5267 {
5268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5269 "%s: MAC ADDR is NULL for staIdx: %d", __func__,
5270 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
5271 }
5272
5273 /*
5274 * VOS_TRACE() macro has limitation of 512 bytes for the print
5275 * buffer. Hence printing the data in two chunks. The first chunk
5276 * will have the data for 16 devices and the second chunk will
5277 * have the rest.
5278 */
5279 if (idx < NUM_OF_STA_DATA_TO_PRINT)
5280 {
5281 numOfBytestoPrint = length;
5282 }
5283 }
5284
5285 /*
5286 * Copy the data back into buffer, if the data to copy is
5287 * morethan 512 bytes than we will split the data and do
5288 * it in two shots
5289 */
5290 if (copy_to_user(priv_data.buf, extra, numOfBytestoPrint))
5291 {
5292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5293 "%s: Copy into user data buffer failed ", __func__);
5294 ret = -EFAULT;
5295 kfree(extra);
5296 goto exit;
5297 }
5298 priv_data.buf[numOfBytestoPrint] = '\0';
5299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5300 "%s", priv_data.buf);
5301
5302 if (length > numOfBytestoPrint)
5303 {
5304 if (copy_to_user(priv_data.buf + numOfBytestoPrint,
5305 extra + numOfBytestoPrint,
5306 length - numOfBytestoPrint + 1))
5307 {
5308 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5309 "%s: Copy into user data buffer failed ", __func__);
5310 ret = -EFAULT;
5311 kfree(extra);
5312 goto exit;
5313 }
5314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5315 "%s", &priv_data.buf[numOfBytestoPrint]);
5316 }
5317
5318 /* Free temporary buffer */
5319 kfree(extra);
5320 }
5321
5322 else
5323 {
5324 /* Command failed, log error */
5325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5326 "%s: GETIBSSPEERINFOALL command failed with status code %d",
5327 __func__, status);
5328 ret = -EINVAL;
5329 goto exit;
5330 }
5331 ret = 0;
5332 }
5333 else if(strncasecmp(command, "GETIBSSPEERINFO", 15) == 0)
5334 {
5335 /* Peer Info <Peer Addr> command */
5336 tANI_U8 *value = command;
5337 VOS_STATUS status;
5338 hdd_station_ctx_t *pHddStaCtx = NULL;
5339 char extra[128] = { 0 };
5340 v_U32_t length = 0;
5341 v_U8_t staIdx = 0;
5342 v_U32_t txRateMbps = 0;
5343 v_MACADDR_t peerMacAddr;
5344
5345 if (WLAN_HDD_IBSS == pAdapter->device_mode)
5346 {
5347 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5348 }
5349 else
5350 {
5351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5352 "%s: pAdapter is not valid for this device mode",
5353 __func__);
5354 ret = -EINVAL;
5355 goto exit;
5356 }
5357
5358 /* if there are no peers, no need to continue with the command */
5359 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5360 "%s: Received GETIBSSPEERINFO Command", __func__);
5361
5362 if (eConnectionState_IbssConnected != pHddStaCtx->conn_info.connState)
5363 {
5364 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5365 "%s:No IBSS Peers coalesced", __func__);
5366 ret = -EINVAL;
5367 goto exit;
5368 }
5369
5370 /* Parse the incoming command buffer */
5371 status = hdd_parse_get_ibss_peer_info(value, &peerMacAddr);
5372 if (VOS_STATUS_SUCCESS != status)
5373 {
5374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5375 "%s: Invalid GETIBSSPEERINFO command", __func__);
5376 ret = -EINVAL;
5377 goto exit;
5378 }
5379
5380 /* Get station index for the peer mac address */
5381 hdd_Ibss_GetStaId(pHddStaCtx, &peerMacAddr, &staIdx);
5382
5383 if (staIdx > HDD_MAX_NUM_IBSS_STA)
5384 {
5385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5386 "%s: Invalid StaIdx %d returned", __func__, staIdx);
5387 ret = -EINVAL;
5388 goto exit;
5389 }
5390
5391 /* Handle the command */
5392 status = hdd_cfg80211_get_ibss_peer_info(pAdapter, staIdx);
5393 if (VOS_STATUS_SUCCESS == status)
5394 {
5395 v_U32_t txRate = pHddStaCtx->ibss_peer_info.ibssPeerList[0].txRate;
5396 txRateMbps = (txRate * 500 * 1000)/1000000;
5397
5398 length = scnprintf( extra, sizeof(extra), "%d %d", (int)txRateMbps,
5399 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[0].rssi);
5400
5401 /* Copy the data back into buffer */
5402 if (copy_to_user(priv_data.buf, &extra, length+ 1))
5403 {
5404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5405 "%s: copy data to user buffer failed GETIBSSPEERINFO command",
5406 __func__);
5407 ret = -EFAULT;
5408 goto exit;
5409 }
5410 }
5411 else
5412 {
5413 /* Command failed, log error */
5414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5415 "%s: GETIBSSPEERINFO command failed with status code %d",
5416 __func__, status);
5417 ret = -EINVAL;
5418 goto exit;
5419 }
5420
5421 /* Success ! */
5422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5423 "%s", priv_data.buf);
5424 ret = 0;
5425 }
5426 else if (strncasecmp(command, "SETRMCTXRATE", 12) == 0)
5427 {
5428 tANI_U8 *value = command;
5429 tANI_U32 uRate = 0;
5430 tTxrateinfoflags txFlags = 0;
5431 tSirRateUpdateInd *rateUpdateParams;
5432 int status;
5433
5434 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
5435 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
5436 {
5437 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5438 "Received SETRMCTXRATE command in invalid mode %d "
5439 "SETRMC command is only allowed in IBSS or SOFTAP mode",
5440 pAdapter->device_mode);
5441 ret = -EINVAL;
5442 goto exit;
5443 }
5444
5445 status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags);
5446 if (status)
5447 {
5448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5449 "Invalid SETRMCTXRATE command ");
5450 ret = -EINVAL;
5451 goto exit;
5452 }
5453
5454 rateUpdateParams = vos_mem_malloc(sizeof(tSirRateUpdateInd));
5455 if (NULL == rateUpdateParams)
5456 {
5457 ret = -EINVAL;
5458 goto exit;
5459 }
5460
5461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5462 "%s: uRate %d ", __func__, uRate);
5463
5464 vos_mem_zero(rateUpdateParams, sizeof(tSirRateUpdateInd ));
5465
5466 /* -1 implies ignore this param */
5467 rateUpdateParams->ucastDataRate = -1;
5468
5469 /*
5470 * Fill the user specifieed RMC rate param
5471 * and the derived tx flags.
5472 */
5473 rateUpdateParams->rmcDataRate = uRate;
5474 rateUpdateParams->rmcDataRateTxFlag = txFlags;
5475
5476 status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), rateUpdateParams);
5477 }
5478 else if (strncasecmp(command, "SETIBSSTXFAILEVENT", 18) == 0 )
5479 {
5480 char *value;
5481 tANI_U8 tx_fail_count = 0;
5482 tANI_U16 pid = 0;
5483
5484 value = command;
5485
5486 ret = hdd_ParseIBSSTXFailEventParams(value, &tx_fail_count, &pid);
5487
5488 if (0 != ret)
5489 {
5490 hddLog(VOS_TRACE_LEVEL_INFO,
5491 "%s: Failed to parse SETIBSSTXFAILEVENT arguments",
5492 __func__);
5493 goto exit;
5494 }
5495
5496 hddLog(VOS_TRACE_LEVEL_INFO, "%s: tx_fail_cnt=%hhu, pid=%hu",
5497 __func__, tx_fail_count, pid);
5498
5499 if (0 == tx_fail_count)
5500 {
5501 // Disable TX Fail Indication
5502 if (eHAL_STATUS_SUCCESS ==
5503 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
5504 tx_fail_count,
5505 NULL))
5506 {
5507 cesium_pid = 0;
5508 }
5509 else
5510 {
5511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5512 "%s: failed to disable TX Fail Event ", __func__);
5513 ret = -EINVAL;
5514 }
5515 }
5516 else
5517 {
5518 if (eHAL_STATUS_SUCCESS ==
5519 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
5520 tx_fail_count,
5521 (void*)hdd_tx_fail_ind_callback))
5522 {
5523 cesium_pid = pid;
5524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5525 "%s: Registered Cesium pid %u", __func__,
5526 cesium_pid);
5527 }
5528 else
5529 {
5530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5531 "%s: Failed to enable TX Fail Monitoring", __func__);
5532 ret = -EINVAL;
5533 }
5534 }
5535 }
5536
5537#endif /* WLAN_FEATURE_RMC */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005538#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005539 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
5540 {
5541 tANI_U8 *value = command;
5542 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
5543 tANI_U8 numChannels = 0;
5544 eHalStatus status = eHAL_STATUS_SUCCESS;
5545
5546 status = hdd_parse_channellist(value, ChannelList, &numChannels);
5547 if (eHAL_STATUS_SUCCESS != status)
5548 {
5549 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5550 "%s: Failed to parse channel list information", __func__);
5551 ret = -EINVAL;
5552 goto exit;
5553 }
5554
5555 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
5556 {
5557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5558 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
5559 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
5560 ret = -EINVAL;
5561 goto exit;
5562 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005563 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005564 ChannelList,
5565 numChannels);
5566 if (eHAL_STATUS_SUCCESS != status)
5567 {
5568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5569 "%s: Failed to update channel list information", __func__);
5570 ret = -EINVAL;
5571 goto exit;
5572 }
5573 }
5574 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
5575 {
5576 tANI_U8 *value = command;
5577 char extra[128] = {0};
5578 int len = 0;
5579 tANI_U8 tid = 0;
5580 hdd_station_ctx_t *pHddStaCtx = NULL;
5581 tAniTrafStrmMetrics tsmMetrics;
5582 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5583
5584 /* if not associated, return error */
5585 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
5586 {
5587 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
5588 ret = -EINVAL;
5589 goto exit;
5590 }
5591
5592 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
5593 value = value + 12;
5594 /* Convert the value from ascii to integer */
5595 ret = kstrtou8(value, 10, &tid);
5596 if (ret < 0)
5597 {
5598 /* If the input value is greater than max value of datatype, then also
5599 kstrtou8 fails */
5600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5601 "%s: kstrtou8 failed range [%d - %d]", __func__,
5602 TID_MIN_VALUE,
5603 TID_MAX_VALUE);
5604 ret = -EINVAL;
5605 goto exit;
5606 }
5607
5608 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
5609 {
5610 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5611 "tid value %d is out of range"
5612 " (Min: %d Max: %d)", tid,
5613 TID_MIN_VALUE,
5614 TID_MAX_VALUE);
5615 ret = -EINVAL;
5616 goto exit;
5617 }
5618
5619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5620 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
5621
5622 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
5623 {
5624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5625 "%s: failed to get tsm stats", __func__);
5626 ret = -EFAULT;
5627 goto exit;
5628 }
5629
5630 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5631 "UplinkPktQueueDly(%d)\n"
5632 "UplinkPktQueueDlyHist[0](%d)\n"
5633 "UplinkPktQueueDlyHist[1](%d)\n"
5634 "UplinkPktQueueDlyHist[2](%d)\n"
5635 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05305636 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005637 "UplinkPktLoss(%d)\n"
5638 "UplinkPktCount(%d)\n"
5639 "RoamingCount(%d)\n"
5640 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
5641 tsmMetrics.UplinkPktQueueDlyHist[0],
5642 tsmMetrics.UplinkPktQueueDlyHist[1],
5643 tsmMetrics.UplinkPktQueueDlyHist[2],
5644 tsmMetrics.UplinkPktQueueDlyHist[3],
5645 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
5646 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
5647
5648 /* Output TSM stats is of the format
5649 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
5650 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005651 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005652 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
5653 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
5654 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
5655 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
5656 tsmMetrics.RoamingDly);
5657
Ratnam Rachurid53009c2015-08-07 13:59:00 +05305658 len = VOS_MIN(priv_data.total_len, len + 1);
5659 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5661 "%s: failed to copy data to user buffer", __func__);
5662 ret = -EFAULT;
5663 goto exit;
5664 }
5665 }
5666 else if (strncmp(command, "SETCCKMIE", 9) == 0)
5667 {
5668 tANI_U8 *value = command;
5669 tANI_U8 *cckmIe = NULL;
5670 tANI_U8 cckmIeLen = 0;
5671 eHalStatus status = eHAL_STATUS_SUCCESS;
5672
5673 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
5674 if (eHAL_STATUS_SUCCESS != status)
5675 {
5676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5677 "%s: Failed to parse cckm ie data", __func__);
5678 ret = -EINVAL;
5679 goto exit;
5680 }
5681
5682 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
5683 {
5684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5685 "%s: CCKM Ie input length is more than max[%d]", __func__,
5686 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08005687 vos_mem_free(cckmIe);
5688 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005689 ret = -EINVAL;
5690 goto exit;
5691 }
5692 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08005693 vos_mem_free(cckmIe);
5694 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005695 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005696 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
5697 {
5698 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005699 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005700 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07005701
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005702 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005703 if (eHAL_STATUS_SUCCESS != status)
5704 {
5705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005706 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005707 ret = -EINVAL;
5708 goto exit;
5709 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07005710 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
5711 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
5712 hdd_indicateEseBcnReportNoResults (pAdapter,
5713 eseBcnReq.bcnReq[0].measurementToken,
5714 0x02, //BIT(1) set for measurement done
5715 0); // no BSS
5716 goto exit;
5717 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005718
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005719 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
5720 if (eHAL_STATUS_SUCCESS != status)
5721 {
5722 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5723 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
5724 ret = -EINVAL;
5725 goto exit;
5726 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005727 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005728#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05305729 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
5730 {
5731 eHalStatus status;
5732 char buf[32], len;
5733 long waitRet;
5734 bcnMissRateContext_t getBcnMissRateCtx;
5735
5736 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5737
5738 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
5739 {
5740 hddLog(VOS_TRACE_LEVEL_WARN,
5741 FL("GETBCNMISSRATE: STA is not in connected state"));
5742 ret = -1;
5743 goto exit;
5744 }
5745
5746 init_completion(&(getBcnMissRateCtx.completion));
5747 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
5748
5749 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
5750 pAdapter->sessionId,
5751 (void *)getBcnMissRateCB,
5752 (void *)(&getBcnMissRateCtx));
5753 if( eHAL_STATUS_SUCCESS != status)
5754 {
5755 hddLog(VOS_TRACE_LEVEL_INFO,
5756 FL("GETBCNMISSRATE: fail to post WDA cmd"));
5757 ret = -EINVAL;
5758 goto exit;
5759 }
5760
5761 waitRet = wait_for_completion_interruptible_timeout
5762 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
5763 if(waitRet <= 0)
5764 {
5765 hddLog(VOS_TRACE_LEVEL_ERROR,
5766 FL("failed to wait on bcnMissRateComp %d"), ret);
5767
5768 //Make magic number to zero so that callback is not called.
5769 spin_lock(&hdd_context_lock);
5770 getBcnMissRateCtx.magic = 0x0;
5771 spin_unlock(&hdd_context_lock);
5772 ret = -EINVAL;
5773 goto exit;
5774 }
5775
5776 hddLog(VOS_TRACE_LEVEL_INFO,
5777 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
5778
5779 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
5780 if (copy_to_user(priv_data.buf, &buf, len + 1))
5781 {
5782 hddLog(VOS_TRACE_LEVEL_ERROR,
5783 "%s: failed to copy data to user buffer", __func__);
5784 ret = -EFAULT;
5785 goto exit;
5786 }
5787 ret = len;
5788 }
Atul Mittal87ec2422014-09-24 13:12:50 +05305789#ifdef FEATURE_WLAN_TDLS
5790 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
5791 tANI_U8 *value = command;
5792 int set_value;
5793 /* Move pointer to ahead of TDLSOFFCH*/
5794 value += 26;
c_manjeebbc40212015-12-08 13:52:59 +05305795 if (!(sscanf(value, "%d", &set_value))) {
5796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5797 FL("No input identified"));
5798 ret = -EINVAL;
5799 goto exit;
5800 }
5801
Atul Mittal87ec2422014-09-24 13:12:50 +05305802 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5803 "%s: Tdls offchannel offset:%d",
5804 __func__, set_value);
5805 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
5806 if (ret < 0)
5807 {
5808 ret = -EINVAL;
5809 goto exit;
5810 }
5811
5812 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
5813 tANI_U8 *value = command;
5814 int set_value;
5815 /* Move pointer to ahead of tdlsoffchnmode*/
5816 value += 18;
c_manjee82323892015-12-08 12:40:34 +05305817 ret = sscanf(value, "%d", &set_value);
5818 if (ret != 1) {
5819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5820 FL("No input identified"));
5821 ret = -EINVAL;
5822 goto exit;
5823 }
Atul Mittal87ec2422014-09-24 13:12:50 +05305824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5825 "%s: Tdls offchannel mode:%d",
5826 __func__, set_value);
5827 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
5828 if (ret < 0)
5829 {
5830 ret = -EINVAL;
5831 goto exit;
5832 }
5833 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
5834 tANI_U8 *value = command;
5835 int set_value;
5836 /* Move pointer to ahead of TDLSOFFCH*/
5837 value += 14;
c_manjeef6ccaf52015-12-08 11:52:11 +05305838 ret = sscanf(value, "%d", &set_value);
5839 if (ret != 1) {
5840 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5841 "Wrong value is given for hdd_set_tdls_offchannel");
5842 ret = -EINVAL;
5843 goto exit;
5844 }
5845
Atul Mittal87ec2422014-09-24 13:12:50 +05305846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5847 "%s: Tdls offchannel num: %d",
5848 __func__, set_value);
5849 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
5850 if (ret < 0)
5851 {
5852 ret = -EINVAL;
5853 goto exit;
5854 }
5855 }
5856#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05305857 else if (strncmp(command, "GETFWSTATS", 10) == 0)
5858 {
5859 eHalStatus status;
5860 char *buf = NULL;
5861 char len;
5862 long waitRet;
5863 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05305864 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05305865 tANI_U8 *ptr = command;
5866 int stats = *(ptr + 11) - '0';
5867
5868 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
5869 if (!IS_FEATURE_FW_STATS_ENABLE)
5870 {
5871 hddLog(VOS_TRACE_LEVEL_INFO,
5872 FL("Get Firmware stats feature not supported"));
5873 ret = -EINVAL;
5874 goto exit;
5875 }
5876
5877 if (FW_STATS_MAX <= stats || 0 >= stats)
5878 {
5879 hddLog(VOS_TRACE_LEVEL_INFO,
5880 FL(" stats %d not supported"),stats);
5881 ret = -EINVAL;
5882 goto exit;
5883 }
5884
5885 init_completion(&(fwStatsCtx.completion));
5886 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
5887 fwStatsCtx.pAdapter = pAdapter;
5888 fwStatsRsp->type = 0;
5889 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05305890 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05305891 if (eHAL_STATUS_SUCCESS != status)
5892 {
5893 hddLog(VOS_TRACE_LEVEL_ERROR,
5894 FL(" fail to post WDA cmd status = %d"), status);
5895 ret = -EINVAL;
5896 goto exit;
5897 }
5898 waitRet = wait_for_completion_timeout
5899 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
5900 if (waitRet <= 0)
5901 {
5902 hddLog(VOS_TRACE_LEVEL_ERROR,
5903 FL("failed to wait on GwtFwstats"));
5904 //Make magic number to zero so that callback is not executed.
5905 spin_lock(&hdd_context_lock);
5906 fwStatsCtx.magic = 0x0;
5907 spin_unlock(&hdd_context_lock);
5908 ret = -EINVAL;
5909 goto exit;
5910 }
5911 if (fwStatsRsp->type)
5912 {
5913 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
5914 if (!buf)
5915 {
5916 hddLog(VOS_TRACE_LEVEL_ERROR,
5917 FL(" failed to allocate memory"));
5918 ret = -ENOMEM;
5919 goto exit;
5920 }
5921 switch( fwStatsRsp->type )
5922 {
5923 case FW_UBSP_STATS:
5924 {
5925 len = snprintf(buf, FW_STATE_RSP_LEN,
5926 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05305927 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
5928 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05305929 }
5930 break;
5931 default:
5932 {
5933 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
5934 ret = -EFAULT;
5935 kfree(buf);
5936 goto exit;
5937 }
5938 }
5939 if (copy_to_user(priv_data.buf, buf, len + 1))
5940 {
5941 hddLog(VOS_TRACE_LEVEL_ERROR,
5942 FL(" failed to copy data to user buffer"));
5943 ret = -EFAULT;
5944 kfree(buf);
5945 goto exit;
5946 }
5947 ret = len;
5948 kfree(buf);
5949 }
5950 else
5951 {
5952 hddLog(VOS_TRACE_LEVEL_ERROR,
5953 FL("failed to fetch the stats"));
5954 ret = -EFAULT;
5955 goto exit;
5956 }
5957
5958 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05305959 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
5960 {
5961 /*
5962 * this command wld be called by user-space when it detects WLAN
5963 * ON after airplane mode is set. When APM is set, WLAN turns off.
5964 * But it can be turned back on. Otherwise; when APM is turned back
5965 * off, WLAN wld turn back on. So at that point the command is
5966 * expected to come down. 0 means disable, 1 means enable. The
5967 * constraint is removed when parameter 1 is set or different
5968 * country code is set
5969 */
5970 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
5971 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05305972 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
5973 {
5974 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
5975 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07005976 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305977 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5978 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
5979 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05305980 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
5981 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07005982 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005983 }
5984exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305985 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005986 if (command)
5987 {
5988 kfree(command);
5989 }
5990 return ret;
5991}
5992
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07005993#ifdef CONFIG_COMPAT
5994static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
5995{
5996 struct {
5997 compat_uptr_t buf;
5998 int used_len;
5999 int total_len;
6000 } compat_priv_data;
6001 hdd_priv_data_t priv_data;
6002 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006003
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006004 /*
6005 * Note that pAdapter and ifr have already been verified by caller,
6006 * and HDD context has also been validated
6007 */
6008 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
6009 sizeof(compat_priv_data))) {
6010 ret = -EFAULT;
6011 goto exit;
6012 }
6013 priv_data.buf = compat_ptr(compat_priv_data.buf);
6014 priv_data.used_len = compat_priv_data.used_len;
6015 priv_data.total_len = compat_priv_data.total_len;
6016 ret = hdd_driver_command(pAdapter, &priv_data);
6017 exit:
6018 return ret;
6019}
6020#else /* CONFIG_COMPAT */
6021static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
6022{
6023 /* will never be invoked */
6024 return 0;
6025}
6026#endif /* CONFIG_COMPAT */
6027
6028static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
6029{
6030 hdd_priv_data_t priv_data;
6031 int ret = 0;
6032
6033 /*
6034 * Note that pAdapter and ifr have already been verified by caller,
6035 * and HDD context has also been validated
6036 */
6037 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
6038 ret = -EFAULT;
6039 } else {
6040 ret = hdd_driver_command(pAdapter, &priv_data);
6041 }
6042 return ret;
6043}
6044
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306045int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006046{
6047 hdd_adapter_t *pAdapter;
6048 hdd_context_t *pHddCtx;
6049 int ret;
6050
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306051 ENTER();
6052
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006053 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6054 if (NULL == pAdapter) {
6055 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6056 "%s: HDD adapter context is Null", __func__);
6057 ret = -ENODEV;
6058 goto exit;
6059 }
6060 if (dev != pAdapter->dev) {
6061 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6062 "%s: HDD adapter/dev inconsistency", __func__);
6063 ret = -ENODEV;
6064 goto exit;
6065 }
6066
6067 if ((!ifr) || (!ifr->ifr_data)) {
6068 ret = -EINVAL;
6069 goto exit;
6070 }
6071
6072 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6073 ret = wlan_hdd_validate_context(pHddCtx);
6074 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006075 ret = -EBUSY;
6076 goto exit;
6077 }
6078
6079 switch (cmd) {
6080 case (SIOCDEVPRIVATE + 1):
6081 if (is_compat_task())
6082 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
6083 else
6084 ret = hdd_driver_ioctl(pAdapter, ifr);
6085 break;
6086 default:
6087 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
6088 __func__, cmd);
6089 ret = -EINVAL;
6090 break;
6091 }
6092 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306093 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006094 return ret;
6095}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006096
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306097int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
6098{
6099 int ret;
6100
6101 vos_ssr_protect(__func__);
6102 ret = __hdd_ioctl(dev, ifr, cmd);
6103 vos_ssr_unprotect(__func__);
6104
6105 return ret;
6106}
6107
Katya Nigame7b69a82015-04-28 15:24:06 +05306108int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
6109{
6110 return 0;
6111}
6112
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006113#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006114/**---------------------------------------------------------------------------
6115
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006116 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006117
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006118 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006119 CCXBEACONREQ<space><Number of fields><space><Measurement token>
6120 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
6121 <space>Scan Mode N<space>Meas Duration N
6122 if the Number of bcn req fields (N) does not match with the actual number of fields passed
6123 then take N.
6124 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
6125 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
6126 This function does not take care of removing duplicate channels from the list
6127
6128 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006129 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006130
6131 \return - 0 for success non-zero for failure
6132
6133 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006134static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
6135 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006136{
6137 tANI_U8 *inPtr = pValue;
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306138 uint8_t input = 0;
6139 uint32_t tempInt = 0;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006140 int j = 0, i = 0, v = 0;
6141 char buf[32];
6142
6143 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6144 /*no argument after the command*/
6145 if (NULL == inPtr)
6146 {
6147 return -EINVAL;
6148 }
6149 /*no space after the command*/
6150 else if (SPACE_ASCII_VALUE != *inPtr)
6151 {
6152 return -EINVAL;
6153 }
6154
6155 /*removing empty spaces*/
6156 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
6157
6158 /*no argument followed by spaces*/
6159 if ('\0' == *inPtr) return -EINVAL;
6160
6161 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006162 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006163 if (1 != v) return -EINVAL;
6164
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306165 v = kstrtos8(buf, 10, &input);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006166 if ( v < 0) return -EINVAL;
6167
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306168 input = VOS_MIN(input, SIR_ESE_MAX_MEAS_IE_REQS);
6169 pEseBcnReq->numBcnReqIe = input;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006170
Srinivas Girigowda725a88e2016-03-31 19:24:25 +05306171 hddLog(LOG1, "Number of Bcn Req Ie fields: %d", pEseBcnReq->numBcnReqIe);
6172
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006173
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006174 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006175 {
6176 for (i = 0; i < 4; i++)
6177 {
6178 /*inPtr pointing to the beginning of first space after number of ie fields*/
6179 inPtr = strpbrk( inPtr, " " );
6180 /*no ie data after the number of ie fields argument*/
6181 if (NULL == inPtr) return -EINVAL;
6182
6183 /*removing empty space*/
6184 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
6185
6186 /*no ie data after the number of ie fields argument and spaces*/
6187 if ( '\0' == *inPtr ) return -EINVAL;
6188
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006189 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006190 if (1 != v) return -EINVAL;
6191
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306192 v = kstrtou32(buf, 10, &tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006193 if (v < 0) return -EINVAL;
6194
6195 switch (i)
6196 {
6197 case 0: /* Measurement token */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306198 if (!tempInt)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006199 {
6200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306201 "Invalid Measurement Token: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006202 return -EINVAL;
6203 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006204 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006205 break;
6206
6207 case 1: /* Channel number */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306208 if ((!tempInt) ||
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006209 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
6210 {
6211 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306212 "Invalid Channel Number: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006213 return -EINVAL;
6214 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006215 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006216 break;
6217
6218 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08006219 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006220 {
6221 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306222 "Invalid Scan Mode(%u) Expected{0|1|2}", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006223 return -EINVAL;
6224 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006225 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006226 break;
6227
6228 case 3: /* Measurement duration */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306229 if (((!tempInt) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
6230 ((pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006231 {
6232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306233 "Invalid Measurement Duration: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006234 return -EINVAL;
6235 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006236 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006237 break;
6238 }
6239 }
6240 }
6241
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006242 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006243 {
6244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05306245 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006246 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006247 pEseBcnReq->bcnReq[j].measurementToken,
6248 pEseBcnReq->bcnReq[j].channel,
6249 pEseBcnReq->bcnReq[j].scanMode,
6250 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006251 }
6252
6253 return VOS_STATUS_SUCCESS;
6254}
6255
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006256static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
6257{
6258 struct statsContext *pStatsContext = NULL;
6259 hdd_adapter_t *pAdapter = NULL;
6260
6261 if (NULL == pContext)
6262 {
6263 hddLog(VOS_TRACE_LEVEL_ERROR,
6264 "%s: Bad param, pContext [%p]",
6265 __func__, pContext);
6266 return;
6267 }
6268
Jeff Johnson72a40512013-12-19 10:14:15 -08006269 /* there is a race condition that exists between this callback
6270 function and the caller since the caller could time out either
6271 before or while this code is executing. we use a spinlock to
6272 serialize these actions */
6273 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006274
6275 pStatsContext = pContext;
6276 pAdapter = pStatsContext->pAdapter;
6277 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
6278 {
6279 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08006280 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006281 hddLog(VOS_TRACE_LEVEL_WARN,
6282 "%s: Invalid context, pAdapter [%p] magic [%08x]",
6283 __func__, pAdapter, pStatsContext->magic);
6284 return;
6285 }
6286
Jeff Johnson72a40512013-12-19 10:14:15 -08006287 /* context is valid so caller is still waiting */
6288
6289 /* paranoia: invalidate the magic */
6290 pStatsContext->magic = 0;
6291
6292 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006293 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
6294 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
6295 tsmMetrics.UplinkPktQueueDlyHist,
6296 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
6297 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
6298 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
6299 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
6300 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
6301 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
6302 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
6303
Jeff Johnson72a40512013-12-19 10:14:15 -08006304 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006305 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08006306
6307 /* serialization is complete */
6308 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006309}
6310
6311
6312
6313static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
6314 tAniTrafStrmMetrics* pTsmMetrics)
6315{
6316 hdd_station_ctx_t *pHddStaCtx = NULL;
6317 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08006318 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006319 long lrc;
6320 struct statsContext context;
6321 hdd_context_t *pHddCtx = NULL;
6322
6323 if (NULL == pAdapter)
6324 {
6325 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
6326 return VOS_STATUS_E_FAULT;
6327 }
6328
6329 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6330 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6331
6332 /* we are connected prepare our callback context */
6333 init_completion(&context.completion);
6334 context.pAdapter = pAdapter;
6335 context.magic = STATS_CONTEXT_MAGIC;
6336
6337 /* query tsm stats */
6338 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
6339 pHddStaCtx->conn_info.staId[ 0 ],
6340 pHddStaCtx->conn_info.bssId,
6341 &context, pHddCtx->pvosContext, tid);
6342
6343 if (eHAL_STATUS_SUCCESS != hstatus)
6344 {
Jeff Johnson72a40512013-12-19 10:14:15 -08006345 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
6346 __func__);
6347 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006348 }
6349 else
6350 {
6351 /* request was sent -- wait for the response */
6352 lrc = wait_for_completion_interruptible_timeout(&context.completion,
6353 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006354 if (lrc <= 0)
6355 {
6356 hddLog(VOS_TRACE_LEVEL_ERROR,
6357 "%s: SME %s while retrieving statistics",
6358 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08006359 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006360 }
6361 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006362
Jeff Johnson72a40512013-12-19 10:14:15 -08006363 /* either we never sent a request, we sent a request and received a
6364 response or we sent a request and timed out. if we never sent a
6365 request or if we sent a request and got a response, we want to
6366 clear the magic out of paranoia. if we timed out there is a
6367 race condition such that the callback function could be
6368 executing at the same time we are. of primary concern is if the
6369 callback function had already verified the "magic" but had not
6370 yet set the completion variable when a timeout occurred. we
6371 serialize these activities by invalidating the magic while
6372 holding a shared spinlock which will cause us to block if the
6373 callback is currently executing */
6374 spin_lock(&hdd_context_lock);
6375 context.magic = 0;
6376 spin_unlock(&hdd_context_lock);
6377
6378 if (VOS_STATUS_SUCCESS == vstatus)
6379 {
6380 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
6381 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
6382 pAdapter->tsmStats.UplinkPktQueueDlyHist,
6383 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
6384 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
6385 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
6386 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
6387 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
6388 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
6389 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
6390 }
6391 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006392}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006393#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006394
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006395#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08006396void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
6397{
6398 eCsrBand band = -1;
6399 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
6400 switch (band)
6401 {
6402 case eCSR_BAND_ALL:
6403 *pBand = WLAN_HDD_UI_BAND_AUTO;
6404 break;
6405
6406 case eCSR_BAND_24:
6407 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
6408 break;
6409
6410 case eCSR_BAND_5G:
6411 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
6412 break;
6413
6414 default:
6415 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
6416 *pBand = -1;
6417 break;
6418 }
6419}
6420
6421/**---------------------------------------------------------------------------
6422
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006423 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
6424
6425 This function parses the send action frame data passed in the format
6426 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
6427
Srinivas Girigowda56076852013-08-20 14:00:50 -07006428 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006429 \param - pTargetApBssid Pointer to target Ap bssid
6430 \param - pChannel Pointer to the Target AP channel
6431 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
6432 \param - pBuf Pointer to data
6433 \param - pBufLen Pointer to data length
6434
6435 \return - 0 for success non-zero for failure
6436
6437 --------------------------------------------------------------------------*/
6438VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
6439 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
6440{
6441 tANI_U8 *inPtr = pValue;
6442 tANI_U8 *dataEnd;
6443 int tempInt;
6444 int j = 0;
6445 int i = 0;
6446 int v = 0;
6447 tANI_U8 tempBuf[32];
6448 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006449 /* 12 hexa decimal digits, 5 ':' and '\0' */
6450 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006451
6452 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6453 /*no argument after the command*/
6454 if (NULL == inPtr)
6455 {
6456 return -EINVAL;
6457 }
6458
6459 /*no space after the command*/
6460 else if (SPACE_ASCII_VALUE != *inPtr)
6461 {
6462 return -EINVAL;
6463 }
6464
6465 /*removing empty spaces*/
6466 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6467
6468 /*no argument followed by spaces*/
6469 if ('\0' == *inPtr)
6470 {
6471 return -EINVAL;
6472 }
6473
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006474 v = sscanf(inPtr, "%17s", macAddress);
6475 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006476 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006477 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6478 "Invalid MAC address or All hex inputs are not read (%d)", v);
6479 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006480 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006481
6482 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
6483 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
6484 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
6485 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
6486 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
6487 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006488
6489 /* point to the next argument */
6490 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6491 /*no argument after the command*/
6492 if (NULL == inPtr) return -EINVAL;
6493
6494 /*removing empty spaces*/
6495 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6496
6497 /*no argument followed by spaces*/
6498 if ('\0' == *inPtr)
6499 {
6500 return -EINVAL;
6501 }
6502
6503 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006504 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006505 if (1 != v) return -EINVAL;
6506
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006507 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05306508 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05306509 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006510
6511 *pChannel = tempInt;
6512
6513 /* point to the next argument */
6514 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6515 /*no argument after the command*/
6516 if (NULL == inPtr) return -EINVAL;
6517 /*removing empty spaces*/
6518 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6519
6520 /*no argument followed by spaces*/
6521 if ('\0' == *inPtr)
6522 {
6523 return -EINVAL;
6524 }
6525
6526 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006527 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006528 if (1 != v) return -EINVAL;
6529
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006530 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08006531 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006532
6533 *pDwellTime = tempInt;
6534
6535 /* point to the next argument */
6536 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6537 /*no argument after the command*/
6538 if (NULL == inPtr) return -EINVAL;
6539 /*removing empty spaces*/
6540 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6541
6542 /*no argument followed by spaces*/
6543 if ('\0' == *inPtr)
6544 {
6545 return -EINVAL;
6546 }
6547
6548 /* find the length of data */
6549 dataEnd = inPtr;
6550 while(('\0' != *dataEnd) )
6551 {
6552 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006553 }
Kiet Lambe150c22013-11-21 16:30:32 +05306554 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006555 if ( *pBufLen <= 0) return -EINVAL;
6556
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07006557 /* Allocate the number of bytes based on the number of input characters
6558 whether it is even or odd.
6559 if the number of input characters are even, then we need N/2 byte.
6560 if the number of input characters are odd, then we need do (N+1)/2 to
6561 compensate rounding off.
6562 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
6563 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
6564 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006565 if (NULL == *pBuf)
6566 {
6567 hddLog(VOS_TRACE_LEVEL_FATAL,
6568 "%s: vos_mem_alloc failed ", __func__);
6569 return -EINVAL;
6570 }
6571
6572 /* the buffer received from the upper layer is character buffer,
6573 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
6574 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
6575 and f0 in 3rd location */
6576 for (i = 0, j = 0; j < *pBufLen; j += 2)
6577 {
Kiet Lambe150c22013-11-21 16:30:32 +05306578 if( j+1 == *pBufLen)
6579 {
6580 tempByte = hdd_parse_hex(inPtr[j]);
6581 }
6582 else
6583 {
6584 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
6585 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006586 (*pBuf)[i++] = tempByte;
6587 }
6588 *pBufLen = i;
6589 return VOS_STATUS_SUCCESS;
6590}
6591
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006592/**---------------------------------------------------------------------------
6593
Srinivas Girigowdade697412013-02-14 16:31:48 -08006594 \brief hdd_parse_channellist() - HDD Parse channel list
6595
6596 This function parses the channel list passed in the format
6597 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07006598 if the Number of channels (N) does not match with the actual number of channels passed
6599 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
6600 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
6601 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
6602 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08006603
6604 \param - pValue Pointer to input channel list
6605 \param - ChannelList Pointer to local output array to record channel list
6606 \param - pNumChannels Pointer to number of roam scan channels
6607
6608 \return - 0 for success non-zero for failure
6609
6610 --------------------------------------------------------------------------*/
6611VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
6612{
6613 tANI_U8 *inPtr = pValue;
6614 int tempInt;
6615 int j = 0;
6616 int v = 0;
6617 char buf[32];
6618
6619 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6620 /*no argument after the command*/
6621 if (NULL == inPtr)
6622 {
6623 return -EINVAL;
6624 }
6625
6626 /*no space after the command*/
6627 else if (SPACE_ASCII_VALUE != *inPtr)
6628 {
6629 return -EINVAL;
6630 }
6631
6632 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006633 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08006634
6635 /*no argument followed by spaces*/
6636 if ('\0' == *inPtr)
6637 {
6638 return -EINVAL;
6639 }
6640
6641 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006642 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006643 if (1 != v) return -EINVAL;
6644
Srinivas Girigowdade697412013-02-14 16:31:48 -08006645 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006646 if ((v < 0) ||
6647 (tempInt <= 0) ||
6648 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
6649 {
6650 return -EINVAL;
6651 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006652
6653 *pNumChannels = tempInt;
6654
6655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6656 "Number of channels are: %d", *pNumChannels);
6657
6658 for (j = 0; j < (*pNumChannels); j++)
6659 {
6660 /*inPtr pointing to the beginning of first space after number of channels*/
6661 inPtr = strpbrk( inPtr, " " );
6662 /*no channel list after the number of channels argument*/
6663 if (NULL == inPtr)
6664 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07006665 if (0 != j)
6666 {
6667 *pNumChannels = j;
6668 return VOS_STATUS_SUCCESS;
6669 }
6670 else
6671 {
6672 return -EINVAL;
6673 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006674 }
6675
6676 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006677 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08006678
6679 /*no channel list after the number of channels argument and spaces*/
6680 if ( '\0' == *inPtr )
6681 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07006682 if (0 != j)
6683 {
6684 *pNumChannels = j;
6685 return VOS_STATUS_SUCCESS;
6686 }
6687 else
6688 {
6689 return -EINVAL;
6690 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006691 }
6692
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006693 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006694 if (1 != v) return -EINVAL;
6695
Srinivas Girigowdade697412013-02-14 16:31:48 -08006696 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006697 if ((v < 0) ||
6698 (tempInt <= 0) ||
6699 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
6700 {
6701 return -EINVAL;
6702 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006703 pChannelList[j] = tempInt;
6704
6705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6706 "Channel %d added to preferred channel list",
6707 pChannelList[j] );
6708 }
6709
Srinivas Girigowdade697412013-02-14 16:31:48 -08006710 return VOS_STATUS_SUCCESS;
6711}
6712
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006713
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05306714/**
6715 * hdd_parse_reassoc_command_v1_data() - HDD Parse reassoc command data
6716 * This function parses the reasoc command data passed in the format
6717 * REASSOC<space><bssid><space><channel>
6718 *
6719 * @pValue: Pointer to input data (its a NUL terminated string)
6720 * @pTargetApBssid: Pointer to target Ap bssid
6721 * @pChannel: Pointer to the Target AP channel
6722 *
6723 * Return: 0 for success non-zero for failure
6724 */
6725static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
6726 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006727{
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05306728 const tANI_U8 *inPtr = pValue;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006729 int tempInt;
6730 int v = 0;
6731 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006732 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006733 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006734
6735 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6736 /*no argument after the command*/
6737 if (NULL == inPtr)
6738 {
6739 return -EINVAL;
6740 }
6741
6742 /*no space after the command*/
6743 else if (SPACE_ASCII_VALUE != *inPtr)
6744 {
6745 return -EINVAL;
6746 }
6747
6748 /*removing empty spaces*/
6749 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6750
6751 /*no argument followed by spaces*/
6752 if ('\0' == *inPtr)
6753 {
6754 return -EINVAL;
6755 }
6756
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006757 v = sscanf(inPtr, "%17s", macAddress);
6758 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006759 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6761 "Invalid MAC address or All hex inputs are not read (%d)", v);
6762 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006763 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006764
6765 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
6766 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
6767 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
6768 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
6769 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
6770 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006771
6772 /* point to the next argument */
6773 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6774 /*no argument after the command*/
6775 if (NULL == inPtr) return -EINVAL;
6776
6777 /*removing empty spaces*/
6778 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6779
6780 /*no argument followed by spaces*/
6781 if ('\0' == *inPtr)
6782 {
6783 return -EINVAL;
6784 }
6785
6786 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006787 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006788 if (1 != v) return -EINVAL;
6789
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006790 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006791 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05306792 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006793 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
6794 {
6795 return -EINVAL;
6796 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006797
6798 *pChannel = tempInt;
6799 return VOS_STATUS_SUCCESS;
6800}
6801
6802#endif
6803
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006804#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006805/**---------------------------------------------------------------------------
6806
6807 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
6808
6809 This function parses the SETCCKM IE command
6810 SETCCKMIE<space><ie data>
6811
6812 \param - pValue Pointer to input data
6813 \param - pCckmIe Pointer to output cckm Ie
6814 \param - pCckmIeLen Pointer to output cckm ie length
6815
6816 \return - 0 for success non-zero for failure
6817
6818 --------------------------------------------------------------------------*/
6819VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
6820 tANI_U8 *pCckmIeLen)
6821{
6822 tANI_U8 *inPtr = pValue;
6823 tANI_U8 *dataEnd;
6824 int j = 0;
6825 int i = 0;
6826 tANI_U8 tempByte = 0;
6827
6828 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6829 /*no argument after the command*/
6830 if (NULL == inPtr)
6831 {
6832 return -EINVAL;
6833 }
6834
6835 /*no space after the command*/
6836 else if (SPACE_ASCII_VALUE != *inPtr)
6837 {
6838 return -EINVAL;
6839 }
6840
6841 /*removing empty spaces*/
6842 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6843
6844 /*no argument followed by spaces*/
6845 if ('\0' == *inPtr)
6846 {
6847 return -EINVAL;
6848 }
6849
6850 /* find the length of data */
6851 dataEnd = inPtr;
6852 while(('\0' != *dataEnd) )
6853 {
6854 dataEnd++;
6855 ++(*pCckmIeLen);
6856 }
6857 if ( *pCckmIeLen <= 0) return -EINVAL;
6858
6859 /* Allocate the number of bytes based on the number of input characters
6860 whether it is even or odd.
6861 if the number of input characters are even, then we need N/2 byte.
6862 if the number of input characters are odd, then we need do (N+1)/2 to
6863 compensate rounding off.
6864 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
6865 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
6866 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
6867 if (NULL == *pCckmIe)
6868 {
6869 hddLog(VOS_TRACE_LEVEL_FATAL,
6870 "%s: vos_mem_alloc failed ", __func__);
6871 return -EINVAL;
6872 }
6873 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
6874 /* the buffer received from the upper layer is character buffer,
6875 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
6876 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
6877 and f0 in 3rd location */
6878 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
6879 {
6880 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
6881 (*pCckmIe)[i++] = tempByte;
6882 }
6883 *pCckmIeLen = i;
6884
6885 return VOS_STATUS_SUCCESS;
6886}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006887#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006888
Jeff Johnson295189b2012-06-20 16:38:30 -07006889/**---------------------------------------------------------------------------
6890
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006891 \brief hdd_is_valid_mac_address() - Validate MAC address
6892
6893 This function validates whether the given MAC address is valid or not
6894 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
6895 where X is the hexa decimal digit character and separated by ':'
6896 This algorithm works even if MAC address is not separated by ':'
6897
6898 This code checks given input string mac contains exactly 12 hexadecimal digits.
6899 and a separator colon : appears in the input string only after
6900 an even number of hex digits.
6901
6902 \param - pMacAddr pointer to the input MAC address
6903 \return - 1 for valid and 0 for invalid
6904
6905 --------------------------------------------------------------------------*/
6906
6907v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
6908{
6909 int xdigit = 0;
6910 int separator = 0;
6911 while (*pMacAddr)
6912 {
6913 if (isxdigit(*pMacAddr))
6914 {
6915 xdigit++;
6916 }
6917 else if (':' == *pMacAddr)
6918 {
6919 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
6920 break;
6921
6922 ++separator;
6923 }
6924 else
6925 {
6926 separator = -1;
6927 /* Invalid MAC found */
6928 return 0;
6929 }
6930 ++pMacAddr;
6931 }
6932 return (xdigit == 12 && (separator == 5 || separator == 0));
6933}
6934
6935/**---------------------------------------------------------------------------
6936
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306937 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07006938
6939 \param - dev Pointer to net_device structure
6940
6941 \return - 0 for success non-zero for failure
6942
6943 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306944int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07006945{
6946 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6947 hdd_context_t *pHddCtx;
6948 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6949 VOS_STATUS status;
6950 v_BOOL_t in_standby = TRUE;
6951
6952 if (NULL == pAdapter)
6953 {
6954 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05306955 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006956 return -ENODEV;
6957 }
6958
6959 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306960 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
6961 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07006962 if (NULL == pHddCtx)
6963 {
6964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006965 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006966 return -ENODEV;
6967 }
6968
6969 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6970 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
6971 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07006972 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
6973 {
6974 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306975 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07006976 in_standby = FALSE;
6977 break;
6978 }
6979 else
6980 {
6981 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6982 pAdapterNode = pNext;
6983 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006984 }
6985
6986 if (TRUE == in_standby)
6987 {
6988 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
6989 {
6990 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
6991 "wlan out of power save", __func__);
6992 return -EINVAL;
6993 }
6994 }
6995
Jeff Johnson6a81ca42013-04-05 10:37:08 -07006996 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07006997 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6998 {
6999 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007000 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007001 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307002 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007003 netif_tx_start_all_queues(dev);
7004 }
7005
7006 return 0;
7007}
7008
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307009/**---------------------------------------------------------------------------
7010
7011 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
7012
7013 This is called in response to ifconfig up
7014
7015 \param - dev Pointer to net_device structure
7016
7017 \return - 0 for success non-zero for failure
7018
7019 --------------------------------------------------------------------------*/
7020int hdd_open(struct net_device *dev)
7021{
7022 int ret;
7023
7024 vos_ssr_protect(__func__);
7025 ret = __hdd_open(dev);
7026 vos_ssr_unprotect(__func__);
7027
7028 return ret;
7029}
7030
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307031int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007032{
7033 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7034
7035 if(pAdapter == NULL) {
7036 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007037 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08007038 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007039 }
7040
Jeff Johnson295189b2012-06-20 16:38:30 -07007041 return 0;
7042}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307043
7044int hdd_mon_open (struct net_device *dev)
7045{
7046 int ret;
7047
7048 vos_ssr_protect(__func__);
7049 ret = __hdd_mon_open(dev);
7050 vos_ssr_unprotect(__func__);
7051
7052 return ret;
7053}
7054
Katya Nigame7b69a82015-04-28 15:24:06 +05307055int hdd_mon_stop(struct net_device *dev)
7056{
7057 return 0;
7058}
7059
Jeff Johnson295189b2012-06-20 16:38:30 -07007060/**---------------------------------------------------------------------------
7061
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307062 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07007063
7064 \param - dev Pointer to net_device structure
7065
7066 \return - 0 for success non-zero for failure
7067
7068 --------------------------------------------------------------------------*/
7069
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307070int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007071{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05307072 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007073 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7074 hdd_context_t *pHddCtx;
7075 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7076 VOS_STATUS status;
7077 v_BOOL_t enter_standby = TRUE;
7078
7079 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007080 if (NULL == pAdapter)
7081 {
7082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05307083 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007084 return -ENODEV;
7085 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05307086 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307087 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05307088
7089 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7090 ret = wlan_hdd_validate_context(pHddCtx);
7091 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07007092 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05307093 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007094 }
7095
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307096 /* Nothing to be done if the interface is not opened */
7097 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
7098 {
7099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7100 "%s: NETDEV Interface is not OPENED", __func__);
7101 return -ENODEV;
7102 }
7103
7104 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007105 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07007106 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307107
7108 /* Disable TX on the interface, after this hard_start_xmit() will not
7109 * be called on that interface
7110 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307111 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007112 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307113
7114 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07007115 netif_carrier_off(pAdapter->dev);
7116
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307117 /* The interface is marked as down for outside world (aka kernel)
7118 * But the driver is pretty much alive inside. The driver needs to
7119 * tear down the existing connection on the netdev (session)
7120 * cleanup the data pipes and wait until the control plane is stabilized
7121 * for this interface. The call also needs to wait until the above
7122 * mentioned actions are completed before returning to the caller.
7123 * Notice that the hdd_stop_adapter is requested not to close the session
7124 * That is intentional to be able to scan if it is a STA/P2P interface
7125 */
7126 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307127#ifdef FEATURE_WLAN_TDLS
7128 mutex_lock(&pHddCtx->tdls_lock);
7129#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307130 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05307131 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307132#ifdef FEATURE_WLAN_TDLS
7133 mutex_unlock(&pHddCtx->tdls_lock);
7134#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007135 /* SoftAP ifaces should never go in power save mode
7136 making sure same here. */
7137 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
7138 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07007139 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07007140 )
7141 {
7142 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7144 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007145 EXIT();
7146 return 0;
7147 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307148 /* Find if any iface is up. If any iface is up then can't put device to
7149 * sleep/power save mode
7150 */
Jeff Johnson295189b2012-06-20 16:38:30 -07007151 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7152 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
7153 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007154 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
7155 {
7156 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307157 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007158 enter_standby = FALSE;
7159 break;
7160 }
7161 else
7162 {
7163 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7164 pAdapterNode = pNext;
7165 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007166 }
7167
7168 if (TRUE == enter_standby)
7169 {
7170 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
7171 "entering standby", __func__);
7172 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
7173 {
7174 /*log and return success*/
7175 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
7176 "wlan in power save", __func__);
7177 }
7178 }
7179
7180 EXIT();
7181 return 0;
7182}
7183
7184/**---------------------------------------------------------------------------
7185
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307186 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07007187
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307188 This is called in response to ifconfig down
7189
7190 \param - dev Pointer to net_device structure
7191
7192 \return - 0 for success non-zero for failure
7193-----------------------------------------------------------------------------*/
7194int hdd_stop (struct net_device *dev)
7195{
7196 int ret;
7197
7198 vos_ssr_protect(__func__);
7199 ret = __hdd_stop(dev);
7200 vos_ssr_unprotect(__func__);
7201
7202 return ret;
7203}
7204
7205/**---------------------------------------------------------------------------
7206
7207 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07007208
7209 \param - dev Pointer to net_device structure
7210
7211 \return - void
7212
7213 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307214static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007215{
7216 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307217 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007218 ENTER();
7219
7220 do
7221 {
7222 if (NULL == pAdapter)
7223 {
7224 hddLog(VOS_TRACE_LEVEL_FATAL,
7225 "%s: NULL pAdapter", __func__);
7226 break;
7227 }
7228
7229 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7230 {
7231 hddLog(VOS_TRACE_LEVEL_FATAL,
7232 "%s: Invalid magic", __func__);
7233 break;
7234 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307235 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7236 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07007237 {
7238 hddLog(VOS_TRACE_LEVEL_FATAL,
7239 "%s: NULL pHddCtx", __func__);
7240 break;
7241 }
7242
7243 if (dev != pAdapter->dev)
7244 {
7245 hddLog(VOS_TRACE_LEVEL_FATAL,
7246 "%s: Invalid device reference", __func__);
7247 /* we haven't validated all cases so let this go for now */
7248 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307249#ifdef FEATURE_WLAN_TDLS
7250 mutex_lock(&pHddCtx->tdls_lock);
7251#endif
c_hpothu002231a2015-02-05 14:58:51 +05307252 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307253#ifdef FEATURE_WLAN_TDLS
7254 mutex_unlock(&pHddCtx->tdls_lock);
7255#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007256
7257 /* after uninit our adapter structure will no longer be valid */
7258 pAdapter->dev = NULL;
7259 pAdapter->magic = 0;
Manjeet Singh47ee8472016-04-11 11:57:18 +05307260 pAdapter->pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007261 } while (0);
7262
7263 EXIT();
7264}
7265
7266/**---------------------------------------------------------------------------
7267
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307268 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
7269
7270 This is called during the netdev unregister to uninitialize all data
7271associated with the device
7272
7273 \param - dev Pointer to net_device structure
7274
7275 \return - void
7276
7277 --------------------------------------------------------------------------*/
7278static void hdd_uninit (struct net_device *dev)
7279{
7280 vos_ssr_protect(__func__);
7281 __hdd_uninit(dev);
7282 vos_ssr_unprotect(__func__);
7283}
7284
7285/**---------------------------------------------------------------------------
7286
Jeff Johnson295189b2012-06-20 16:38:30 -07007287 \brief hdd_release_firmware() -
7288
7289 This function calls the release firmware API to free the firmware buffer.
7290
7291 \param - pFileName Pointer to the File Name.
7292 pCtx - Pointer to the adapter .
7293
7294
7295 \return - 0 for success, non zero for failure
7296
7297 --------------------------------------------------------------------------*/
7298
7299VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
7300{
7301 VOS_STATUS status = VOS_STATUS_SUCCESS;
7302 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7303 ENTER();
7304
7305
7306 if (!strcmp(WLAN_FW_FILE, pFileName)) {
7307
7308 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
7309
7310 if(pHddCtx->fw) {
7311 release_firmware(pHddCtx->fw);
7312 pHddCtx->fw = NULL;
7313 }
7314 else
7315 status = VOS_STATUS_E_FAILURE;
7316 }
7317 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
7318 if(pHddCtx->nv) {
7319 release_firmware(pHddCtx->nv);
7320 pHddCtx->nv = NULL;
7321 }
7322 else
7323 status = VOS_STATUS_E_FAILURE;
7324
7325 }
7326
7327 EXIT();
7328 return status;
7329}
7330
7331/**---------------------------------------------------------------------------
7332
7333 \brief hdd_request_firmware() -
7334
7335 This function reads the firmware file using the request firmware
7336 API and returns the the firmware data and the firmware file size.
7337
7338 \param - pfileName - Pointer to the file name.
7339 - pCtx - Pointer to the adapter .
7340 - ppfw_data - Pointer to the pointer of the firmware data.
7341 - pSize - Pointer to the file size.
7342
7343 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
7344
7345 --------------------------------------------------------------------------*/
7346
7347
7348VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
7349{
7350 int status;
7351 VOS_STATUS retval = VOS_STATUS_SUCCESS;
7352 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7353 ENTER();
7354
7355 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
7356
7357 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
7358
7359 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
7360 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
7361 __func__, pfileName);
7362 retval = VOS_STATUS_E_FAILURE;
7363 }
7364
7365 else {
7366 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
7367 *pSize = pHddCtx->fw->size;
7368 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
7369 __func__, *pSize);
7370 }
7371 }
7372 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
7373
7374 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
7375
7376 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
7377 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
7378 __func__, pfileName);
7379 retval = VOS_STATUS_E_FAILURE;
7380 }
7381
7382 else {
7383 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
7384 *pSize = pHddCtx->nv->size;
7385 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
7386 __func__, *pSize);
7387 }
7388 }
7389
7390 EXIT();
7391 return retval;
7392}
7393/**---------------------------------------------------------------------------
7394 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
7395
7396 This is the function invoked by SME to inform the result of a full power
7397 request issued by HDD
7398
7399 \param - callbackcontext - Pointer to cookie
7400 status - result of request
7401
7402 \return - None
7403
7404--------------------------------------------------------------------------*/
7405void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
7406{
7407 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
7408
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007409 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007410 if(&pHddCtx->full_pwr_comp_var)
7411 {
7412 complete(&pHddCtx->full_pwr_comp_var);
7413 }
7414}
7415
Abhishek Singh00b71972016-01-07 10:51:04 +05307416#ifdef WLAN_FEATURE_RMC
7417static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo)
7418{
7419 int payload_len;
7420 struct sk_buff *skb;
7421 struct nlmsghdr *nlh;
7422 v_U8_t *data;
7423
7424 payload_len = ETH_ALEN;
7425
7426 if (0 == cesium_pid)
7427 {
7428 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: cesium process not registered",
7429 __func__);
7430 return;
7431 }
7432
7433 if ((skb = nlmsg_new(payload_len,GFP_ATOMIC)) == NULL)
7434 {
7435 hddLog(VOS_TRACE_LEVEL_ERROR,
7436 "%s: nlmsg_new() failed for msg size[%d]",
7437 __func__, NLMSG_SPACE(payload_len));
7438 return;
7439 }
7440
7441 nlh = nlmsg_put(skb, cesium_pid, seqNo, 0, payload_len, NLM_F_REQUEST);
7442
7443 if (NULL == nlh)
7444 {
7445 hddLog(VOS_TRACE_LEVEL_ERROR,
7446 "%s: nlmsg_put() failed for msg size[%d]",
7447 __func__, NLMSG_SPACE(payload_len));
7448
7449 kfree_skb(skb);
7450 return;
7451 }
7452
7453 data = nlmsg_data(nlh);
7454 memcpy(data, MacAddr, ETH_ALEN);
7455
7456 if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0)
7457 {
7458 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_unicast() failed for msg size[%d]",
7459 __func__, NLMSG_SPACE(payload_len));
7460 }
7461
7462 return;
7463}
7464
7465/**---------------------------------------------------------------------------
7466 \brief hdd_ParseuserParams - return a pointer to the next argument
7467
7468 \return - status
7469
7470--------------------------------------------------------------------------*/
7471static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg)
7472{
7473 tANI_U8 *pVal;
7474
7475 pVal = strchr(pValue, ' ');
7476
7477 if (NULL == pVal)
7478 {
7479 /* no argument remains */
7480 return -EINVAL;
7481 }
7482 else if (SPACE_ASCII_VALUE != *pVal)
7483 {
7484 /* no space after the current argument */
7485 return -EINVAL;
7486 }
7487
7488 pVal++;
7489
7490 /* remove empty spaces */
7491 while ((SPACE_ASCII_VALUE == *pVal) && ('\0' != *pVal))
7492 {
7493 pVal++;
7494 }
7495
7496 /* no argument followed by spaces */
7497 if ('\0' == *pVal)
7498 {
7499 return -EINVAL;
7500 }
7501
7502 *ppArg = pVal;
7503
7504 return 0;
7505}
7506
7507/**----------------------------------------------------------------------------
7508 \brief hdd_ParseIBSSTXFailEventParams - Parse params for SETIBSSTXFAILEVENT
7509
7510 \return - status
7511
7512------------------------------------------------------------------------------*/
7513static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
7514 tANI_U8 *tx_fail_count,
7515 tANI_U16 *pid)
7516{
7517 tANI_U8 *param = NULL;
7518 int ret;
7519
7520 ret = hdd_ParseUserParams(pValue, &param);
7521
7522 if (0 == ret && NULL != param)
7523 {
7524 if (1 != sscanf(param, "%hhu", tx_fail_count))
7525 {
7526 ret = -EINVAL;
7527 goto done;
7528 }
7529 }
7530 else
7531 {
7532 goto done;
7533 }
7534
7535 if (0 == *tx_fail_count)
7536 {
7537 *pid = 0;
7538 goto done;
7539 }
7540
7541 pValue = param;
7542 pValue++;
7543
7544 ret = hdd_ParseUserParams(pValue, &param);
7545
7546 if (0 == ret)
7547 {
7548 if (1 != sscanf(param, "%hu", pid))
7549 {
7550 ret = -EINVAL;
7551 goto done;
7552 }
7553 }
7554 else
7555 {
7556 goto done;
7557 }
7558
7559done:
7560 return ret;
7561}
7562
7563static int hdd_open_cesium_nl_sock()
7564{
7565#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
7566 struct netlink_kernel_cfg cfg = {
7567 .groups = WLAN_NLINK_MCAST_GRP_ID,
7568 .input = NULL
7569 };
7570#endif
7571 int ret = 0;
7572
7573#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
7574 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
7575#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
7576 THIS_MODULE,
7577#endif
7578 &cfg);
7579#else
7580 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
7581 WLAN_NLINK_MCAST_GRP_ID, NULL, NULL, THIS_MODULE);
7582#endif
7583
7584 if (cesium_nl_srv_sock == NULL)
7585 {
7586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7587 "NLINK: cesium netlink_kernel_create failed");
7588 ret = -ECONNREFUSED;
7589 }
7590
7591 return ret;
7592}
7593
7594static void hdd_close_cesium_nl_sock()
7595{
7596 if (NULL != cesium_nl_srv_sock)
7597 {
7598 netlink_kernel_release(cesium_nl_srv_sock);
7599 cesium_nl_srv_sock = NULL;
7600 }
7601}
7602#endif /* WLAN_FEATURE_RMC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007603/**---------------------------------------------------------------------------
7604
7605 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
7606
7607 This is the function invoked by SME to inform the result of BMPS
7608 request issued by HDD
7609
7610 \param - callbackcontext - Pointer to cookie
7611 status - result of request
7612
7613 \return - None
7614
7615--------------------------------------------------------------------------*/
7616void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
7617{
7618
7619 struct completion *completion_var = (struct completion*) callbackContext;
7620
Arif Hussain6d2a3322013-11-17 19:50:10 -08007621 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007622 if(completion_var != NULL)
7623 {
7624 complete(completion_var);
7625 }
7626}
7627
7628/**---------------------------------------------------------------------------
7629
7630 \brief hdd_get_cfg_file_size() -
7631
7632 This function reads the configuration file using the request firmware
7633 API and returns the configuration file size.
7634
7635 \param - pCtx - Pointer to the adapter .
7636 - pFileName - Pointer to the file name.
7637 - pBufSize - Pointer to the buffer size.
7638
7639 \return - 0 for success, non zero for failure
7640
7641 --------------------------------------------------------------------------*/
7642
7643VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
7644{
7645 int status;
7646 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7647
7648 ENTER();
7649
7650 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
7651
7652 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
7653 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
7654 status = VOS_STATUS_E_FAILURE;
7655 }
7656 else {
7657 *pBufSize = pHddCtx->fw->size;
7658 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
7659 release_firmware(pHddCtx->fw);
7660 pHddCtx->fw = NULL;
7661 }
7662
7663 EXIT();
7664 return VOS_STATUS_SUCCESS;
7665}
7666
7667/**---------------------------------------------------------------------------
7668
7669 \brief hdd_read_cfg_file() -
7670
7671 This function reads the configuration file using the request firmware
7672 API and returns the cfg data and the buffer size of the configuration file.
7673
7674 \param - pCtx - Pointer to the adapter .
7675 - pFileName - Pointer to the file name.
7676 - pBuffer - Pointer to the data buffer.
7677 - pBufSize - Pointer to the buffer size.
7678
7679 \return - 0 for success, non zero for failure
7680
7681 --------------------------------------------------------------------------*/
7682
7683VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
7684 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
7685{
7686 int status;
7687 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7688
7689 ENTER();
7690
7691 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
7692
7693 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
7694 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
7695 return VOS_STATUS_E_FAILURE;
7696 }
7697 else {
7698 if(*pBufSize != pHddCtx->fw->size) {
7699 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
7700 "file size", __func__);
7701 release_firmware(pHddCtx->fw);
7702 pHddCtx->fw = NULL;
7703 return VOS_STATUS_E_FAILURE;
7704 }
7705 else {
7706 if(pBuffer) {
7707 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
7708 }
7709 release_firmware(pHddCtx->fw);
7710 pHddCtx->fw = NULL;
7711 }
7712 }
7713
7714 EXIT();
7715
7716 return VOS_STATUS_SUCCESS;
7717}
7718
7719/**---------------------------------------------------------------------------
7720
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307721 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007722
7723 This function sets the user specified mac address using
7724 the command ifconfig wlanX hw ether <mac adress>.
7725
7726 \param - dev - Pointer to the net device.
7727 - addr - Pointer to the sockaddr.
7728 \return - 0 for success, non zero for failure
7729
7730 --------------------------------------------------------------------------*/
7731
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307732static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07007733{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307734 hdd_adapter_t *pAdapter;
7735 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007736 struct sockaddr *psta_mac_addr = addr;
7737 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307738 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007739
7740 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307741 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7742 if (NULL == pAdapter)
7743 {
7744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7745 "%s: Adapter is NULL",__func__);
7746 return -EINVAL;
7747 }
7748 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7749 ret = wlan_hdd_validate_context(pHddCtx);
7750 if (0 != ret)
7751 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307752 return ret;
7753 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007754
7755 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07007756 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
7757
7758 EXIT();
7759 return halStatus;
7760}
7761
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307762/**---------------------------------------------------------------------------
7763
7764 \brief hdd_set_mac_address() -
7765
7766 Wrapper function to protect __hdd_set_mac_address() function from ssr
7767
7768 \param - dev - Pointer to the net device.
7769 - addr - Pointer to the sockaddr.
7770 \return - 0 for success, non zero for failure
7771
7772 --------------------------------------------------------------------------*/
7773static int hdd_set_mac_address(struct net_device *dev, void *addr)
7774{
7775 int ret;
7776
7777 vos_ssr_protect(__func__);
7778 ret = __hdd_set_mac_address(dev, addr);
7779 vos_ssr_unprotect(__func__);
7780
7781 return ret;
7782}
7783
Jeff Johnson295189b2012-06-20 16:38:30 -07007784tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
7785{
7786 int i;
7787 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
7788 {
Abhishek Singheb183782014-02-06 13:37:21 +05307789 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007790 break;
7791 }
7792
7793 if( VOS_MAX_CONCURRENCY_PERSONA == i)
7794 return NULL;
7795
7796 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
7797 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
7798}
7799
7800void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
7801{
7802 int i;
7803 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
7804 {
7805 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
7806 {
7807 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
7808 break;
7809 }
7810 }
7811 return;
7812}
7813
7814#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
7815 static struct net_device_ops wlan_drv_ops = {
7816 .ndo_open = hdd_open,
7817 .ndo_stop = hdd_stop,
7818 .ndo_uninit = hdd_uninit,
7819 .ndo_start_xmit = hdd_hard_start_xmit,
7820 .ndo_tx_timeout = hdd_tx_timeout,
7821 .ndo_get_stats = hdd_stats,
7822 .ndo_do_ioctl = hdd_ioctl,
7823 .ndo_set_mac_address = hdd_set_mac_address,
7824 .ndo_select_queue = hdd_select_queue,
7825#ifdef WLAN_FEATURE_PACKET_FILTERING
7826#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
7827 .ndo_set_rx_mode = hdd_set_multicast_list,
7828#else
7829 .ndo_set_multicast_list = hdd_set_multicast_list,
7830#endif //LINUX_VERSION_CODE
7831#endif
7832 };
Jeff Johnson295189b2012-06-20 16:38:30 -07007833 static struct net_device_ops wlan_mon_drv_ops = {
7834 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05307835 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07007836 .ndo_uninit = hdd_uninit,
7837 .ndo_start_xmit = hdd_mon_hard_start_xmit,
7838 .ndo_tx_timeout = hdd_tx_timeout,
7839 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05307840 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07007841 .ndo_set_mac_address = hdd_set_mac_address,
7842 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05307843
Jeff Johnson295189b2012-06-20 16:38:30 -07007844#endif
7845
7846void hdd_set_station_ops( struct net_device *pWlanDev )
7847{
7848#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07007849 pWlanDev->netdev_ops = &wlan_drv_ops;
7850#else
7851 pWlanDev->open = hdd_open;
7852 pWlanDev->stop = hdd_stop;
7853 pWlanDev->uninit = hdd_uninit;
7854 pWlanDev->hard_start_xmit = NULL;
7855 pWlanDev->tx_timeout = hdd_tx_timeout;
7856 pWlanDev->get_stats = hdd_stats;
7857 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07007858 pWlanDev->set_mac_address = hdd_set_mac_address;
7859#endif
7860}
7861
Katya Nigam1fd24402015-02-16 14:52:19 +05307862void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
7863{
7864 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
7865 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
7866 #else
7867 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
7868 #endif
7869}
7870
Jeff Johnsoneed415b2013-01-18 16:11:20 -08007871static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07007872{
7873 struct net_device *pWlanDev = NULL;
7874 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007875 /*
7876 * cfg80211 initialization and registration....
7877 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05307878 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
7879#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
7880 NET_NAME_UNKNOWN,
7881#endif
7882 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07007883 if(pWlanDev != NULL)
7884 {
7885
7886 //Save the pointer to the net_device in the HDD adapter
7887 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
7888
Jeff Johnson295189b2012-06-20 16:38:30 -07007889 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
7890
7891 pAdapter->dev = pWlanDev;
7892 pAdapter->pHddCtx = pHddCtx;
7893 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05307894 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07007895
Rajeev79dbe4c2013-10-05 11:03:42 +05307896#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05307897 pAdapter->pBatchScanRsp = NULL;
7898 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07007899 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08007900 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05307901 mutex_init(&pAdapter->hdd_batch_scan_lock);
7902#endif
7903
Jeff Johnson295189b2012-06-20 16:38:30 -07007904 pAdapter->isLinkUpSvcNeeded = FALSE;
7905 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
7906 //Init the net_device structure
7907 strlcpy(pWlanDev->name, name, IFNAMSIZ);
7908
7909 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
7910 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
7911 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
7912 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
7913
7914 hdd_set_station_ops( pAdapter->dev );
7915
7916 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07007917 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
7918 pAdapter->wdev.wiphy = pHddCtx->wiphy;
7919 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07007920 /* set pWlanDev's parent to underlying device */
7921 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07007922
7923 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007924 }
7925
7926 return pAdapter;
7927}
7928
7929VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
7930{
7931 struct net_device *pWlanDev = pAdapter->dev;
7932 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
7933 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
7934 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7935
7936 if( rtnl_lock_held )
7937 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08007938 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07007939 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
7940 {
7941 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
7942 return VOS_STATUS_E_FAILURE;
7943 }
7944 }
7945 if (register_netdevice(pWlanDev))
7946 {
7947 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
7948 return VOS_STATUS_E_FAILURE;
7949 }
7950 }
7951 else
7952 {
7953 if(register_netdev(pWlanDev))
7954 {
7955 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
7956 return VOS_STATUS_E_FAILURE;
7957 }
7958 }
7959 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
7960
7961 return VOS_STATUS_SUCCESS;
7962}
7963
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007964static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07007965{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007966 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007967
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007968 if (NULL == pAdapter)
7969 {
7970 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
7971 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07007972 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007973
7974 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7975 {
7976 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
7977 return eHAL_STATUS_NOT_INITIALIZED;
7978 }
7979
7980 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
7981
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007982#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007983 /* need to make sure all of our scheduled work has completed.
7984 * This callback is called from MC thread context, so it is safe to
7985 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007986 *
7987 * Even though this is called from MC thread context, if there is a faulty
7988 * work item in the system, that can hang this call forever. So flushing
7989 * this global work queue is not safe; and now we make sure that
7990 * individual work queues are stopped correctly. But the cancel work queue
7991 * is a GPL only API, so the proprietary version of the driver would still
7992 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007993 */
7994 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007995#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007996
7997 /* We can be blocked while waiting for scheduled work to be
7998 * flushed, and the adapter structure can potentially be freed, in
7999 * which case the magic will have been reset. So make sure the
8000 * magic is still good, and hence the adapter structure is still
8001 * valid, before signaling completion */
8002 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
8003 {
8004 complete(&pAdapter->session_close_comp_var);
8005 }
8006
Jeff Johnson295189b2012-06-20 16:38:30 -07008007 return eHAL_STATUS_SUCCESS;
8008}
Manjeet Singh47ee8472016-04-11 11:57:18 +05308009/**
8010 * hdd_close_tx_queues() - close tx queues
8011 * @hdd_ctx: hdd global context
8012 *
8013 * Return: None
8014 */
8015static void hdd_close_tx_queues(hdd_context_t *hdd_ctx)
8016{
8017 VOS_STATUS status;
8018 hdd_adapter_t *adapter;
8019 hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter = NULL;
8020 /* Not validating hdd_ctx as it's already done by the caller */
8021 ENTER();
8022 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
8023 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
8024 adapter = adapter_node->pAdapter;
8025 if (adapter && adapter->dev) {
8026 netif_tx_disable (adapter->dev);
8027 netif_carrier_off(adapter->dev);
8028 }
8029 status = hdd_get_next_adapter(hdd_ctx, adapter_node,
8030 &next_adapter);
8031 adapter_node = next_adapter;
8032 }
8033 EXIT();
8034}
Jeff Johnson295189b2012-06-20 16:38:30 -07008035
8036VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
8037{
8038 struct net_device *pWlanDev = pAdapter->dev;
8039 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
8040 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
8041 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
8042 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308043 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008044
Nirav Shah7e3c8132015-06-22 23:51:42 +05308045 spin_lock_init( &pAdapter->sta_hash_lock);
8046 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
8047
Jeff Johnson295189b2012-06-20 16:38:30 -07008048 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07008049 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008050 //Open a SME session for future operation
8051 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07008052 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008053 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8054 {
8055 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008056 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008057 halStatus, halStatus );
8058 status = VOS_STATUS_E_FAILURE;
8059 goto error_sme_open;
8060 }
8061
8062 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05308063 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008064 &pAdapter->session_open_comp_var,
8065 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308066 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008067 {
8068 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308069 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07008070 status = VOS_STATUS_E_FAILURE;
8071 goto error_sme_open;
8072 }
8073
8074 // Register wireless extensions
8075 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
8076 {
8077 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008078 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008079 halStatus, halStatus );
8080 status = VOS_STATUS_E_FAILURE;
8081 goto error_register_wext;
8082 }
Katya Nigam1fd24402015-02-16 14:52:19 +05308083
Jeff Johnson295189b2012-06-20 16:38:30 -07008084 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05308085 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
8086 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
8087 #else
8088 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
8089 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008090
8091 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05308092 hddLog(VOS_TRACE_LEVEL_INFO,
8093 "%s: Set HDD connState to eConnectionState_NotConnected",
8094 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008095 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
8096
8097 //Set the default operation channel
8098 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
8099
8100 /* Make the default Auth Type as OPEN*/
8101 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
8102
8103 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
8104 {
8105 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008106 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008107 status, status );
8108 goto error_init_txrx;
8109 }
8110
8111 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8112
8113 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
8114 {
8115 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008116 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008117 status, status );
8118 goto error_wmm_init;
8119 }
8120
8121 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
8122
8123 return VOS_STATUS_SUCCESS;
8124
8125error_wmm_init:
8126 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8127 hdd_deinit_tx_rx(pAdapter);
8128error_init_txrx:
8129 hdd_UnregisterWext(pWlanDev);
8130error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008131 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07008132 {
8133 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008134 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05308135 pAdapter->sessionId, FALSE, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008136 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07008137 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308138 unsigned long rc;
8139
Jeff Johnson295189b2012-06-20 16:38:30 -07008140 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308141 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008142 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008143 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308144 if (rc <= 0)
8145 hddLog(VOS_TRACE_LEVEL_ERROR,
8146 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07008147 }
8148}
8149error_sme_open:
8150 return status;
8151}
8152
Jeff Johnson295189b2012-06-20 16:38:30 -07008153void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
8154{
8155 hdd_cfg80211_state_t *cfgState;
8156
8157 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
8158
8159 if( NULL != cfgState->buf )
8160 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308161 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07008162 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
8163 rc = wait_for_completion_interruptible_timeout(
8164 &pAdapter->tx_action_cnf_event,
8165 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308166 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008167 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05308168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8169 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
8170 , __func__, rc);
8171
8172 // Inform tx status as FAILURE to upper layer and free cfgState->buf
8173 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008174 }
8175 }
8176 return;
8177}
Jeff Johnson295189b2012-06-20 16:38:30 -07008178
c_hpothu002231a2015-02-05 14:58:51 +05308179void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07008180{
8181 ENTER();
8182 switch ( pAdapter->device_mode )
8183 {
Katya Nigam1fd24402015-02-16 14:52:19 +05308184 case WLAN_HDD_IBSS:
8185 {
8186 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8187 {
8188 hdd_ibss_deinit_tx_rx( pAdapter );
8189 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8190 }
8191 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008192 case WLAN_HDD_INFRA_STATION:
8193 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07008194 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07008195 {
8196 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8197 {
8198 hdd_deinit_tx_rx( pAdapter );
8199 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8200 }
8201
8202 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
8203 {
8204 hdd_wmm_adapter_close( pAdapter );
8205 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
8206 }
8207
Jeff Johnson295189b2012-06-20 16:38:30 -07008208 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008209 break;
8210 }
8211
8212 case WLAN_HDD_SOFTAP:
8213 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008214 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05308215
8216 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
8217 {
8218 hdd_wmm_adapter_close( pAdapter );
8219 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
8220 }
8221
Jeff Johnson295189b2012-06-20 16:38:30 -07008222 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008223
c_hpothu002231a2015-02-05 14:58:51 +05308224 hdd_unregister_hostapd(pAdapter, rtnl_held);
Agrawal Ashisha0584d42016-09-29 13:03:45 +05308225 /* set con_mode to STA only when no SAP concurrency mode */
8226 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
8227 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07008228 break;
8229 }
8230
8231 case WLAN_HDD_MONITOR:
8232 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008233 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8234 {
8235 hdd_deinit_tx_rx( pAdapter );
8236 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8237 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008238 break;
8239 }
8240
8241
8242 default:
8243 break;
8244 }
8245
8246 EXIT();
8247}
8248
8249void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
8250{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008251 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308252
8253 ENTER();
8254 if (NULL == pAdapter)
8255 {
8256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8257 "%s: HDD adapter is Null", __func__);
8258 return;
8259 }
8260
8261 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07008262
Rajeev79dbe4c2013-10-05 11:03:42 +05308263#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308264 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8265 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08008266 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308267 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
8268 )
8269 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08008270 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05308271 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08008272 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
8273 {
8274 hdd_deinit_batch_scan(pAdapter);
8275 }
Rajeev79dbe4c2013-10-05 11:03:42 +05308276 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08008277 }
Rajeev79dbe4c2013-10-05 11:03:42 +05308278#endif
8279
Jeff Johnson295189b2012-06-20 16:38:30 -07008280 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
8281 if( rtnl_held )
8282 {
8283 unregister_netdevice(pWlanDev);
8284 }
8285 else
8286 {
8287 unregister_netdev(pWlanDev);
8288 }
8289 // note that the pAdapter is no longer valid at this point
8290 // since the memory has been reclaimed
8291 }
8292
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308293 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008294}
8295
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008296void hdd_set_pwrparams(hdd_context_t *pHddCtx)
8297{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308298 VOS_STATUS status;
8299 hdd_adapter_t *pAdapter = NULL;
8300 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008301
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308302 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008303
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308304 /*loop through all adapters.*/
8305 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008306 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308307 pAdapter = pAdapterNode->pAdapter;
8308 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
8309 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008310
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308311 { // we skip this registration for modes other than STA and P2P client modes.
8312 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8313 pAdapterNode = pNext;
8314 continue;
8315 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008316
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308317 //Apply Dynamic DTIM For P2P
8318 //Only if ignoreDynamicDtimInP2pMode is not set in ini
8319 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
8320 pHddCtx->cfg_ini->enableModulatedDTIM) &&
8321 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8322 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
8323 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
8324 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
8325 (eConnectionState_Associated ==
8326 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
8327 (pHddCtx->cfg_ini->fIsBmpsEnabled))
8328 {
8329 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008330
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308331 powerRequest.uIgnoreDTIM = 1;
8332 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
8333
8334 if (pHddCtx->cfg_ini->enableModulatedDTIM)
8335 {
8336 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
8337 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
8338 }
8339 else
8340 {
8341 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
8342 }
8343
8344 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
8345 * specified during Enter/Exit BMPS when LCD off*/
8346 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
8347 NULL, eANI_BOOLEAN_FALSE);
8348 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
8349 NULL, eANI_BOOLEAN_FALSE);
8350
8351 /* switch to the DTIM specified in cfg.ini */
8352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05308353 "Switch to DTIM %d Listen interval %d",
8354 powerRequest.uDTIMPeriod,
8355 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308356 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
8357 break;
8358
8359 }
8360
8361 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8362 pAdapterNode = pNext;
8363 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008364}
8365
8366void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
8367{
8368 /*Switch back to DTIM 1*/
8369 tSirSetPowerParamsReq powerRequest = { 0 };
8370
8371 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
8372 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07008373 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008374
8375 /* Update ignoreDTIM and ListedInterval in CFG with default values */
8376 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
8377 NULL, eANI_BOOLEAN_FALSE);
8378 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
8379 NULL, eANI_BOOLEAN_FALSE);
8380
8381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8382 "Switch to DTIM%d",powerRequest.uListenInterval);
8383 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
8384
8385}
8386
Jeff Johnson295189b2012-06-20 16:38:30 -07008387VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
8388{
8389 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05308390 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
8391 {
8392 hddLog( LOGE, FL("Wlan Unload in progress"));
8393 return VOS_STATUS_E_PERM;
8394 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008395 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
8396 {
8397 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8398 }
8399
8400 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
8401 {
8402 sme_StartAutoBmpsTimer(pHddCtx->hHal);
8403 }
8404
8405 if (pHddCtx->cfg_ini->fIsImpsEnabled)
8406 {
8407 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8408 }
8409
8410 return status;
8411}
8412
8413VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
8414{
8415 hdd_adapter_t *pAdapter = NULL;
8416 eHalStatus halStatus;
8417 VOS_STATUS status = VOS_STATUS_E_INVAL;
8418 v_BOOL_t disableBmps = FALSE;
8419 v_BOOL_t disableImps = FALSE;
8420
8421 switch(session_type)
8422 {
8423 case WLAN_HDD_INFRA_STATION:
8424 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008425 case WLAN_HDD_P2P_CLIENT:
8426 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008427 //Exit BMPS -> Is Sta/P2P Client is already connected
8428 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
8429 if((NULL != pAdapter)&&
8430 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8431 {
8432 disableBmps = TRUE;
8433 }
8434
8435 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
8436 if((NULL != pAdapter)&&
8437 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8438 {
8439 disableBmps = TRUE;
8440 }
8441
8442 //Exit both Bmps and Imps incase of Go/SAP Mode
8443 if((WLAN_HDD_SOFTAP == session_type) ||
8444 (WLAN_HDD_P2P_GO == session_type))
8445 {
8446 disableBmps = TRUE;
8447 disableImps = TRUE;
8448 }
8449
8450 if(TRUE == disableImps)
8451 {
8452 if (pHddCtx->cfg_ini->fIsImpsEnabled)
8453 {
8454 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8455 }
8456 }
8457
8458 if(TRUE == disableBmps)
8459 {
8460 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
8461 {
8462 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8463
8464 if(eHAL_STATUS_SUCCESS != halStatus)
8465 {
8466 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008467 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008468 VOS_ASSERT(0);
8469 return status;
8470 }
8471 }
8472
8473 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
8474 {
8475 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
8476
8477 if(eHAL_STATUS_SUCCESS != halStatus)
8478 {
8479 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008480 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008481 VOS_ASSERT(0);
8482 return status;
8483 }
8484 }
8485 }
8486
8487 if((TRUE == disableBmps) ||
8488 (TRUE == disableImps))
8489 {
8490 /* Now, get the chip into Full Power now */
8491 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
8492 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
8493 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
8494
8495 if(halStatus != eHAL_STATUS_SUCCESS)
8496 {
8497 if(halStatus == eHAL_STATUS_PMC_PENDING)
8498 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308499 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008500 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308501 ret = wait_for_completion_interruptible_timeout(
8502 &pHddCtx->full_pwr_comp_var,
8503 msecs_to_jiffies(1000));
8504 if (ret <= 0)
8505 {
8506 hddLog(VOS_TRACE_LEVEL_ERROR,
8507 "%s: wait on full_pwr_comp_var failed %ld",
8508 __func__, ret);
8509 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008510 }
8511 else
8512 {
8513 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008514 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008515 VOS_ASSERT(0);
8516 return status;
8517 }
8518 }
8519
8520 status = VOS_STATUS_SUCCESS;
8521 }
8522
8523 break;
8524 }
8525 return status;
8526}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308527
8528void hdd_monPostMsgCb(tANI_U32 *magic, struct completion *cmpVar)
8529{
8530 if (magic == NULL || cmpVar == NULL) {
8531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8532 FL("invalid arguments %p %p"), magic, cmpVar);
8533 return;
8534 }
8535 if (*magic != MON_MODE_MSG_MAGIC) {
8536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8537 FL("maic: %x"), *magic);
8538 return;
8539 }
8540
8541 complete(cmpVar);
8542 return;
8543}
8544
Katya Nigame7b69a82015-04-28 15:24:06 +05308545void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
8546 {
8547 hdd_mon_ctx_t *pMonCtx = NULL;
8548 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
8549
8550 pMonCtx->state = 0;
8551 pMonCtx->ChannelNo = 1;
8552 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05308553 pMonCtx->crcCheckEnabled = 1;
8554 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
8555 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05308556 pMonCtx->numOfMacFilters = 0;
8557 }
8558
Jeff Johnson295189b2012-06-20 16:38:30 -07008559
8560hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08008561 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07008562 tANI_U8 rtnl_held )
8563{
8564 hdd_adapter_t *pAdapter = NULL;
8565 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
8566 VOS_STATUS status = VOS_STATUS_E_FAILURE;
8567 VOS_STATUS exitbmpsStatus;
8568
Arif Hussain6d2a3322013-11-17 19:50:10 -08008569 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008570
Nirav Shah436658f2014-02-28 17:05:45 +05308571 if(macAddr == NULL)
8572 {
8573 /* Not received valid macAddr */
8574 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8575 "%s:Unable to add virtual intf: Not able to get"
8576 "valid mac address",__func__);
8577 return NULL;
8578 }
8579
Jeff Johnson295189b2012-06-20 16:38:30 -07008580 //Disable BMPS incase of Concurrency
8581 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
8582
8583 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
8584 {
8585 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308586 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008587 VOS_ASSERT(0);
8588 return NULL;
8589 }
8590
8591 switch(session_type)
8592 {
8593 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008594 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07008595 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07008596 {
8597 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8598
8599 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308600 {
8601 hddLog(VOS_TRACE_LEVEL_FATAL,
8602 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008603 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308604 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008605
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308606#ifdef FEATURE_WLAN_TDLS
8607 /* A Mutex Lock is introduced while changing/initializing the mode to
8608 * protect the concurrent access for the Adapters by TDLS module.
8609 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308610 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308611#endif
8612
Jeff Johnsone7245742012-09-05 17:12:55 -07008613 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
8614 NL80211_IFTYPE_P2P_CLIENT:
8615 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07008616
Jeff Johnson295189b2012-06-20 16:38:30 -07008617 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308618#ifdef FEATURE_WLAN_TDLS
8619 mutex_unlock(&pHddCtx->tdls_lock);
8620#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308621
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308622 hdd_initialize_adapter_common(pAdapter);
Sunil Dutt66485cb2013-12-19 19:05:03 +05308623 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008624 if( VOS_STATUS_SUCCESS != status )
8625 goto err_free_netdev;
8626
8627 status = hdd_register_interface( pAdapter, rtnl_held );
8628 if( VOS_STATUS_SUCCESS != status )
8629 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308630#ifdef FEATURE_WLAN_TDLS
8631 mutex_lock(&pHddCtx->tdls_lock);
8632#endif
c_hpothu002231a2015-02-05 14:58:51 +05308633 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308634#ifdef FEATURE_WLAN_TDLS
8635 mutex_unlock(&pHddCtx->tdls_lock);
8636#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008637 goto err_free_netdev;
8638 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308639
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05308640 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308641 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05308642
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308643#ifdef WLAN_NS_OFFLOAD
8644 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308645 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308646#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008647 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308648 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008649 netif_tx_disable(pAdapter->dev);
8650 //netif_tx_disable(pWlanDev);
8651 netif_carrier_off(pAdapter->dev);
8652
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308653 if (WLAN_HDD_P2P_CLIENT == session_type ||
8654 WLAN_HDD_P2P_DEVICE == session_type)
8655 {
8656 /* Initialize the work queue to defer the
8657 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308658 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308659 hdd_p2p_roc_work_queue);
8660 }
8661
Jeff Johnson295189b2012-06-20 16:38:30 -07008662 break;
8663 }
8664
Jeff Johnson295189b2012-06-20 16:38:30 -07008665 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008666 case WLAN_HDD_SOFTAP:
8667 {
8668 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
8669 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308670 {
8671 hddLog(VOS_TRACE_LEVEL_FATAL,
8672 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008673 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308674 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008675
Jeff Johnson295189b2012-06-20 16:38:30 -07008676 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
8677 NL80211_IFTYPE_AP:
8678 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008679 pAdapter->device_mode = session_type;
8680
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308681 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008682 status = hdd_init_ap_mode(pAdapter);
8683 if( VOS_STATUS_SUCCESS != status )
8684 goto err_free_netdev;
8685
Nirav Shah7e3c8132015-06-22 23:51:42 +05308686 status = hdd_sta_id_hash_attach(pAdapter);
8687 if (VOS_STATUS_SUCCESS != status)
8688 {
8689 hddLog(VOS_TRACE_LEVEL_FATAL,
8690 FL("failed to attach hash for session %d"), session_type);
8691 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
8692 goto err_free_netdev;
8693 }
8694
Jeff Johnson295189b2012-06-20 16:38:30 -07008695 status = hdd_register_hostapd( pAdapter, rtnl_held );
8696 if( VOS_STATUS_SUCCESS != status )
8697 {
c_hpothu002231a2015-02-05 14:58:51 +05308698 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07008699 goto err_free_netdev;
8700 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308701 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008702 netif_tx_disable(pAdapter->dev);
8703 netif_carrier_off(pAdapter->dev);
8704
8705 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308706
8707 if (WLAN_HDD_P2P_GO == session_type)
8708 {
8709 /* Initialize the work queue to
8710 * defer the back to back RoC request */
8711 INIT_DELAYED_WORK(&pAdapter->roc_work,
8712 hdd_p2p_roc_work_queue);
8713 }
Bhargav Shahd0715912015-10-01 18:17:37 +05308714
Jeff Johnson295189b2012-06-20 16:38:30 -07008715 break;
8716 }
8717 case WLAN_HDD_MONITOR:
8718 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008719 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8720 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308721 {
8722 hddLog(VOS_TRACE_LEVEL_FATAL,
8723 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008724 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308725 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008726
Katya Nigame7b69a82015-04-28 15:24:06 +05308727 // Register wireless extensions
8728 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
8729 {
8730 hddLog(VOS_TRACE_LEVEL_FATAL,
8731 "hdd_register_wext() failed with status code %08d [x%08x]",
8732 status, status );
8733 status = VOS_STATUS_E_FAILURE;
8734 }
8735
Jeff Johnson295189b2012-06-20 16:38:30 -07008736 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
8737 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008738#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
8739 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
8740#else
8741 pAdapter->dev->open = hdd_mon_open;
8742 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05308743 pAdapter->dev->stop = hdd_mon_stop;
8744 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07008745#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05308746 status = hdd_register_interface( pAdapter, rtnl_held );
8747 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308748 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008749 hdd_init_tx_rx( pAdapter );
8750 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05308751 //Stop the Interface TX queue.
8752 netif_tx_disable(pAdapter->dev);
8753 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008754 }
8755 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07008756 case WLAN_HDD_FTM:
8757 {
8758 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8759
8760 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308761 {
8762 hddLog(VOS_TRACE_LEVEL_FATAL,
8763 FL("failed to allocate adapter for session %d"), session_type);
8764 return NULL;
8765 }
8766
Jeff Johnson295189b2012-06-20 16:38:30 -07008767 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
8768 * message while loading driver in FTM mode. */
8769 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
8770 pAdapter->device_mode = session_type;
8771 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05308772
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308773 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05308774 hdd_init_tx_rx( pAdapter );
8775
8776 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308777 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05308778 netif_tx_disable(pAdapter->dev);
8779 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008780 }
8781 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07008782 default:
8783 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308784 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
8785 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008786 VOS_ASSERT(0);
8787 return NULL;
8788 }
8789 }
8790
Jeff Johnson295189b2012-06-20 16:38:30 -07008791 if( VOS_STATUS_SUCCESS == status )
8792 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308793 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -07008794 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
8795 if( NULL == pHddAdapterNode )
8796 {
8797 status = VOS_STATUS_E_NOMEM;
8798 }
8799 else
8800 {
8801 pHddAdapterNode->pAdapter = pAdapter;
8802 status = hdd_add_adapter_back ( pHddCtx,
8803 pHddAdapterNode );
8804 }
8805 }
8806
8807 if( VOS_STATUS_SUCCESS != status )
8808 {
8809 if( NULL != pAdapter )
8810 {
8811 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
8812 pAdapter = NULL;
8813 }
8814 if( NULL != pHddAdapterNode )
8815 {
8816 vos_mem_free( pHddAdapterNode );
8817 }
8818
8819 goto resume_bmps;
8820 }
8821
8822 if(VOS_STATUS_SUCCESS == status)
8823 {
8824 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
8825
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07008826 //Initialize the WoWL service
8827 if(!hdd_init_wowl(pAdapter))
8828 {
8829 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
8830 goto err_free_netdev;
8831 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008832 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008833 return pAdapter;
8834
8835err_free_netdev:
8836 free_netdev(pAdapter->dev);
8837 wlan_hdd_release_intf_addr( pHddCtx,
8838 pAdapter->macAddressCurrent.bytes );
8839
8840resume_bmps:
8841 //If bmps disabled enable it
8842 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
8843 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308844 if (pHddCtx->hdd_wlan_suspended)
8845 {
8846 hdd_set_pwrparams(pHddCtx);
8847 }
8848 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008849 }
8850 return NULL;
8851}
8852
8853VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
8854 tANI_U8 rtnl_held )
8855{
8856 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
8857 VOS_STATUS status;
8858
8859 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
8860 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308861 {
8862 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
8863 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008864 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308865 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008866
8867 while ( pCurrent->pAdapter != pAdapter )
8868 {
8869 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
8870 if( VOS_STATUS_SUCCESS != status )
8871 break;
8872
8873 pCurrent = pNext;
8874 }
8875 pAdapterNode = pCurrent;
8876 if( VOS_STATUS_SUCCESS == status )
8877 {
8878 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8879 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308880
8881#ifdef FEATURE_WLAN_TDLS
8882
8883 /* A Mutex Lock is introduced while changing/initializing the mode to
8884 * protect the concurrent access for the Adapters by TDLS module.
8885 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308886 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308887#endif
8888
Jeff Johnson295189b2012-06-20 16:38:30 -07008889 hdd_remove_adapter( pHddCtx, pAdapterNode );
8890 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008891 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008892
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308893#ifdef FEATURE_WLAN_TDLS
8894 mutex_unlock(&pHddCtx->tdls_lock);
8895#endif
8896
Jeff Johnson295189b2012-06-20 16:38:30 -07008897
8898 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05308899 if ((!vos_concurrent_open_sessions_running()) &&
8900 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
8901 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008902 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308903 if (pHddCtx->hdd_wlan_suspended)
8904 {
8905 hdd_set_pwrparams(pHddCtx);
8906 }
8907 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008908 }
8909
8910 return VOS_STATUS_SUCCESS;
8911 }
8912
8913 return VOS_STATUS_E_FAILURE;
8914}
8915
8916VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
8917{
8918 hdd_adapter_list_node_t *pHddAdapterNode;
8919 VOS_STATUS status;
8920
8921 ENTER();
8922
8923 do
8924 {
8925 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
8926 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
8927 {
8928 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
8929 vos_mem_free( pHddAdapterNode );
8930 }
8931 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
8932
8933 EXIT();
8934
8935 return VOS_STATUS_SUCCESS;
8936}
8937
8938void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
8939{
8940 v_U8_t addIE[1] = {0};
8941
8942 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8943 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
8944 eANI_BOOLEAN_FALSE) )
8945 {
8946 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008947 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008948 }
8949
8950 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8951 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8952 eANI_BOOLEAN_FALSE) )
8953 {
8954 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008955 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008956 }
8957
8958 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8959 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8960 eANI_BOOLEAN_FALSE) )
8961 {
8962 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008963 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008964 }
8965}
8966
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308967VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
8968 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07008969{
8970 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
8971 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308972 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008973 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05308974 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308975 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05308976 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008977
Anand N Sunkad26d71b92014-12-24 18:08:22 +05308978 if (pHddCtx->isLogpInProgress) {
8979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8980 "%s:LOGP in Progress. Ignore!!!",__func__);
8981 return VOS_STATUS_E_FAILURE;
8982 }
8983
Jeff Johnson295189b2012-06-20 16:38:30 -07008984 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308985
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308986 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07008987 switch(pAdapter->device_mode)
8988 {
Nirav Shah0cf4d892015-11-05 16:27:27 +05308989 case WLAN_HDD_IBSS:
8990 if ( VOS_TRUE == bCloseSession )
8991 {
8992 status = hdd_sta_id_hash_detach(pAdapter);
8993 if (status != VOS_STATUS_SUCCESS)
8994 hddLog(VOS_TRACE_LEVEL_ERROR,
8995 FL("sta id hash detach failed"));
8996 }
8997
Jeff Johnson295189b2012-06-20 16:38:30 -07008998 case WLAN_HDD_INFRA_STATION:
8999 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009000 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309001 {
9002 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05309003#ifdef FEATURE_WLAN_TDLS
9004 mutex_lock(&pHddCtx->tdls_lock);
9005 wlan_hdd_tdls_exit(pAdapter, TRUE);
9006 mutex_unlock(&pHddCtx->tdls_lock);
9007#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309008 if( hdd_connIsConnected(pstation) ||
9009 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009010 {
9011 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
9012 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
9013 pAdapter->sessionId,
9014 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
9015 else
9016 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
9017 pAdapter->sessionId,
9018 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Abhishek Singh7b52ed52016-02-11 17:45:54 +05309019 /* Success implies disconnect command got queued up successfully
9020 * Or cmd not queued as scan for SSID is in progress
9021 */
9022 if((eHAL_STATUS_SUCCESS == halStatus) ||
9023 (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07009024 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309025 ret = wait_for_completion_interruptible_timeout(
9026 &pAdapter->disconnect_comp_var,
9027 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singh7b52ed52016-02-11 17:45:54 +05309028 if (ret <= 0 &&
9029 (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309030 {
9031 hddLog(VOS_TRACE_LEVEL_ERROR,
9032 "%s: wait on disconnect_comp_var failed %ld",
9033 __func__, ret);
9034 }
9035 }
9036 else
9037 {
9038 hddLog(LOGE, "%s: failed to post disconnect event to SME",
9039 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009040 }
9041 memset(&wrqu, '\0', sizeof(wrqu));
9042 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
9043 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
9044 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
9045 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309046 else if(pstation->conn_info.connState ==
9047 eConnectionState_Disconnecting)
9048 {
9049 ret = wait_for_completion_interruptible_timeout(
9050 &pAdapter->disconnect_comp_var,
9051 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
9052 if (ret <= 0)
9053 {
9054 hddLog(VOS_TRACE_LEVEL_ERROR,
9055 FL("wait on disconnect_comp_var failed %ld"), ret);
9056 }
9057 }
Sachin Ahuja27dd2402016-08-01 20:30:31 +05309058 if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07009059 {
Mahesh A Saptasagar0b61dcc2016-02-15 14:23:38 +05309060 wlan_hdd_scan_abort(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009061 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +05309062 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
9063 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309064 {
9065 while (pAdapter->is_roc_inprogress)
9066 {
9067 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9068 "%s: ROC in progress for session %d!!!",
9069 __func__, pAdapter->sessionId);
9070 // waiting for ROC to expire
9071 msleep(500);
9072 /* In GO present case , if retry exceeds 3,
9073 it means something went wrong. */
9074 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
9075 {
9076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9077 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05309078 if (eHAL_STATUS_SUCCESS !=
9079 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
9080 pAdapter->sessionId ))
9081 {
9082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9083 FL("Failed to Cancel Remain on Channel"));
9084 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309085 wait_for_completion_interruptible_timeout(
9086 &pAdapter->cancel_rem_on_chan_var,
9087 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
9088 break;
9089 }
9090 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309091 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309092 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309093#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309094 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309095#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309096
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309097 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309098
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309099 /* It is possible that the caller of this function does not
9100 * wish to close the session
9101 */
9102 if (VOS_TRUE == bCloseSession &&
9103 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009104 {
9105 INIT_COMPLETION(pAdapter->session_close_comp_var);
9106 if (eHAL_STATUS_SUCCESS ==
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05309107 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, FALSE,
9108 VOS_FALSE, hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07009109 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309110 unsigned long ret;
9111
Jeff Johnson295189b2012-06-20 16:38:30 -07009112 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309113 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309114 &pAdapter->session_close_comp_var,
9115 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309116 if ( 0 >= ret)
9117 {
9118 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309119 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309120 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009121 }
9122 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309123 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009124 break;
9125
9126 case WLAN_HDD_SOFTAP:
9127 case WLAN_HDD_P2P_GO:
Nirav Shah0cf4d892015-11-05 16:27:27 +05309128 if ( VOS_TRUE == bCloseSession )
9129 {
9130 status = hdd_sta_id_hash_detach(pAdapter);
9131 if (status != VOS_STATUS_SUCCESS)
9132 hddLog(VOS_TRACE_LEVEL_ERROR,
9133 FL("sta id hash detach failed"));
9134 }
9135
Jeff Johnson295189b2012-06-20 16:38:30 -07009136 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309137 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
9138 while (pAdapter->is_roc_inprogress) {
9139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9140 "%s: ROC in progress for session %d!!!",
9141 __func__, pAdapter->sessionId);
9142 msleep(500);
9143 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
9144 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9145 "%s: ROC completion is not received.!!!", __func__);
9146 WLANSAP_CancelRemainOnChannel(
9147 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
9148 wait_for_completion_interruptible_timeout(
9149 &pAdapter->cancel_rem_on_chan_var,
9150 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
9151 break;
9152 }
9153 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309154
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309155 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309156 }
Agrawal Ashish17ef5082016-10-17 18:33:21 +05309157#ifdef SAP_AUTH_OFFLOAD
9158 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
9159 hdd_set_sap_auth_offload(pAdapter, FALSE);
9160#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009161 mutex_lock(&pHddCtx->sap_lock);
9162 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9163 {
9164 VOS_STATUS status;
9165 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9166
9167 //Stop Bss.
9168 status = WLANSAP_StopBss(pHddCtx->pvosContext);
9169 if (VOS_IS_STATUS_SUCCESS(status))
9170 {
9171 hdd_hostapd_state_t *pHostapdState =
9172 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9173
9174 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9175
9176 if (!VOS_IS_STATUS_SUCCESS(status))
9177 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309178 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
9179 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009180 }
9181 }
9182 else
9183 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009184 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009185 }
9186 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309187 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009188
9189 if (eHAL_STATUS_FAILURE ==
9190 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
9191 0, NULL, eANI_BOOLEAN_FALSE))
9192 {
9193 hddLog(LOGE,
9194 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009195 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009196 }
9197
9198 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
9199 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9200 eANI_BOOLEAN_FALSE) )
9201 {
9202 hddLog(LOGE,
9203 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
9204 }
9205
9206 // Reset WNI_CFG_PROBE_RSP Flags
9207 wlan_hdd_reset_prob_rspies(pAdapter);
9208 kfree(pAdapter->sessionCtx.ap.beacon);
9209 pAdapter->sessionCtx.ap.beacon = NULL;
9210 }
9211 mutex_unlock(&pHddCtx->sap_lock);
9212 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009213
Jeff Johnson295189b2012-06-20 16:38:30 -07009214 case WLAN_HDD_MONITOR:
9215 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009216
Jeff Johnson295189b2012-06-20 16:38:30 -07009217 default:
9218 break;
9219 }
9220
9221 EXIT();
9222 return VOS_STATUS_SUCCESS;
9223}
9224
9225VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
9226{
9227 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9228 VOS_STATUS status;
9229 hdd_adapter_t *pAdapter;
9230
9231 ENTER();
9232
9233 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9234
9235 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9236 {
9237 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009238
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309239 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009240
9241 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9242 pAdapterNode = pNext;
9243 }
9244
9245 EXIT();
9246
9247 return VOS_STATUS_SUCCESS;
9248}
9249
Rajeev Kumarf999e582014-01-09 17:33:29 -08009250
9251#ifdef FEATURE_WLAN_BATCH_SCAN
9252/**---------------------------------------------------------------------------
9253
9254 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
9255 structures
9256
9257 \param - pAdapter Pointer to HDD adapter
9258
9259 \return - None
9260
9261 --------------------------------------------------------------------------*/
9262void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
9263{
9264 tHddBatchScanRsp *pNode;
9265 tHddBatchScanRsp *pPrev;
9266
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05309267 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08009268 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05309269 hddLog(VOS_TRACE_LEVEL_ERROR,
9270 "%s: Adapter context is Null", __func__);
9271 return;
9272 }
9273
9274 pNode = pAdapter->pBatchScanRsp;
9275 while (pNode)
9276 {
9277 pPrev = pNode;
9278 pNode = pNode->pNext;
9279 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08009280 }
9281
9282 pAdapter->pBatchScanRsp = NULL;
9283 pAdapter->numScanList = 0;
9284 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
9285 pAdapter->prev_batch_id = 0;
9286
9287 return;
9288}
9289#endif
9290
9291
Jeff Johnson295189b2012-06-20 16:38:30 -07009292VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
9293{
9294 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9295 VOS_STATUS status;
9296 hdd_adapter_t *pAdapter;
9297
9298 ENTER();
9299
9300 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9301
9302 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9303 {
9304 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309305 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009306 netif_tx_disable(pAdapter->dev);
9307 netif_carrier_off(pAdapter->dev);
9308
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07009309 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
9310
Jeff Johnson295189b2012-06-20 16:38:30 -07009311 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05309312
Katya Nigam1fd24402015-02-16 14:52:19 +05309313 if(pAdapter->device_mode == WLAN_HDD_IBSS )
9314 hdd_ibss_deinit_tx_rx(pAdapter);
9315
Nirav Shah7e3c8132015-06-22 23:51:42 +05309316 status = hdd_sta_id_hash_detach(pAdapter);
9317 if (status != VOS_STATUS_SUCCESS)
9318 hddLog(VOS_TRACE_LEVEL_ERROR,
9319 FL("sta id hash detach failed for session id %d"),
9320 pAdapter->sessionId);
9321
Agarwal Ashish6267caa2014-08-06 19:16:21 +05309322 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
9323
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05309324 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9325 {
9326 hdd_wmm_adapter_close( pAdapter );
9327 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9328 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009329
Siddharth Bhal2db319d2014-12-03 12:37:18 +05309330 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9331 {
9332 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
9333 }
9334
Rajeev Kumarf999e582014-01-09 17:33:29 -08009335#ifdef FEATURE_WLAN_BATCH_SCAN
9336 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
9337 {
9338 hdd_deinit_batch_scan(pAdapter);
9339 }
9340#endif
9341
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05309342#ifdef FEATURE_WLAN_TDLS
9343 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05309344 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05309345 mutex_unlock(&pHddCtx->tdls_lock);
9346#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009347 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9348 pAdapterNode = pNext;
9349 }
9350
9351 EXIT();
9352
9353 return VOS_STATUS_SUCCESS;
9354}
9355
9356VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
9357{
9358 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9359 VOS_STATUS status;
9360 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309361 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07009362
9363 ENTER();
9364
9365 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9366
9367 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9368 {
9369 pAdapter = pAdapterNode->pAdapter;
9370
Kumar Anand82c009f2014-05-29 00:29:42 -07009371 hdd_wmm_init( pAdapter );
9372
Jeff Johnson295189b2012-06-20 16:38:30 -07009373 switch(pAdapter->device_mode)
9374 {
9375 case WLAN_HDD_INFRA_STATION:
9376 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009377 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309378
9379 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
9380
Jeff Johnson295189b2012-06-20 16:38:30 -07009381 hdd_init_station_mode(pAdapter);
9382 /* Open the gates for HDD to receive Wext commands */
9383 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009384 pHddCtx->scan_info.mScanPending = FALSE;
9385 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009386
9387 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +05309388 if (!pHddCtx->isLogpInProgress)
9389 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009390
9391 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309392 if (eConnectionState_Associated == connState ||
9393 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07009394 {
9395 union iwreq_data wrqu;
9396 memset(&wrqu, '\0', sizeof(wrqu));
9397 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
9398 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
9399 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07009400 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009401
Jeff Johnson295189b2012-06-20 16:38:30 -07009402 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagar9ff4bcc2016-06-01 17:17:50 +05309403 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, false,
Mahesh A Saptasagarb5a15142016-05-25 11:27:43 +05309404 WLAN_REASON_UNSPECIFIED);
Jeff Johnson295189b2012-06-20 16:38:30 -07009405 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309406 else if (eConnectionState_Connecting == connState)
9407 {
9408 /*
9409 * Indicate connect failure to supplicant if we were in the
9410 * process of connecting
9411 */
9412 cfg80211_connect_result(pAdapter->dev, NULL,
9413 NULL, 0, NULL, 0,
9414 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
9415 GFP_KERNEL);
9416 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009417 break;
9418
9419 case WLAN_HDD_SOFTAP:
9420 /* softAP can handle SSR */
9421 break;
9422
9423 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07009424 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07009425 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07009426 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009427 break;
9428
9429 case WLAN_HDD_MONITOR:
9430 /* monitor interface start */
9431 break;
9432 default:
9433 break;
9434 }
9435
9436 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9437 pAdapterNode = pNext;
9438 }
9439
9440 EXIT();
9441
9442 return VOS_STATUS_SUCCESS;
9443}
9444
9445VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
9446{
9447 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9448 hdd_adapter_t *pAdapter;
9449 VOS_STATUS status;
9450 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309451 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009452
9453 ENTER();
9454
9455 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9456
9457 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9458 {
9459 pAdapter = pAdapterNode->pAdapter;
9460
9461 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9462 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9463 {
9464 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9465 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9466
Abhishek Singhf4669da2014-05-26 15:07:49 +05309467 hddLog(VOS_TRACE_LEVEL_INFO,
9468 "%s: Set HDD connState to eConnectionState_NotConnected",
9469 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +05309470 spin_lock_bh(&pAdapter->lock_for_active_session);
9471 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
9472 {
9473 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
9474 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009475 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +05309476 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07009477 init_completion(&pAdapter->disconnect_comp_var);
9478 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
9479 eCSR_DISCONNECT_REASON_UNSPECIFIED);
9480
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309481 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009482 &pAdapter->disconnect_comp_var,
9483 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309484 if (0 >= ret)
9485 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
9486 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07009487
9488 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
9489 pHddCtx->isAmpAllowed = VOS_FALSE;
9490 sme_RoamConnect(pHddCtx->hHal,
9491 pAdapter->sessionId, &(pWextState->roamProfile),
9492 &roamId);
9493 }
9494
9495 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9496 pAdapterNode = pNext;
9497 }
9498
9499 EXIT();
9500
9501 return VOS_STATUS_SUCCESS;
9502}
9503
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009504void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
9505{
9506 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9507 VOS_STATUS status;
9508 hdd_adapter_t *pAdapter;
9509 hdd_station_ctx_t *pHddStaCtx;
9510 hdd_ap_ctx_t *pHddApCtx;
9511 hdd_hostapd_state_t * pHostapdState;
9512 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
9513 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
9514 const char *p2pMode = "DEV";
9515 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009516
9517 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9518 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9519 {
9520 pAdapter = pAdapterNode->pAdapter;
9521 switch (pAdapter->device_mode) {
9522 case WLAN_HDD_INFRA_STATION:
9523 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9524 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
9525 staChannel = pHddStaCtx->conn_info.operationChannel;
9526 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
9527 }
9528 break;
9529 case WLAN_HDD_P2P_CLIENT:
9530 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9531 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
9532 p2pChannel = pHddStaCtx->conn_info.operationChannel;
9533 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
9534 p2pMode = "CLI";
9535 }
9536 break;
9537 case WLAN_HDD_P2P_GO:
9538 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9539 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9540 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
9541 p2pChannel = pHddApCtx->operatingChannel;
9542 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
9543 }
9544 p2pMode = "GO";
9545 break;
9546 case WLAN_HDD_SOFTAP:
9547 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9548 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9549 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
9550 apChannel = pHddApCtx->operatingChannel;
9551 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
9552 }
9553 break;
9554 default:
9555 break;
9556 }
9557 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9558 pAdapterNode = pNext;
9559 }
9560 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
9561 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
9562 }
SaidiReddy Yenugaa8b32f92016-07-27 19:29:18 +05309563 hddLog(VOS_TRACE_LEVEL_INFO, "wlan(%d) " MAC_ADDRESS_STR " %s",
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009564 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
9565 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05309566 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009567 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
9568 }
9569 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05309570 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009571 apChannel, MAC_ADDR_ARRAY(apBssid));
9572 }
9573
9574 if (p2pChannel > 0 && apChannel > 0) {
9575 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
9576 }
9577}
9578
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009579bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009580{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009581 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07009582}
9583
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009584/* Once SSR is disabled then it cannot be set. */
9585void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07009586{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009587 if (HDD_SSR_DISABLED == isSsrRequired)
9588 return;
9589
Jeff Johnson295189b2012-06-20 16:38:30 -07009590 isSsrRequired = value;
9591}
9592
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05309593void hdd_set_pre_close( hdd_context_t *pHddCtx)
9594{
9595 sme_PreClose(pHddCtx->hHal);
9596}
9597
Jeff Johnson295189b2012-06-20 16:38:30 -07009598VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
9599 hdd_adapter_list_node_t** ppAdapterNode)
9600{
9601 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309602 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009603 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
9604 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309605 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009606 return status;
9607}
9608
9609VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
9610 hdd_adapter_list_node_t* pAdapterNode,
9611 hdd_adapter_list_node_t** pNextAdapterNode)
9612{
9613 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309614 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009615 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
9616 (hdd_list_node_t*) pAdapterNode,
9617 (hdd_list_node_t**)pNextAdapterNode );
9618
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309619 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009620 return status;
9621}
9622
9623VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
9624 hdd_adapter_list_node_t* pAdapterNode)
9625{
9626 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309627 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009628 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
9629 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309630 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009631 return status;
9632}
9633
9634VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
9635 hdd_adapter_list_node_t** ppAdapterNode)
9636{
9637 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309638 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009639 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
9640 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309641 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009642 return status;
9643}
9644
9645VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
9646 hdd_adapter_list_node_t* pAdapterNode)
9647{
9648 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309649 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009650 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
9651 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309652 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009653 return status;
9654}
9655
9656VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
9657 hdd_adapter_list_node_t* pAdapterNode)
9658{
9659 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309660 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009661 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
9662 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309663 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009664 return status;
9665}
9666
9667hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
9668 tSirMacAddr macAddr )
9669{
9670 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9671 hdd_adapter_t *pAdapter;
9672 VOS_STATUS status;
9673
9674 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9675
9676 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9677 {
9678 pAdapter = pAdapterNode->pAdapter;
9679
9680 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
9681 macAddr, sizeof(tSirMacAddr) ) )
9682 {
9683 return pAdapter;
9684 }
9685 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9686 pAdapterNode = pNext;
9687 }
9688
9689 return NULL;
9690
9691}
9692
9693hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
9694{
9695 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9696 hdd_adapter_t *pAdapter;
9697 VOS_STATUS status;
9698
9699 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9700
9701 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9702 {
9703 pAdapter = pAdapterNode->pAdapter;
9704
9705 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
9706 IFNAMSIZ ) )
9707 {
9708 return pAdapter;
9709 }
9710 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9711 pAdapterNode = pNext;
9712 }
9713
9714 return NULL;
9715
9716}
9717
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +05309718hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
9719 tANI_U32 sme_session_id )
9720{
9721 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9722 hdd_adapter_t *pAdapter;
9723 VOS_STATUS vos_status;
9724
9725
9726 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
9727
9728 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
9729 {
9730 pAdapter = pAdapterNode->pAdapter;
9731
9732 if (pAdapter->sessionId == sme_session_id)
9733 return pAdapter;
9734
9735 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
9736 pAdapterNode = pNext;
9737 }
9738
9739 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9740 "%s: sme_session_id %d does not exist with host",
9741 __func__, sme_session_id);
9742
9743 return NULL;
9744}
9745
Jeff Johnson295189b2012-06-20 16:38:30 -07009746hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
9747{
9748 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9749 hdd_adapter_t *pAdapter;
9750 VOS_STATUS status;
9751
9752 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9753
9754 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9755 {
9756 pAdapter = pAdapterNode->pAdapter;
9757
9758 if( pAdapter && (mode == pAdapter->device_mode) )
9759 {
9760 return pAdapter;
9761 }
9762 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9763 pAdapterNode = pNext;
9764 }
9765
9766 return NULL;
9767
9768}
9769
9770//Remove this function later
9771hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
9772{
9773 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9774 hdd_adapter_t *pAdapter;
9775 VOS_STATUS status;
9776
9777 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9778
9779 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9780 {
9781 pAdapter = pAdapterNode->pAdapter;
9782
9783 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
9784 {
9785 return pAdapter;
9786 }
9787
9788 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9789 pAdapterNode = pNext;
9790 }
9791
9792 return NULL;
9793
9794}
9795
Jeff Johnson295189b2012-06-20 16:38:30 -07009796/**---------------------------------------------------------------------------
9797
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05309798 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07009799
9800 This API returns the operating channel of the requested device mode
9801
9802 \param - pHddCtx - Pointer to the HDD context.
9803 - mode - Device mode for which operating channel is required
9804 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
9805 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
9806 \return - channel number. "0" id the requested device is not found OR it is not connected.
9807 --------------------------------------------------------------------------*/
9808v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
9809{
9810 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9811 VOS_STATUS status;
9812 hdd_adapter_t *pAdapter;
9813 v_U8_t operatingChannel = 0;
9814
9815 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9816
9817 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9818 {
9819 pAdapter = pAdapterNode->pAdapter;
9820
9821 if( mode == pAdapter->device_mode )
9822 {
9823 switch(pAdapter->device_mode)
9824 {
9825 case WLAN_HDD_INFRA_STATION:
9826 case WLAN_HDD_P2P_CLIENT:
9827 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
9828 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
9829 break;
9830 case WLAN_HDD_SOFTAP:
9831 case WLAN_HDD_P2P_GO:
9832 /*softap connection info */
9833 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9834 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
9835 break;
9836 default:
9837 break;
9838 }
9839
9840 break; //Found the device of interest. break the loop
9841 }
9842
9843 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9844 pAdapterNode = pNext;
9845 }
9846 return operatingChannel;
9847}
9848
9849#ifdef WLAN_FEATURE_PACKET_FILTERING
9850/**---------------------------------------------------------------------------
9851
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309852 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07009853
9854 This used to set the multicast address list.
9855
9856 \param - dev - Pointer to the WLAN device.
9857 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309858 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07009859
9860 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309861static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07009862{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309863 hdd_adapter_t *pAdapter;
9864 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009865 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309866 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009867 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309868
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309869 ENTER();
9870
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309871 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309872 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009873 {
9874 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309875 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009876 return;
9877 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309878 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9879 ret = wlan_hdd_validate_context(pHddCtx);
9880 if (0 != ret)
9881 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309882 return;
9883 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009884 if (dev->flags & IFF_ALLMULTI)
9885 {
9886 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009887 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309888 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009889 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309890 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009891 {
9892 mc_count = netdev_mc_count(dev);
9893 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009894 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07009895 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
9896 {
9897 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009898 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309899 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009900 return;
9901 }
9902
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309903 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07009904
9905 netdev_for_each_mc_addr(ha, dev) {
9906 if (i == mc_count)
9907 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309908 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
9909 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08009910 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309911 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309912 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07009913 i++;
9914 }
9915 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309916
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +05309917 if (pHddCtx->hdd_wlan_suspended)
9918 {
9919 /*
9920 * Configure the Mcast address list to FW
9921 * If wlan is already in suspend mode
9922 */
9923 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
9924 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309925 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009926 return;
9927}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309928
9929static void hdd_set_multicast_list(struct net_device *dev)
9930{
9931 vos_ssr_protect(__func__);
9932 __hdd_set_multicast_list(dev);
9933 vos_ssr_unprotect(__func__);
9934}
Jeff Johnson295189b2012-06-20 16:38:30 -07009935#endif
9936
9937/**---------------------------------------------------------------------------
9938
9939 \brief hdd_select_queue() -
9940
9941 This function is registered with the Linux OS for network
9942 core to decide which queue to use first.
9943
9944 \param - dev - Pointer to the WLAN device.
9945 - skb - Pointer to OS packet (sk_buff).
9946 \return - ac, Queue Index/access category corresponding to UP in IP header
9947
9948 --------------------------------------------------------------------------*/
9949v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309950 struct sk_buff *skb
9951#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
9952 , void *accel_priv
9953#endif
9954#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9955 , select_queue_fallback_t fallback
9956#endif
9957)
Jeff Johnson295189b2012-06-20 16:38:30 -07009958{
9959 return hdd_wmm_select_queue(dev, skb);
9960}
9961
9962
9963/**---------------------------------------------------------------------------
9964
9965 \brief hdd_wlan_initial_scan() -
9966
9967 This function triggers the initial scan
9968
9969 \param - pAdapter - Pointer to the HDD adapter.
9970
9971 --------------------------------------------------------------------------*/
9972void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
9973{
9974 tCsrScanRequest scanReq;
9975 tCsrChannelInfo channelInfo;
9976 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07009977 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07009978 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9979
9980 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
9981 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
9982 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
9983
9984 if(sme_Is11dSupported(pHddCtx->hHal))
9985 {
9986 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
9987 if ( HAL_STATUS_SUCCESS( halStatus ) )
9988 {
9989 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
9990 if( !scanReq.ChannelInfo.ChannelList )
9991 {
9992 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
9993 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08009994 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009995 return;
9996 }
9997 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
9998 channelInfo.numOfChannels);
9999 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
10000 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080010001 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010002 }
10003
10004 scanReq.scanType = eSIR_PASSIVE_SCAN;
10005 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
10006 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
10007 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
10008 }
10009 else
10010 {
10011 scanReq.scanType = eSIR_ACTIVE_SCAN;
10012 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10013 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
10014 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
10015 }
10016
10017 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
10018 if ( !HAL_STATUS_SUCCESS( halStatus ) )
10019 {
10020 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
10021 __func__, halStatus );
10022 }
10023
10024 if(sme_Is11dSupported(pHddCtx->hHal))
10025 vos_mem_free(scanReq.ChannelInfo.ChannelList);
10026}
10027
Jeff Johnson295189b2012-06-20 16:38:30 -070010028/**---------------------------------------------------------------------------
10029
10030 \brief hdd_full_power_callback() - HDD full power callback function
10031
10032 This is the function invoked by SME to inform the result of a full power
10033 request issued by HDD
10034
10035 \param - callbackcontext - Pointer to cookie
10036 \param - status - result of request
10037
10038 \return - None
10039
10040 --------------------------------------------------------------------------*/
10041static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
10042{
Jeff Johnson72a40512013-12-19 10:14:15 -080010043 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010044
10045 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010046 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010047
10048 if (NULL == callbackContext)
10049 {
10050 hddLog(VOS_TRACE_LEVEL_ERROR,
10051 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010052 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010053 return;
10054 }
10055
Jeff Johnson72a40512013-12-19 10:14:15 -080010056 /* there is a race condition that exists between this callback
10057 function and the caller since the caller could time out either
10058 before or while this code is executing. we use a spinlock to
10059 serialize these actions */
10060 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010061
10062 if (POWER_CONTEXT_MAGIC != pContext->magic)
10063 {
10064 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -080010065 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010066 hddLog(VOS_TRACE_LEVEL_WARN,
10067 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010068 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -070010069 return;
10070 }
10071
Jeff Johnson72a40512013-12-19 10:14:15 -080010072 /* context is valid so caller is still waiting */
10073
10074 /* paranoia: invalidate the magic */
10075 pContext->magic = 0;
10076
10077 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -070010078 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -080010079
10080 /* serialization is complete */
10081 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010082}
10083
Katya Nigamf0511f62015-05-05 16:40:57 +053010084void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
10085{
10086 pMonCtx->typeSubtypeBitmap = 0;
10087 if( type%10 ) /* Management Packets */
10088 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
10089 type/=10;
10090 if( type%10 ) /* Control Packets */
10091 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
10092 type/=10;
10093 if( type%10 ) /* Data Packets */
10094 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
10095}
10096
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010097VOS_STATUS wlan_hdd_mon_postMsg(tANI_U32 *magic, struct completion *cmpVar,
10098 hdd_mon_ctx_t *pMonCtx , void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +053010099{
10100 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010101 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053010102
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010103 if (MON_MODE_START == pMonCtx->state)
10104 monMsg.type = WDA_MON_START_REQ;
10105 else if (MON_MODE_STOP == pMonCtx->state)
10106 monMsg.type = WDA_MON_STOP_REQ;
10107 else {
10108 hddLog(VOS_TRACE_LEVEL_ERROR,
10109 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +053010110 return VOS_STATUS_E_FAILURE;
10111 }
10112
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010113 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
10114 if (pMonModeReq == NULL) {
10115 hddLog(VOS_TRACE_LEVEL_ERROR,
10116 FL("fail to allocate memory for monitor mode req"));
10117 return VOS_STATUS_E_FAILURE;
10118 }
Katya Nigamf0511f62015-05-05 16:40:57 +053010119
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010120 pMonModeReq->magic = magic;
10121 pMonModeReq->cmpVar = cmpVar;
10122 pMonModeReq->data = pMonCtx;
10123 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +053010124
Katya Nigamf0511f62015-05-05 16:40:57 +053010125 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010126 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053010127 monMsg.bodyval = 0;
10128
10129 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
10130 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
10131 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010132 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +053010133 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010134 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +053010135}
10136
Katya Nigame7b69a82015-04-28 15:24:06 +053010137void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
10138{
10139 VOS_STATUS vosStatus;
10140 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010141 long ret;
10142 hdd_mon_ctx_t *pMonCtx = NULL;
10143 v_U32_t magic;
10144 struct completion cmpVar;
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053010145
Katya Nigame7b69a82015-04-28 15:24:06 +053010146 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
10147 if(pAdapter == NULL || pVosContext == NULL)
10148 {
10149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
10150 return ;
10151 }
Katya Nigamf0511f62015-05-05 16:40:57 +053010152
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010153 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
10154 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
10155 pMonCtx->state = MON_MODE_STOP;
10156 magic = MON_MODE_MSG_MAGIC;
10157 init_completion(&cmpVar);
10158 if (VOS_STATUS_SUCCESS !=
10159 wlan_hdd_mon_postMsg(&magic, &cmpVar,
10160 pMonCtx, hdd_monPostMsgCb)) {
10161 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10162 FL("failed to post MON MODE REQ"));
10163 pMonCtx->state = MON_MODE_START;
10164 magic = 0;
10165 return;
10166 }
10167 ret = wait_for_completion_timeout(&cmpVar, MON_MODE_MSG_TIMEOUT);
10168 magic = 0;
10169 if (ret <= 0 ) {
10170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10171 FL("timeout on monitor mode completion %ld"), ret);
10172 }
10173 }
10174
Katya Nigame7b69a82015-04-28 15:24:06 +053010175 hdd_UnregisterWext(pAdapter->dev);
10176
10177 vos_mon_stop( pVosContext );
10178
10179 vosStatus = vos_sched_close( pVosContext );
10180 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
10181 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10182 "%s: Failed to close VOSS Scheduler",__func__);
10183 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10184 }
10185
10186 vosStatus = vos_nv_close();
10187 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10188 {
10189 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10190 "%s: Failed to close NV", __func__);
10191 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10192 }
10193
10194 vos_close(pVosContext);
10195
10196 #ifdef WLAN_KD_READY_NOTIFIER
10197 nl_srv_exit(pHddCtx->ptt_pid);
10198 #else
10199 nl_srv_exit();
10200 #endif
10201
Katya Nigame7b69a82015-04-28 15:24:06 +053010202 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +053010203}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053010204/**
10205 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
10206 * @ wiphy: the wiphy to validate against
10207 *
10208 * Return: void
10209 */
10210void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
10211{
10212 int i =0;
10213 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
10214 {
10215 if (NULL != wiphy->bands[i] &&
10216 (NULL != wiphy->bands[i]->channels))
10217 {
10218 vos_mem_free(wiphy->bands[i]->channels);
10219 wiphy->bands[i]->channels = NULL;
10220 }
10221 }
10222}
Jeff Johnson295189b2012-06-20 16:38:30 -070010223/**---------------------------------------------------------------------------
10224
10225 \brief hdd_wlan_exit() - HDD WLAN exit function
10226
10227 This is the driver exit point (invoked during rmmod)
10228
10229 \param - pHddCtx - Pointer to the HDD Context
10230
10231 \return - None
10232
10233 --------------------------------------------------------------------------*/
10234void hdd_wlan_exit(hdd_context_t *pHddCtx)
10235{
10236 eHalStatus halStatus;
10237 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
10238 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +053010239 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080010240 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -080010241 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010242 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +053010243 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010244
10245 ENTER();
10246
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010247
Katya Nigame7b69a82015-04-28 15:24:06 +053010248 if (VOS_MONITOR_MODE == hdd_get_conparam())
10249 {
10250 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
10251 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053010252 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +053010253 }
10254 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -080010255 {
10256 // Unloading, restart logic is no more required.
10257 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -070010258
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053010259#ifdef FEATURE_WLAN_TDLS
10260 /* At the time of driver unloading; if tdls connection is present;
10261 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
10262 * wlan_hdd_tdls_find_peer always checks for valid context;
10263 * as load/unload in progress there can be a race condition.
10264 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
10265 * when tdls state is enabled.
10266 * As soon as driver set load/unload flag; tdls flag also needs
10267 * to be disabled so that hdd_rx_packet_cbk won't call
10268 * wlan_hdd_tdls_find_peer.
10269 */
Masti, Narayanraddi20494af2015-12-17 20:56:42 +053010270 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE,
10271 HDD_SET_TDLS_MODE_SOURCE_USER);
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053010272#endif
10273
c_hpothu5ab05e92014-06-13 17:34:05 +053010274 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10275 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -070010276 {
c_hpothu5ab05e92014-06-13 17:34:05 +053010277 pAdapter = pAdapterNode->pAdapter;
10278 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070010279 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053010280 /* Disable TX on the interface, after this hard_start_xmit() will
10281 * not be called on that interface
10282 */
10283 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10284 netif_tx_disable(pAdapter->dev);
10285
10286 /* Mark the interface status as "down" for outside world */
10287 netif_carrier_off(pAdapter->dev);
10288
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053010289 /* DeInit the adapter. This ensures that all data packets
10290 * are freed.
10291 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053010292#ifdef FEATURE_WLAN_TDLS
10293 mutex_lock(&pHddCtx->tdls_lock);
10294#endif
c_hpothu002231a2015-02-05 14:58:51 +053010295 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053010296#ifdef FEATURE_WLAN_TDLS
10297 mutex_unlock(&pHddCtx->tdls_lock);
10298#endif
Masti, Narayanraddi26378462016-01-05 18:20:28 +053010299 vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work);
10300
10301 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053010302
c_hpothu5ab05e92014-06-13 17:34:05 +053010303 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10304 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
10305 {
10306 wlan_hdd_cfg80211_deregister_frames(pAdapter);
10307 hdd_UnregisterWext(pAdapter->dev);
10308 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010309
Jeff Johnson295189b2012-06-20 16:38:30 -070010310 }
c_hpothu5ab05e92014-06-13 17:34:05 +053010311 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10312 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010313 }
mukul sharmabab477d2015-06-11 17:14:55 +053010314
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010315 // Cancel any outstanding scan requests. We are about to close all
10316 // of our adapters, but an adapter structure is what SME passes back
10317 // to our callback function. Hence if there are any outstanding scan
10318 // requests then there is a race condition between when the adapter
10319 // is closed and when the callback is invoked.We try to resolve that
10320 // race condition here by canceling any outstanding scans before we
10321 // close the adapters.
10322 // Note that the scans may be cancelled in an asynchronous manner,
10323 // so ideally there needs to be some kind of synchronization. Rather
10324 // than introduce a new synchronization here, we will utilize the
10325 // fact that we are about to Request Full Power, and since that is
10326 // synchronized, the expectation is that by the time Request Full
10327 // Power has completed all scans will be cancelled.
10328 if (pHddCtx->scan_info.mScanPending)
10329 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +053010330 if(NULL != pAdapter)
10331 {
10332 hddLog(VOS_TRACE_LEVEL_INFO,
10333 FL("abort scan mode: %d sessionId: %d"),
10334 pAdapter->device_mode,
10335 pAdapter->sessionId);
10336 }
10337 hdd_abort_mac_scan(pHddCtx,
10338 pHddCtx->scan_info.sessionId,
10339 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010340 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010341 }
c_hpothu5ab05e92014-06-13 17:34:05 +053010342 else
Jeff Johnson88ba7742013-02-27 14:36:02 -080010343 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010344 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +053010345 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
10346 {
10347 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
10348 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10349 "%s: in middle of FTM START", __func__);
10350 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
10351 msecs_to_jiffies(20000));
10352 if(!lrc)
10353 {
10354 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10355 "%s: timedout on ftmStartCmpVar fatal error", __func__);
10356 }
10357 }
Jeff Johnson88ba7742013-02-27 14:36:02 -080010358 wlan_hdd_ftm_close(pHddCtx);
10359 goto free_hdd_ctx;
10360 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010361
Jeff Johnson295189b2012-06-20 16:38:30 -070010362 /* DeRegister with platform driver as client for Suspend/Resume */
10363 vosStatus = hddDeregisterPmOps(pHddCtx);
10364 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
10365 {
10366 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
10367 VOS_ASSERT(0);
10368 }
10369
10370 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
10371 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
10372 {
10373 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
10374 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010375
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010376 //Stop the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053010377 if ((pHddCtx->cfg_ini->dynSplitscan) && (VOS_TIMER_STATE_RUNNING ==
10378 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010379 {
10380 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
10381 }
10382
10383 // Destroy the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053010384 if ((pHddCtx->cfg_ini->dynSplitscan) &&
10385 (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
10386 &pHddCtx->tx_rx_trafficTmr))))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010387 {
10388 hddLog(VOS_TRACE_LEVEL_ERROR,
10389 "%s: Cannot deallocate Traffic monitor timer", __func__);
10390 }
10391
Bhargav Shahd0715912015-10-01 18:17:37 +053010392 if (VOS_TIMER_STATE_RUNNING ==
10393 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
10394 vos_timer_stop(&pHddCtx->delack_timer);
10395 }
10396
10397 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
10398 &pHddCtx->delack_timer))) {
10399 hddLog(VOS_TRACE_LEVEL_ERROR,
10400 "%s: Cannot deallocate Bus bandwidth timer", __func__);
10401 }
10402
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053010403 if (VOS_TIMER_STATE_RUNNING ==
10404 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) {
10405 vos_timer_stop(&pHddCtx->tdls_source_timer);
10406 }
10407
10408 vos_timer_destroy(&pHddCtx->tdls_source_timer);
10409
Jeff Johnson295189b2012-06-20 16:38:30 -070010410 //Disable IMPS/BMPS as we do not want the device to enter any power
10411 //save mode during shutdown
10412 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
10413 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
10414 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
10415
10416 //Ensure that device is in full power as we will touch H/W during vos_Stop
10417 init_completion(&powerContext.completion);
10418 powerContext.magic = POWER_CONTEXT_MAGIC;
10419
10420 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
10421 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
10422
10423 if (eHAL_STATUS_SUCCESS != halStatus)
10424 {
10425 if (eHAL_STATUS_PMC_PENDING == halStatus)
10426 {
10427 /* request was sent -- wait for the response */
10428 lrc = wait_for_completion_interruptible_timeout(
10429 &powerContext.completion,
10430 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -070010431 if (lrc <= 0)
10432 {
10433 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010434 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -070010435 }
10436 }
10437 else
10438 {
10439 hddLog(VOS_TRACE_LEVEL_ERROR,
10440 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010441 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -070010442 /* continue -- need to clean up as much as possible */
10443 }
10444 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +053010445 if ((eHAL_STATUS_SUCCESS == halStatus) ||
10446 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
10447 {
10448 /* This will issue a dump command which will clean up
10449 BTQM queues and unblock MC thread */
10450 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
10451 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010452
Jeff Johnson72a40512013-12-19 10:14:15 -080010453 /* either we never sent a request, we sent a request and received a
10454 response or we sent a request and timed out. if we never sent a
10455 request or if we sent a request and got a response, we want to
10456 clear the magic out of paranoia. if we timed out there is a
10457 race condition such that the callback function could be
10458 executing at the same time we are. of primary concern is if the
10459 callback function had already verified the "magic" but had not
10460 yet set the completion variable when a timeout occurred. we
10461 serialize these activities by invalidating the magic while
10462 holding a shared spinlock which will cause us to block if the
10463 callback is currently executing */
10464 spin_lock(&hdd_context_lock);
10465 powerContext.magic = 0;
10466 spin_unlock(&hdd_context_lock);
10467
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +053010468 /* If Device is shutdown, no point for SME to wait for responses
10469 from device. Pre Close SME */
10470 if(wcnss_device_is_shutdown())
10471 {
10472 sme_PreClose(pHddCtx->hHal);
10473 }
Yue Ma0d4891e2013-08-06 17:01:45 -070010474 hdd_debugfs_exit(pHddCtx);
10475
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010476#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +053010477 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010478 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10479#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +053010480 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010481 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10482
Jeff Johnson295189b2012-06-20 16:38:30 -070010483 // Unregister the Net Device Notifier
10484 unregister_netdevice_notifier(&hdd_netdev_notifier);
10485
Jeff Johnson295189b2012-06-20 16:38:30 -070010486 hdd_stop_all_adapters( pHddCtx );
10487
Jeff Johnson295189b2012-06-20 16:38:30 -070010488#ifdef WLAN_BTAMP_FEATURE
10489 vosStatus = WLANBAP_Stop(pVosContext);
10490 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10491 {
10492 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10493 "%s: Failed to stop BAP",__func__);
10494 }
10495#endif //WLAN_BTAMP_FEATURE
10496
10497 //Stop all the modules
10498 vosStatus = vos_stop( pVosContext );
10499 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10500 {
10501 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10502 "%s: Failed to stop VOSS",__func__);
10503 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053010504 if (isSsrPanicOnFailure())
10505 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070010506 }
10507
Jeff Johnson295189b2012-06-20 16:38:30 -070010508 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -070010509 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010510
10511 //Close the scheduler before calling vos_close to make sure no thread is
10512 // scheduled after the each module close is called i.e after all the data
10513 // structures are freed.
10514 vosStatus = vos_sched_close( pVosContext );
10515 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
10516 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10517 "%s: Failed to close VOSS Scheduler",__func__);
10518 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10519 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010520#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10521 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010522 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070010523#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010524 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010525 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010526
Mihir Shete7a24b5f2013-12-21 12:18:31 +053010527#ifdef CONFIG_ENABLE_LINUX_REG
10528 vosStatus = vos_nv_close();
10529 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10530 {
10531 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10532 "%s: Failed to close NV", __func__);
10533 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10534 }
10535#endif
10536
Jeff Johnson295189b2012-06-20 16:38:30 -070010537 //Close VOSS
10538 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
10539 vos_close(pVosContext);
10540
Jeff Johnson295189b2012-06-20 16:38:30 -070010541 //Close Watchdog
10542 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10543 vos_watchdog_close(pVosContext);
10544
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053010545 //Clean up HDD Nlink Service
10546 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053010547
Manjeet Singh47ee8472016-04-11 11:57:18 +053010548 hdd_close_tx_queues(pHddCtx);
c_manjeecfd1efb2015-09-25 19:32:34 +053010549 wlan_free_fwr_mem_dump_buffer();
10550 memdump_deinit();
10551
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010552#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010553 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010554 {
10555 wlan_logging_sock_deactivate_svc();
10556 }
10557#endif
10558
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053010559#ifdef WLAN_KD_READY_NOTIFIER
10560 nl_srv_exit(pHddCtx->ptt_pid);
10561#else
10562 nl_srv_exit();
10563#endif /* WLAN_KD_READY_NOTIFIER */
10564
Abhishek Singh00b71972016-01-07 10:51:04 +053010565#ifdef WLAN_FEATURE_RMC
10566 hdd_close_cesium_nl_sock();
10567#endif /* WLAN_FEATURE_RMC */
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053010568
Jeff Johnson295189b2012-06-20 16:38:30 -070010569 hdd_close_all_adapters( pHddCtx );
10570
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053010571 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
10572
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +053010573free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -070010574 /* free the power on lock from platform driver */
10575 if (free_riva_power_on_lock("wlan"))
10576 {
10577 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
10578 __func__);
10579 }
10580
c_hpothu78c7b602014-05-17 17:35:49 +053010581 //Free up dynamically allocated members inside HDD Adapter
10582 if (pHddCtx->cfg_ini)
10583 {
10584 kfree(pHddCtx->cfg_ini);
10585 pHddCtx->cfg_ini= NULL;
10586 }
10587
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053010588 /* FTM/MONITOR mode, WIPHY did not registered
Leo Changf04ddad2013-09-18 13:46:38 -070010589 If un-register here, system crash will happen */
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053010590 if (!(VOS_FTM_MODE == hdd_get_conparam() ||
10591 VOS_MONITOR_MODE == hdd_get_conparam()))
Leo Changf04ddad2013-09-18 13:46:38 -070010592 {
10593 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053010594 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -070010595 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010596 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010597 if (hdd_is_ssr_required())
10598 {
10599 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -070010600 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -070010601 msleep(5000);
10602 }
10603 hdd_set_ssr_required (VOS_FALSE);
10604}
10605
10606
10607/**---------------------------------------------------------------------------
10608
10609 \brief hdd_update_config_from_nv() - Function to update the contents of
10610 the running configuration with parameters taken from NV storage
10611
10612 \param - pHddCtx - Pointer to the HDD global context
10613
10614 \return - VOS_STATUS_SUCCESS if successful
10615
10616 --------------------------------------------------------------------------*/
10617static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
10618{
Jeff Johnson295189b2012-06-20 16:38:30 -070010619 v_BOOL_t itemIsValid = VOS_FALSE;
10620 VOS_STATUS status;
10621 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
10622 v_U8_t macLoop;
10623
10624 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
10625 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
10626 if(status != VOS_STATUS_SUCCESS)
10627 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010628 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070010629 return VOS_STATUS_E_FAILURE;
10630 }
10631
10632 if (itemIsValid == VOS_TRUE)
10633 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010634 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -070010635 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
10636 VOS_MAX_CONCURRENCY_PERSONA);
10637 if(status != VOS_STATUS_SUCCESS)
10638 {
10639 /* Get MAC from NV fail, not update CFG info
10640 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -080010641 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070010642 return VOS_STATUS_E_FAILURE;
10643 }
10644
10645 /* If first MAC is not valid, treat all others are not valid
10646 * Then all MACs will be got from ini file */
10647 if(vos_is_macaddr_zero(&macFromNV[0]))
10648 {
10649 /* MAC address in NV file is not configured yet */
10650 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
10651 return VOS_STATUS_E_INVAL;
10652 }
10653
10654 /* Get MAC address from NV, update CFG info */
10655 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
10656 {
10657 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
10658 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010659 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -070010660 /* This MAC is not valid, skip it
10661 * This MAC will be got from ini file */
10662 }
10663 else
10664 {
10665 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
10666 (v_U8_t *)&macFromNV[macLoop].bytes[0],
10667 VOS_MAC_ADDR_SIZE);
10668 }
10669 }
10670 }
10671 else
10672 {
10673 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
10674 return VOS_STATUS_E_FAILURE;
10675 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010676
Jeff Johnson295189b2012-06-20 16:38:30 -070010677
10678 return VOS_STATUS_SUCCESS;
10679}
10680
10681/**---------------------------------------------------------------------------
10682
10683 \brief hdd_post_voss_start_config() - HDD post voss start config helper
10684
10685 \param - pAdapter - Pointer to the HDD
10686
10687 \return - None
10688
10689 --------------------------------------------------------------------------*/
10690VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
10691{
10692 eHalStatus halStatus;
10693 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010694 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -070010695
Jeff Johnson295189b2012-06-20 16:38:30 -070010696
10697 // Send ready indication to the HDD. This will kick off the MAC
10698 // into a 'running' state and should kick off an initial scan.
10699 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
10700 if ( !HAL_STATUS_SUCCESS( halStatus ) )
10701 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010702 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -070010703 "code %08d [x%08x]",__func__, halStatus, halStatus );
10704 return VOS_STATUS_E_FAILURE;
10705 }
10706
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010707 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -070010708 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
10709 // And RIVA will crash
10710 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
10711 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010712 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
10713 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
10714
10715
Jeff Johnson295189b2012-06-20 16:38:30 -070010716 return VOS_STATUS_SUCCESS;
10717}
10718
Jeff Johnson295189b2012-06-20 16:38:30 -070010719/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010720void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070010721{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010722
10723 vos_wake_lock_acquire(&wlan_wake_lock, reason);
10724
Jeff Johnson295189b2012-06-20 16:38:30 -070010725}
10726
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010727void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070010728{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010729
10730 vos_wake_lock_release(&wlan_wake_lock, reason);
10731
Jeff Johnson295189b2012-06-20 16:38:30 -070010732}
10733
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010734void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010735{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010736
10737 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
10738 reason);
10739
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010740}
10741
Jeff Johnson295189b2012-06-20 16:38:30 -070010742/**---------------------------------------------------------------------------
10743
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010744 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
10745 information between Host and Riva
10746
10747 This function gets reported version of FW
10748 It also finds the version of Riva headers used to compile the host
10749 It compares the above two and prints a warning if they are different
10750 It gets the SW and HW version string
10751 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
10752 indicating the features they support through a bitmap
10753
10754 \param - pHddCtx - Pointer to HDD context
10755
10756 \return - void
10757
10758 --------------------------------------------------------------------------*/
10759
10760void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
10761{
10762
10763 tSirVersionType versionCompiled;
10764 tSirVersionType versionReported;
10765 tSirVersionString versionString;
10766 tANI_U8 fwFeatCapsMsgSupported = 0;
10767 VOS_STATUS vstatus;
10768
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080010769 memset(&versionCompiled, 0, sizeof(versionCompiled));
10770 memset(&versionReported, 0, sizeof(versionReported));
10771
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010772 /* retrieve and display WCNSS version information */
10773 do {
10774
10775 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
10776 &versionCompiled);
10777 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10778 {
10779 hddLog(VOS_TRACE_LEVEL_FATAL,
10780 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010781 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010782 break;
10783 }
10784
10785 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
10786 &versionReported);
10787 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10788 {
10789 hddLog(VOS_TRACE_LEVEL_FATAL,
10790 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010791 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010792 break;
10793 }
10794
10795 if ((versionCompiled.major != versionReported.major) ||
10796 (versionCompiled.minor != versionReported.minor) ||
10797 (versionCompiled.version != versionReported.version) ||
10798 (versionCompiled.revision != versionReported.revision))
10799 {
10800 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
10801 "Host expected %u.%u.%u.%u\n",
10802 WLAN_MODULE_NAME,
10803 (int)versionReported.major,
10804 (int)versionReported.minor,
10805 (int)versionReported.version,
10806 (int)versionReported.revision,
10807 (int)versionCompiled.major,
10808 (int)versionCompiled.minor,
10809 (int)versionCompiled.version,
10810 (int)versionCompiled.revision);
10811 }
10812 else
10813 {
10814 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
10815 WLAN_MODULE_NAME,
10816 (int)versionReported.major,
10817 (int)versionReported.minor,
10818 (int)versionReported.version,
10819 (int)versionReported.revision);
10820 }
10821
10822 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
10823 versionString,
10824 sizeof(versionString));
10825 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10826 {
10827 hddLog(VOS_TRACE_LEVEL_FATAL,
10828 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010829 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010830 break;
10831 }
10832
10833 pr_info("%s: WCNSS software version %s\n",
10834 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +053010835 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010836
10837 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
10838 versionString,
10839 sizeof(versionString));
10840 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10841 {
10842 hddLog(VOS_TRACE_LEVEL_FATAL,
10843 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010844 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010845 break;
10846 }
10847
10848 pr_info("%s: WCNSS hardware version %s\n",
10849 WLAN_MODULE_NAME, versionString);
10850
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010851 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
10852 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010853 send the message only if it the riva is 1.1
10854 minor numbers for different riva branches:
10855 0 -> (1.0)Mainline Build
10856 1 -> (1.1)Mainline Build
10857 2->(1.04) Stability Build
10858 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010859 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010860 ((versionReported.minor>=1) && (versionReported.version>=1)))
10861 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
10862 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010863
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010864 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -080010865 {
10866#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
10867 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
10868 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
10869#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -070010870 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
10871 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
10872 {
10873 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
10874 }
10875
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010876 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -080010877 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010878
10879 } while (0);
10880
10881}
Neelansh Mittaledafed22014-09-04 18:54:39 +053010882void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
10883{
10884 struct sk_buff *skb;
10885 struct nlmsghdr *nlh;
10886 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053010887 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +053010888 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +053010889
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053010890 if (in_interrupt() || irqs_disabled() || in_atomic())
10891 flags = GFP_ATOMIC;
10892
10893 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +053010894
10895 if(skb == NULL) {
10896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10897 "%s: alloc_skb failed", __func__);
10898 return;
10899 }
10900
10901 nlh = (struct nlmsghdr *)skb->data;
10902 nlh->nlmsg_pid = 0; /* from kernel */
10903 nlh->nlmsg_flags = 0;
10904 nlh->nlmsg_seq = 0;
10905 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
10906
10907 ani_hdr = NLMSG_DATA(nlh);
10908 ani_hdr->type = type;
10909
10910 switch(type) {
10911 case WLAN_SVC_SAP_RESTART_IND:
10912 ani_hdr->length = 0;
10913 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
10914 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
10915 break;
Bhargav Shahd0715912015-10-01 18:17:37 +053010916 case WLAN_SVC_WLAN_TP_IND:
10917 ani_hdr->length = len;
10918 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
10919 + len));
10920 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
10921 memcpy(nl_data, data, len);
10922 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
10923 break;
Bhargav shah23c94942015-10-13 12:48:35 +053010924 case WLAN_MSG_RPS_ENABLE_IND:
10925 ani_hdr->length = len;
10926 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
10927 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
10928 memcpy(nl_data, data, len);
10929 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
10930 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +053010931 default:
10932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10933 "Attempt to send unknown nlink message %d", type);
10934 kfree_skb(skb);
10935 return;
10936 }
10937
10938 nl_srv_bcast(skb);
10939
10940 return;
10941}
10942
Bhargav Shahd0715912015-10-01 18:17:37 +053010943/**
10944 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
10945 * @pHddCtx: Valid Global HDD context pointer
10946 * @rx_packets: Number of RX packet in perticular time
10947 *
10948 * Based on the RX packet this function calculate next value of tcp delack.
10949 * This function compare rx packet value to high and low threshold limit.
10950 *
10951 * Return: void
10952 */
10953void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
10954{
10955 /* average of rx_packets and prev_rx is taken so that
10956 bus width doesnot fluctuate much */
10957 uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
10958 TP_IND_TYPE next_rx_level = pHddCtx->cur_rx_level;
Neelansh Mittaledafed22014-09-04 18:54:39 +053010959
Bhargav Shahd0715912015-10-01 18:17:37 +053010960 pHddCtx->prev_rx = rx_packets;
10961 if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
10962 next_rx_level = TP_IND_HIGH;
10963 else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
10964 next_rx_level = TP_IND_LOW;
10965
10966 hdd_set_delack_value(pHddCtx, next_rx_level);
10967}
10968
10969#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))
10970
10971/**
10972 * hdd_tcp_delack_compute_function() - get link status
10973 * @priv: Valid Global HDD context pointer
10974 *
10975 * This function find number of RX packet during timer life span.
10976 * It request tcp delack with number of RX packet and re-configure delack timer
10977 * for tcpDelAckComputeInterval timer interval.
10978 *
10979 * Return: void
10980 */
10981void hdd_tcp_delack_compute_function(void *priv)
10982{
10983 hdd_context_t *pHddCtx = (hdd_context_t *)priv;
10984 hdd_adapter_t *pAdapter = NULL;
10985 v_U32_t rx_packets = 0;
10986 hdd_adapter_list_node_t *pAdapterNode = NULL;
10987 VOS_STATUS status = 0;
10988
10989 for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
10990 NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
10991 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
10992 if ((pAdapter = pAdapterNode->pAdapter) == NULL)
10993 continue;
10994
10995 rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
10996 pAdapter->prev_rx_packets);
10997 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
10998 }
10999
11000 hdd_request_tcp_delack(pHddCtx, rx_packets);
11001
11002 vos_timer_start(&pHddCtx->delack_timer,
11003 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
11004}
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011005
11006/**---------------------------------------------------------------------------
11007
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011008 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
11009
11010 \param - pHddCtx - Pointer to the hdd context
11011
11012 \return - true if hardware supports 5GHz
11013
11014 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +053011015boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011016{
11017 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
11018 * then hardware support 5Ghz.
11019 */
11020 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
11021 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053011022 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011023 return true;
11024 }
11025 else
11026 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053011027 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011028 __func__);
11029 return false;
11030 }
11031}
11032
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011033/**---------------------------------------------------------------------------
11034
11035 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
11036 generate function
11037
11038 This is generate the random mac address for WLAN interface
11039
11040 \param - pHddCtx - Pointer to HDD context
11041 idx - Start interface index to get auto
11042 generated mac addr.
11043 mac_addr - Mac address
11044
11045 \return - 0 for success, < 0 for failure
11046
11047 --------------------------------------------------------------------------*/
11048
11049static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
11050 int idx, v_MACADDR_t mac_addr)
11051{
11052 int i;
11053 unsigned int serialno;
11054 serialno = wcnss_get_serial_number();
11055
11056 if (0 != serialno)
11057 {
11058 /* MAC address has 3 bytes of OUI so we have a maximum of 3
11059 bytes of the serial number that can be used to generate
11060 the other 3 bytes of the MAC address. Mask off all but
11061 the lower 3 bytes (this will also make sure we don't
11062 overflow in the next step) */
11063 serialno &= 0x00FFFFFF;
11064
11065 /* we need a unique address for each session */
11066 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
11067
11068 /* autogen other Mac addresses */
11069 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
11070 {
11071 /* start with the entire default address */
11072 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
11073 /* then replace the lower 3 bytes */
11074 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
11075 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
11076 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
11077
11078 serialno++;
11079 hddLog(VOS_TRACE_LEVEL_ERROR,
11080 "%s: Derived Mac Addr: "
11081 MAC_ADDRESS_STR, __func__,
11082 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
11083 }
11084
11085 }
11086 else
11087 {
11088 hddLog(LOGE, FL("Failed to Get Serial NO"));
11089 return -1;
11090 }
11091 return 0;
11092}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011093
Katya Nigame7b69a82015-04-28 15:24:06 +053011094int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
11095{
11096 VOS_STATUS status;
11097 v_CONTEXT_t pVosContext= NULL;
11098 hdd_adapter_t *pAdapter= NULL;
11099
11100 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11101
11102 if (NULL == pVosContext)
11103 {
11104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11105 "%s: Trying to open VOSS without a PreOpen", __func__);
11106 VOS_ASSERT(0);
11107 return VOS_STATUS_E_FAILURE;
11108 }
11109
11110 status = vos_nv_open();
11111 if (!VOS_IS_STATUS_SUCCESS(status))
11112 {
11113 /* NV module cannot be initialized */
11114 hddLog( VOS_TRACE_LEVEL_FATAL,
11115 "%s: vos_nv_open failed", __func__);
11116 return VOS_STATUS_E_FAILURE;
11117 }
11118
11119 status = vos_init_wiphy_from_nv_bin();
11120 if (!VOS_IS_STATUS_SUCCESS(status))
11121 {
11122 /* NV module cannot be initialized */
11123 hddLog( VOS_TRACE_LEVEL_FATAL,
11124 "%s: vos_init_wiphy failed", __func__);
11125 goto err_vos_nv_close;
11126 }
11127
11128 status = vos_open( &pVosContext, pHddCtx->parent_dev);
11129 if ( !VOS_IS_STATUS_SUCCESS( status ))
11130 {
11131 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
11132 goto err_vos_nv_close;
11133 }
11134
11135 status = vos_mon_start( pVosContext );
11136 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11137 {
11138 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
11139 goto err_vosclose;
11140 }
11141
11142 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
11143 WDA_featureCapsExchange(pVosContext);
11144 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
11145
11146 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
11147 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
11148 if( pAdapter == NULL )
11149 {
11150 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
11151 goto err_close_adapter;
11152 }
11153
11154 //Initialize the nlink service
11155 if(nl_srv_init() != 0)
11156 {
11157 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
11158 goto err_close_adapter;
11159 }
11160 return VOS_STATUS_SUCCESS;
11161
11162err_close_adapter:
11163 hdd_close_all_adapters( pHddCtx );
11164 vos_mon_stop( pVosContext );
11165err_vosclose:
11166 status = vos_sched_close( pVosContext );
11167 if (!VOS_IS_STATUS_SUCCESS(status)) {
11168 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
11169 "%s: Failed to close VOSS Scheduler", __func__);
11170 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
11171 }
11172 vos_close(pVosContext );
11173
11174err_vos_nv_close:
11175 vos_nv_close();
11176
11177return status;
11178}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011179/**---------------------------------------------------------------------------
11180
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011181 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
11182 completed to flush out the scan results
11183
11184 11d scan is done during driver load and is a passive scan on all
11185 channels supported by the device, 11d scans may find some APs on
11186 frequencies which are forbidden to be used in the regulatory domain
11187 the device is operating in. If these APs are notified to the supplicant
11188 it may try to connect to these APs, thus flush out all the scan results
11189 which are present in SME after 11d scan is done.
11190
11191 \return - eHalStatus
11192
11193 --------------------------------------------------------------------------*/
11194static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
11195 tANI_U32 scanId, eCsrScanStatus status)
11196{
11197 ENTER();
11198
11199 sme_ScanFlushResult(halHandle, 0);
11200
11201 EXIT();
11202
11203 return eHAL_STATUS_SUCCESS;
11204}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011205/**---------------------------------------------------------------------------
11206
11207 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
11208 logging is completed successfully.
11209
11210 \return - None
11211
11212 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +053011213void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011214{
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011215 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011216
11217 if (NULL == pHddCtx)
11218 {
11219 hddLog(VOS_TRACE_LEVEL_ERROR,
11220 "%s: HDD context is NULL",__func__);
11221 return;
11222 }
11223
c_manjeecfd1efb2015-09-25 19:32:34 +053011224 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +053011225 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011226 {
11227 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
11228 pHddCtx->mgmt_frame_logging = TRUE;
11229 }
11230 else
11231 {
11232 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
11233 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +053011234 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011235 }
11236
c_manjeecfd1efb2015-09-25 19:32:34 +053011237 /*Check feature supported by FW*/
11238 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
11239 {
11240 //Store fwr mem dump size given by firmware.
11241 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
11242 }
11243 else
11244 {
11245 wlan_store_fwr_mem_dump_size(0);
11246 }
11247
11248
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011249}
11250/**---------------------------------------------------------------------------
11251
11252 \brief hdd_init_frame_logging - function to initialize frame logging.
11253 Currently only Mgmt Frames are logged in both TX
11254 and Rx direction and are sent to userspace
11255 application using logger thread when queried.
11256
11257 \return - None
11258
11259 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011260void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011261{
11262 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011263 tSirFWLoggingInitParam wlanFWLoggingInitParam = {0};
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011264
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011265 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
11266 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011267 {
11268 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
11269 return;
11270 }
11271
c_manjeecfd1efb2015-09-25 19:32:34 +053011272 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011273 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
11274 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +053011275 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
11276 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011277
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011278 if (pHddCtx->cfg_ini->enableFWLogging ||
11279 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011280 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011281 wlanFWLoggingInitParam.enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011282 }
11283
Sushant Kaushik46804902015-07-08 14:46:03 +053011284 if (pHddCtx->cfg_ini->enableMgmtLogging)
11285 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011286 wlanFWLoggingInitParam.enableFlag |= WLAN_FRAME_LOG_EN;
Sushant Kaushik46804902015-07-08 14:46:03 +053011287 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011288 if (pHddCtx->cfg_ini->enableBMUHWtracing)
11289 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011290 wlanFWLoggingInitParam.enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011291 }
c_manjeecfd1efb2015-09-25 19:32:34 +053011292 if(pHddCtx->cfg_ini->enableFwrMemDump &&
11293 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
11294 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011295 wlanFWLoggingInitParam.enableFlag |= WLAN_FW_MEM_DUMP_EN;
c_manjeecfd1efb2015-09-25 19:32:34 +053011296 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011297 if( wlanFWLoggingInitParam.enableFlag == 0 )
c_manjeecfd1efb2015-09-25 19:32:34 +053011298 {
11299 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
11300 return;
11301 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011302 wlanFWLoggingInitParam.frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
11303 wlanFWLoggingInitParam.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
11304 wlanFWLoggingInitParam.bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
11305 wlanFWLoggingInitParam.continuousFrameLogging =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011306 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011307
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011308 wlanFWLoggingInitParam.enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011309
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011310 wlanFWLoggingInitParam.minLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011311 pHddCtx->cfg_ini->minLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011312 wlanFWLoggingInitParam.maxLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011313 pHddCtx->cfg_ini->maxLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011314 wlanFWLoggingInitParam.fwlogInitCallback = hdd_init_frame_logging_done;
11315 wlanFWLoggingInitParam.fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011316
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011317 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, &wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011318
11319 if (eHAL_STATUS_SUCCESS != halStatus)
11320 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011321 hddLog(LOGE, FL("sme_InitMgmtFrameLogging failed, returned %d"),
11322 halStatus);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011323 }
11324
11325 return;
11326}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011327
Bhargav shah23c94942015-10-13 12:48:35 +053011328static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
11329{
11330 hdd_adapter_t *adapter;
11331 hdd_adapter_list_node_t *adapter_node, *next;
11332 VOS_STATUS status = VOS_STATUS_SUCCESS;
11333 struct wlan_rps_data rps_data;
11334 int count;
11335
11336 if(!hdd_ctxt->cfg_ini->rps_mask)
11337 {
11338 return;
11339 }
11340
11341 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
11342 {
11343 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
11344 }
11345
11346 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
11347
11348 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
11349 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
11350 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
11351
11352 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
11353
11354 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
11355 {
11356 adapter = adapter_node->pAdapter;
11357 if (NULL != adapter) {
11358 strlcpy(rps_data.ifname, adapter->dev->name,
11359 sizeof(rps_data.ifname));
11360 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
11361 (void *)&rps_data,sizeof(rps_data));
11362 }
11363 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
11364 adapter_node = next;
11365 }
11366}
11367
Masti, Narayanraddi26378462016-01-05 18:20:28 +053011368void wlan_hdd_schedule_defer_scan(struct work_struct *work)
11369{
11370 scan_context_t *scan_ctx =
11371 container_of(work, scan_context_t, scan_work.work);
11372
11373 if (NULL == scan_ctx)
11374 {
11375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11376 FL("scan_ctx is NULL"));
11377 return;
11378 }
11379
11380 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
11381 return;
11382
11383 scan_ctx->attempt++;
11384
11385 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
11386#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11387 scan_ctx->dev,
11388#endif
11389 scan_ctx->scan_request);
11390}
11391
11392int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx,
11393 struct wiphy *wiphy,
11394#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11395 struct net_device *dev,
11396#endif
11397 struct cfg80211_scan_request *request)
11398{
11399 scan_context_t *scan_ctx;
11400
11401 ENTER();
11402 if (0 != (wlan_hdd_validate_context(pHddCtx)))
11403 {
11404 return -1;
11405 }
11406
11407 scan_ctx = &pHddCtx->scan_ctxt;
11408
11409 scan_ctx->wiphy = wiphy;
11410#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11411 scan_ctx->dev = dev;
11412#endif
11413
11414 scan_ctx->scan_request = request;
11415
11416 EXIT();
11417 return 0;
11418}
11419
11420void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
11421 struct wiphy *wiphy,
11422#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11423 struct net_device *dev,
11424#endif
11425 struct cfg80211_scan_request *request,
11426 unsigned long delay)
11427{
11428 if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic)
11429 {
11430#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11431 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request);
11432#else
11433 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request);
11434#endif
11435 pHddCtx->scan_ctxt.attempt = 0;
11436 pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC;
11437 }
11438 schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay);
11439}
11440
11441void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx)
11442{
11443 scan_ctx->magic = 0;
11444 scan_ctx->attempt = 0;
11445 scan_ctx->reject = 0;
11446 scan_ctx->scan_request = NULL;
11447
11448 return;
11449}
11450
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011451/**---------------------------------------------------------------------------
11452
Jeff Johnson295189b2012-06-20 16:38:30 -070011453 \brief hdd_wlan_startup() - HDD init function
11454
11455 This is the driver startup code executed once a WLAN device has been detected
11456
11457 \param - dev - Pointer to the underlying device
11458
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011459 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -070011460
11461 --------------------------------------------------------------------------*/
11462
11463int hdd_wlan_startup(struct device *dev )
11464{
11465 VOS_STATUS status;
11466 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011467 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011468 hdd_context_t *pHddCtx = NULL;
11469 v_CONTEXT_t pVosContext= NULL;
11470#ifdef WLAN_BTAMP_FEATURE
11471 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
11472 WLANBAP_ConfigType btAmpConfig;
11473 hdd_config_t *pConfig;
11474#endif
11475 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011476 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011477 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -070011478
11479 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011480 /*
11481 * cfg80211: wiphy allocation
11482 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011483 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070011484
11485 if(wiphy == NULL)
11486 {
11487 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011488 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011489 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011490 pHddCtx = wiphy_priv(wiphy);
11491
Jeff Johnson295189b2012-06-20 16:38:30 -070011492 //Initialize the adapter context to zeros.
11493 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
11494
Jeff Johnson295189b2012-06-20 16:38:30 -070011495 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011496 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +053011497 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011498
11499 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
11500
Siddharth Bhalcd92b782015-06-29 12:25:40 +053011501 /* register for riva power on lock to platform driver
11502 * Locking power early to ensure FW doesn't reset by kernel while
11503 * host driver is busy initializing itself */
11504 if (req_riva_power_on_lock("wlan"))
11505 {
11506 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
11507 __func__);
11508 goto err_free_hdd_context;
11509 }
11510
Jeff Johnson295189b2012-06-20 16:38:30 -070011511 /*Get vos context here bcoz vos_open requires it*/
11512 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11513
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -080011514 if(pVosContext == NULL)
11515 {
11516 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
11517 goto err_free_hdd_context;
11518 }
11519
Jeff Johnson295189b2012-06-20 16:38:30 -070011520 //Save the Global VOSS context in adapter context for future.
11521 pHddCtx->pvosContext = pVosContext;
11522
11523 //Save the adapter context in global context for future.
11524 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
11525
Jeff Johnson295189b2012-06-20 16:38:30 -070011526 pHddCtx->parent_dev = dev;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053011527 pHddCtx->last_scan_reject_session_id = 0xFF;
11528 pHddCtx->last_scan_reject_reason = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053011529 pHddCtx->last_scan_reject_timestamp = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011530
11531 init_completion(&pHddCtx->full_pwr_comp_var);
11532 init_completion(&pHddCtx->standby_comp_var);
11533 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011534 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080011535 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +053011536 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053011537 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053011538 init_completion(&pHddCtx->mc_sus_event_var);
11539 init_completion(&pHddCtx->tx_sus_event_var);
11540 init_completion(&pHddCtx->rx_sus_event_var);
11541
Amar Singhala49cbc52013-10-08 18:37:44 -070011542
mukul sharma4bd8d2e2015-08-13 20:33:25 +053011543 hdd_init_ll_stats_ctx(pHddCtx);
11544
Amar Singhala49cbc52013-10-08 18:37:44 -070011545#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -070011546 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -070011547#else
11548 init_completion(&pHddCtx->driver_crda_req);
11549#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011550
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +053011551#ifdef WLAN_FEATURE_EXTSCAN
11552 init_completion(&pHddCtx->ext_scan_context.response_event);
11553#endif /* WLAN_FEATURE_EXTSCAN */
11554
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053011555 spin_lock_init(&pHddCtx->schedScan_lock);
11556
Jeff Johnson295189b2012-06-20 16:38:30 -070011557 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
11558
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053011559 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
11560 hdd_processSpoofMacAddrRequest);
11561
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011562#ifdef FEATURE_WLAN_TDLS
11563 /* tdls_lock is initialized before an hdd_open_adapter ( which is
11564 * invoked by other instances also) to protect the concurrent
11565 * access for the Adapters by TDLS module.
11566 */
11567 mutex_init(&pHddCtx->tdls_lock);
11568#endif
Siddharth Bhal76972212014-10-15 16:22:51 +053011569 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +053011570 mutex_init(&pHddCtx->wmmLock);
11571
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +053011572 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +053011573 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011574
Agarwal Ashish1f422872014-07-22 00:11:55 +053011575 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011576 // Load all config first as TL config is needed during vos_open
11577 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
11578 if(pHddCtx->cfg_ini == NULL)
11579 {
11580 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
11581 goto err_free_hdd_context;
11582 }
11583
11584 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
11585
11586 // Read and parse the qcom_cfg.ini file
11587 status = hdd_parse_config_ini( pHddCtx );
11588 if ( VOS_STATUS_SUCCESS != status )
11589 {
11590 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
11591 __func__, WLAN_INI_FILE);
11592 goto err_config;
11593 }
Arif Hussaind5218912013-12-05 01:10:55 -080011594#ifdef MEMORY_DEBUG
11595 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
11596 vos_mem_init();
11597
11598 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
11599 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
11600#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011601
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +053011602 /* INI has been read, initialise the configuredMcastBcastFilter with
11603 * INI value as this will serve as the default value
11604 */
11605 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
11606 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
11607 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011608
11609 if (false == hdd_is_5g_supported(pHddCtx))
11610 {
11611 //5Ghz is not supported.
11612 if (1 != pHddCtx->cfg_ini->nBandCapability)
11613 {
11614 hddLog(VOS_TRACE_LEVEL_INFO,
11615 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
11616 pHddCtx->cfg_ini->nBandCapability = 1;
11617 }
11618 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053011619
11620 /* If SNR Monitoring is enabled, FW has to parse all beacons
11621 * for calcaluting and storing the average SNR, so set Nth beacon
11622 * filter to 1 to enable FW to parse all the beaocons
11623 */
11624 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
11625 {
11626 /* The log level is deliberately set to WARN as overriding
11627 * nthBeaconFilter to 1 will increase power cosumption and this
11628 * might just prove helpful to detect the power issue.
11629 */
11630 hddLog(VOS_TRACE_LEVEL_WARN,
11631 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
11632 pHddCtx->cfg_ini->nthBeaconFilter = 1;
11633 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011634 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011635 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -070011636 */
Manjeet Singh61016fa2016-12-02 11:10:19 +053011637 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
Jeff Johnson295189b2012-06-20 16:38:30 -070011638 {
Manjeet Singh61016fa2016-12-02 11:10:19 +053011639 hddLog(VOS_TRACE_LEVEL_FATAL,
11640 "%s: wlan_hdd_cfg80211_init return failure", __func__);
11641 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070011642 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011643
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011644 // Update VOS trace levels based upon the cfg.ini
11645 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
11646 pHddCtx->cfg_ini->vosTraceEnableBAP);
11647 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
11648 pHddCtx->cfg_ini->vosTraceEnableTL);
11649 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
11650 pHddCtx->cfg_ini->vosTraceEnableWDI);
11651 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
11652 pHddCtx->cfg_ini->vosTraceEnableHDD);
11653 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
11654 pHddCtx->cfg_ini->vosTraceEnableSME);
11655 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
11656 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +053011657 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
11658 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011659 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
11660 pHddCtx->cfg_ini->vosTraceEnableWDA);
11661 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
11662 pHddCtx->cfg_ini->vosTraceEnableSYS);
11663 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
11664 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011665 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
11666 pHddCtx->cfg_ini->vosTraceEnableSAP);
11667 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
11668 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011669
Jeff Johnson295189b2012-06-20 16:38:30 -070011670 // Update WDI trace levels based upon the cfg.ini
11671 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
11672 pHddCtx->cfg_ini->wdiTraceEnableDAL);
11673 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
11674 pHddCtx->cfg_ini->wdiTraceEnableCTL);
11675 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
11676 pHddCtx->cfg_ini->wdiTraceEnableDAT);
11677 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
11678 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -070011679
Jeff Johnson88ba7742013-02-27 14:36:02 -080011680 if (VOS_FTM_MODE == hdd_get_conparam())
11681 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011682 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
11683 {
11684 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
11685 goto err_free_hdd_context;
11686 }
11687 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +053011688 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +053011689 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011690 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -080011691 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011692
Katya Nigame7b69a82015-04-28 15:24:06 +053011693 if( VOS_MONITOR_MODE == hdd_get_conparam())
11694 {
11695 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
11696 {
11697 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
11698 goto err_free_hdd_context;
11699 }
11700 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
11701 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
11702 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
11703 return VOS_STATUS_SUCCESS;
11704 }
11705
Jeff Johnson88ba7742013-02-27 14:36:02 -080011706 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -070011707 if(pHddCtx->cfg_ini->fIsLogpEnabled)
11708 {
11709 status = vos_watchdog_open(pVosContext,
11710 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
11711
11712 if(!VOS_IS_STATUS_SUCCESS( status ))
11713 {
11714 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011715 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011716 }
11717 }
11718
11719 pHddCtx->isLogpInProgress = FALSE;
11720 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
11721
Amar Singhala49cbc52013-10-08 18:37:44 -070011722#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070011723 /* initialize the NV module. This is required so that
11724 we can initialize the channel information in wiphy
11725 from the NV.bin data. The channel information in
11726 wiphy needs to be initialized before wiphy registration */
11727
11728 status = vos_nv_open();
11729 if (!VOS_IS_STATUS_SUCCESS(status))
11730 {
11731 /* NV module cannot be initialized */
11732 hddLog( VOS_TRACE_LEVEL_FATAL,
11733 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +053011734 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -070011735 }
11736
11737 status = vos_init_wiphy_from_nv_bin();
11738 if (!VOS_IS_STATUS_SUCCESS(status))
11739 {
11740 /* NV module cannot be initialized */
11741 hddLog( VOS_TRACE_LEVEL_FATAL,
11742 "%s: vos_init_wiphy failed", __func__);
11743 goto err_vos_nv_close;
11744 }
11745
Amar Singhala49cbc52013-10-08 18:37:44 -070011746#endif
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053011747 //Initialize the nlink service
11748 if(nl_srv_init() != 0)
11749 {
11750 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
11751 goto err_vos_nv_close;
11752 }
11753
11754#ifdef WLAN_KD_READY_NOTIFIER
11755 pHddCtx->kd_nl_init = 1;
11756#endif /* WLAN_KD_READY_NOTIFIER */
11757
Girish Gowlibf0e1ab2015-01-19 16:05:16 +053011758 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053011759 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070011760 if ( !VOS_IS_STATUS_SUCCESS( status ))
11761 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011762 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053011763 goto err_nl_srv;
Jeff Johnson295189b2012-06-20 16:38:30 -070011764 }
11765
Jeff Johnson295189b2012-06-20 16:38:30 -070011766 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
11767
11768 if ( NULL == pHddCtx->hHal )
11769 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011770 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011771 goto err_vosclose;
11772 }
11773
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011774 status = vos_preStart( pHddCtx->pvosContext );
11775 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11776 {
11777 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011778 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011779 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011780
Arif Hussaineaf68602013-12-30 23:10:44 -080011781 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
11782 {
11783 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
11784 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
11785 __func__, enable_dfs_chan_scan);
11786 }
11787 if (0 == enable_11d || 1 == enable_11d)
11788 {
11789 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
11790 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
11791 __func__, enable_11d);
11792 }
11793
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011794 /* Note that the vos_preStart() sequence triggers the cfg download.
11795 The cfg download must occur before we update the SME config
11796 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -070011797 status = hdd_set_sme_config( pHddCtx );
11798
11799 if ( VOS_STATUS_SUCCESS != status )
11800 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011801 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011802 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011803 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011804
Jeff Johnson295189b2012-06-20 16:38:30 -070011805 /* In the integrated architecture we update the configuration from
11806 the INI file and from NV before vOSS has been started so that
11807 the final contents are available to send down to the cCPU */
11808
11809 // Apply the cfg.ini to cfg.dat
11810 if (FALSE == hdd_update_config_dat(pHddCtx))
11811 {
11812 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011813 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011814 }
11815
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011816 // Get mac addr from platform driver
11817 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
11818
11819 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011820 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011821 /* Store the mac addr for first interface */
11822 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
11823
11824 hddLog(VOS_TRACE_LEVEL_ERROR,
11825 "%s: WLAN Mac Addr: "
11826 MAC_ADDRESS_STR, __func__,
11827 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
11828
11829 /* Here, passing Arg2 as 1 because we do not want to change the
11830 last 3 bytes (means non OUI bytes) of first interface mac
11831 addr.
11832 */
11833 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
11834 {
11835 hddLog(VOS_TRACE_LEVEL_ERROR,
11836 "%s: Failed to generate wlan interface mac addr "
11837 "using MAC from ini file ", __func__);
11838 }
11839 }
11840 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
11841 {
11842 // Apply the NV to cfg.dat
11843 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070011844#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
11845 /* There was not a valid set of MAC Addresses in NV. See if the
11846 default addresses were modified by the cfg.ini settings. If so,
11847 we'll use them, but if not, we'll autogenerate a set of MAC
11848 addresses based upon the device serial number */
11849
11850 static const v_MACADDR_t default_address =
11851 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070011852
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011853 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
11854 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011855 {
11856 /* cfg.ini has the default address, invoke autogen logic */
11857
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011858 /* Here, passing Arg2 as 0 because we want to change the
11859 last 3 bytes (means non OUI bytes) of all the interfaces
11860 mac addr.
11861 */
11862 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
11863 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070011864 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011865 hddLog(VOS_TRACE_LEVEL_ERROR,
11866 "%s: Failed to generate wlan interface mac addr "
11867 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
11868 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070011869 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011870 }
11871 else
11872#endif //WLAN_AUTOGEN_MACADDR_FEATURE
11873 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011874 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011875 "%s: Invalid MAC address in NV, using MAC from ini file "
11876 MAC_ADDRESS_STR, __func__,
11877 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
11878 }
11879 }
11880 {
11881 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011882
11883 /* Set the MAC Address Currently this is used by HAL to
11884 * add self sta. Remove this once self sta is added as
11885 * part of session open.
11886 */
Jeff Johnson295189b2012-06-20 16:38:30 -070011887 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
11888 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
11889 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011890
Jeff Johnson295189b2012-06-20 16:38:30 -070011891 if (!HAL_STATUS_SUCCESS( halStatus ))
11892 {
11893 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
11894 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011895 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011896 }
11897 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011898
11899 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
11900 Note: Firmware image will be read and downloaded inside vos_start API */
11901 status = vos_start( pHddCtx->pvosContext );
11902 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11903 {
11904 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053011905 if (isSsrPanicOnFailure())
11906 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011907 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011908 }
11909
Leo Chang6cec3e22014-01-21 15:33:49 -080011910#ifdef FEATURE_WLAN_CH_AVOID
11911 /* Plug in avoid channel notification callback
11912 * This should happen before ADD_SELF_STA
11913 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053011914
11915 /* check the Channel Avoidance is enabled */
11916 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
11917 {
11918 sme_AddChAvoidCallback(pHddCtx->hHal,
11919 hdd_hostapd_ch_avoid_cb);
11920 }
Leo Chang6cec3e22014-01-21 15:33:49 -080011921#endif /* FEATURE_WLAN_CH_AVOID */
11922
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011923 /* Exchange capability info between Host and FW and also get versioning info from FW */
11924 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011925
Agarwal Ashishad9281b2014-06-10 14:57:30 +053011926#ifdef CONFIG_ENABLE_LINUX_REG
11927 status = wlan_hdd_init_channels(pHddCtx);
11928 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11929 {
11930 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
11931 __func__);
11932 goto err_vosstop;
11933 }
11934#endif
11935
Jeff Johnson295189b2012-06-20 16:38:30 -070011936 status = hdd_post_voss_start_config( pHddCtx );
11937 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11938 {
11939 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
11940 __func__);
11941 goto err_vosstop;
11942 }
Amar Singhala49cbc52013-10-08 18:37:44 -070011943
11944#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011945 wlan_hdd_cfg80211_update_reg_info( wiphy );
11946
11947 /* registration of wiphy dev with cfg80211 */
11948 if (0 > wlan_hdd_cfg80211_register(wiphy))
11949 {
11950 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
11951 goto err_vosstop;
11952 }
Amar Singhala49cbc52013-10-08 18:37:44 -070011953#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011954
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011955#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011956 /* registration of wiphy dev with cfg80211 */
11957 if (0 > wlan_hdd_cfg80211_register(wiphy))
11958 {
11959 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
11960 goto err_vosstop;
11961 }
11962
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011963 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011964 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11965 {
11966 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
11967 __func__);
11968 goto err_unregister_wiphy;
11969 }
11970#endif
11971
c_hpothu4a298be2014-12-22 21:12:51 +053011972 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
11973
Jeff Johnson295189b2012-06-20 16:38:30 -070011974 if (VOS_STA_SAP_MODE == hdd_get_conparam())
11975 {
11976 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
11977 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
11978 }
11979 else
11980 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011981 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
11982 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
11983 if (pAdapter != NULL)
11984 {
Katya Nigama7d81d72014-11-12 12:44:34 +053011985 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070011986 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053011987 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
11988 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
11989 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070011990
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053011991 /* Generate the P2P Device Address. This consists of the device's
11992 * primary MAC address with the locally administered bit set.
11993 */
11994 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070011995 }
11996 else
11997 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053011998 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
11999 if (p2p_dev_addr != NULL)
12000 {
12001 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
12002 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
12003 }
12004 else
12005 {
12006 hddLog(VOS_TRACE_LEVEL_FATAL,
12007 "%s: Failed to allocate mac_address for p2p_device",
12008 __func__);
12009 goto err_close_adapter;
12010 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012011 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012012
12013 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
12014 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
12015 if ( NULL == pP2pAdapter )
12016 {
12017 hddLog(VOS_TRACE_LEVEL_FATAL,
12018 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012019 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070012020 goto err_close_adapter;
12021 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012022 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012023 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012024
12025 if( pAdapter == NULL )
12026 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012027 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
12028 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070012029 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012030
Arif Hussain66559122013-11-21 10:11:40 -080012031 if (country_code)
12032 {
12033 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080012034 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080012035 hdd_checkandupdate_dfssetting(pAdapter, country_code);
12036#ifndef CONFIG_ENABLE_LINUX_REG
12037 hdd_checkandupdate_phymode(pAdapter, country_code);
12038#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080012039 ret = sme_ChangeCountryCode(pHddCtx->hHal,
12040 (void *)(tSmeChangeCountryCallback)
12041 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080012042 country_code,
12043 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012044 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080012045 if (eHAL_STATUS_SUCCESS == ret)
12046 {
Arif Hussaincb607082013-12-20 11:57:42 -080012047 ret = wait_for_completion_interruptible_timeout(
12048 &pAdapter->change_country_code,
12049 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
12050
12051 if (0 >= ret)
12052 {
12053 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12054 "%s: SME while setting country code timed out", __func__);
12055 }
Arif Hussain66559122013-11-21 10:11:40 -080012056 }
12057 else
12058 {
Arif Hussaincb607082013-12-20 11:57:42 -080012059 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12060 "%s: SME Change Country code from module param fail ret=%d",
12061 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080012062 }
12063 }
12064
Jeff Johnson295189b2012-06-20 16:38:30 -070012065#ifdef WLAN_BTAMP_FEATURE
12066 vStatus = WLANBAP_Open(pVosContext);
12067 if(!VOS_IS_STATUS_SUCCESS(vStatus))
12068 {
12069 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12070 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070012071 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070012072 }
12073
12074 vStatus = BSL_Init(pVosContext);
12075 if(!VOS_IS_STATUS_SUCCESS(vStatus))
12076 {
12077 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12078 "%s: Failed to Init BSL",__func__);
12079 goto err_bap_close;
12080 }
12081 vStatus = WLANBAP_Start(pVosContext);
12082 if (!VOS_IS_STATUS_SUCCESS(vStatus))
12083 {
12084 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12085 "%s: Failed to start TL",__func__);
12086 goto err_bap_close;
12087 }
12088
12089 pConfig = pHddCtx->cfg_ini;
12090 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
12091 status = WLANBAP_SetConfig(&btAmpConfig);
12092
12093#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070012094
Mihir Shete9c238772014-10-15 14:35:16 +053012095 /*
12096 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
12097 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
12098 * which is greater than 0xf. So the below check is safe to make
12099 * sure that there is no entry for UapsdMask in the ini
12100 */
12101 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
12102 {
12103 if(IS_DYNAMIC_WMM_PS_ENABLED)
12104 {
12105 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
12106 __func__);
12107 pHddCtx->cfg_ini->UapsdMask =
12108 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
12109 }
12110 else
12111 {
12112 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
12113 __func__);
12114 pHddCtx->cfg_ini->UapsdMask =
12115 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
12116 }
12117 }
12118
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070012119#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
12120 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
12121 {
12122 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
12123 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
12124 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
12125 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
12126 }
12127#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012128
Agarwal Ashish4b87f922014-06-18 03:03:21 +053012129 wlan_hdd_tdls_init(pHddCtx);
12130
Masti, Narayanraddi26378462016-01-05 18:20:28 +053012131 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
12132
12133 vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work,
12134 wlan_hdd_schedule_defer_scan);
12135
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053012136 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
12137
Jeff Johnson295189b2012-06-20 16:38:30 -070012138 /* Register with platform driver as client for Suspend/Resume */
12139 status = hddRegisterPmOps(pHddCtx);
12140 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12141 {
12142 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
12143#ifdef WLAN_BTAMP_FEATURE
12144 goto err_bap_stop;
12145#else
Jeff Johnsone7245742012-09-05 17:12:55 -070012146 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070012147#endif //WLAN_BTAMP_FEATURE
12148 }
12149
Yue Ma0d4891e2013-08-06 17:01:45 -070012150 /* Open debugfs interface */
12151 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
12152 {
12153 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12154 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070012155 }
12156
Jeff Johnson295189b2012-06-20 16:38:30 -070012157 /* Register TM level change handler function to the platform */
12158 status = hddDevTmRegisterNotifyCallback(pHddCtx);
12159 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12160 {
12161 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
12162 goto err_unregister_pmops;
12163 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012164
Jeff Johnson295189b2012-06-20 16:38:30 -070012165 // register net device notifier for device change notification
12166 ret = register_netdevice_notifier(&hdd_netdev_notifier);
12167
12168 if(ret < 0)
12169 {
12170 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053012171 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070012172 }
12173
Jeff Johnson295189b2012-06-20 16:38:30 -070012174 //Initialize the BTC service
12175 if(btc_activate_service(pHddCtx) != 0)
12176 {
12177 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012178 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070012179 }
12180
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053012181#ifdef FEATURE_OEM_DATA_SUPPORT
12182 //Initialize the OEM service
12183 if (oem_activate_service(pHddCtx) != 0)
12184 {
12185 hddLog(VOS_TRACE_LEVEL_FATAL,
12186 "%s: oem_activate_service failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012187 goto err_reg_netdev;
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053012188 }
12189#endif
12190
Jeff Johnson295189b2012-06-20 16:38:30 -070012191#ifdef PTT_SOCK_SVC_ENABLE
12192 //Initialize the PTT service
12193 if(ptt_sock_activate_svc(pHddCtx) != 0)
12194 {
12195 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012196 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070012197 }
12198#endif
12199
Abhishek Singh00b71972016-01-07 10:51:04 +053012200#ifdef WLAN_FEATURE_RMC
12201 if (hdd_open_cesium_nl_sock() < 0)
12202 {
12203 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
12204 goto err_reg_netdev;
12205 }
12206#endif
12207
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012208#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12209 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
12210 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053012211 if(wlan_logging_sock_activate_svc(
12212 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053012213 pHddCtx->cfg_ini->wlanLoggingNumBuf,
12214 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
12215 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053012216 {
12217 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
12218 " failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012219 goto err_reg_netdev;
Deepthi Gowri78083a32014-11-04 12:55:51 +053012220 }
12221 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
12222 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053012223 if (!pHddCtx->cfg_ini->gEnableDebugLog)
12224 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053012225 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
12226 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012227 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012228
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012229 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
12230 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053012231 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053012232 pHddCtx->cfg_ini->enableContFWLogging ||
12233 pHddCtx->cfg_ini->enableFwrMemDump )
12234 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012235 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012236 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012237 }
12238 else
12239 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012240 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012241 }
12242
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012243#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012244
Agrawal Ashish17ef5082016-10-17 18:33:21 +053012245#ifdef SAP_AUTH_OFFLOAD
12246 if (!sme_IsFeatureSupportedByFW(SAP_OFFLOADS))
12247 {
12248 hddLog(VOS_TRACE_LEVEL_INFO, FL(" SAP AUTH OFFLOAD not supp by FW"));
12249 pHddCtx->cfg_ini->enable_sap_auth_offload = 0;
12250 }
12251#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012252
Sushant Kaushik215778f2015-05-21 14:05:36 +053012253 if (vos_is_multicast_logging())
12254 wlan_logging_set_log_level();
12255
Jeff Johnson295189b2012-06-20 16:38:30 -070012256 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012257 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070012258 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070012259 /* Action frame registered in one adapter which will
12260 * applicable to all interfaces
12261 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053012262 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012263 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012264
12265 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053012266 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012267
Jeff Johnsone7245742012-09-05 17:12:55 -070012268#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
12269 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012270 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070012271 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012272
Jeff Johnsone7245742012-09-05 17:12:55 -070012273#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012274 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012275 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012276 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012277
Jeff Johnsone7245742012-09-05 17:12:55 -070012278
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012279 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
12280 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012281
Katya Nigam5c306ea2014-06-19 15:39:54 +053012282 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012283 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012284 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053012285
12286#ifdef FEATURE_WLAN_SCAN_PNO
12287 /*SME must send channel update configuration to RIVA*/
12288 sme_UpdateChannelConfig(pHddCtx->hHal);
12289#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053012290 /* Send the update default channel list to the FW*/
12291 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053012292
12293 /* Fwr capabilities received, Set the Dot11 mode */
Abhishek Singh41ebce12016-02-03 10:43:21 +053012294 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
12295 hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode));
Mukul Sharma45063942015-04-01 20:07:59 +053012296 sme_SetDefDot11Mode(pHddCtx->hHal);
12297
Abhishek Singha306a442013-11-07 18:39:01 +053012298#ifndef CONFIG_ENABLE_LINUX_REG
12299 /*updating wiphy so that regulatory user hints can be processed*/
12300 if (wiphy)
12301 {
12302 regulatory_hint(wiphy, "00");
12303 }
12304#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012305 // Initialize the restart logic
12306 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053012307
Hanumanth Reddy Pothula146bca42016-11-08 12:01:07 +053012308 if (pHddCtx->cfg_ini->fIsLogpEnabled) {
12309 vos_wdthread_init_timer_work(vos_process_wd_timer);
12310 /* Initialize the timer to detect thread stuck issues */
12311 vos_thread_stuck_timer_init(
12312 &((VosContextType*)pVosContext)->vosWatchdog);
12313 }
12314
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012315 //Register the traffic monitor timer now
12316 if ( pHddCtx->cfg_ini->dynSplitscan)
12317 {
12318 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
12319 VOS_TIMER_TYPE_SW,
12320 hdd_tx_rx_pkt_cnt_stat_timer_handler,
12321 (void *)pHddCtx);
12322 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053012323 wlan_hdd_cfg80211_nan_init(pHddCtx);
12324
Bhargav Shahd0715912015-10-01 18:17:37 +053012325 mutex_init(&pHddCtx->cur_rx_level_lock);
12326 vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
12327 hdd_tcp_delack_compute_function,(void *)pHddCtx);
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012328 vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW,
12329 wlan_hdd_change_tdls_mode, (void *)pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +053012330
Dino Mycle6fb96c12014-06-10 11:52:40 +053012331#ifdef WLAN_FEATURE_EXTSCAN
12332 sme_EXTScanRegisterCallback(pHddCtx->hHal,
12333 wlan_hdd_cfg80211_extscan_callback,
12334 pHddCtx);
12335#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012336
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053012337#ifdef FEATURE_OEM_DATA_SUPPORT
12338 sme_OemDataRegisterCallback(pHddCtx->hHal,
12339 wlan_hdd_cfg80211_oemdata_callback,
12340 pHddCtx);
12341#endif /* FEATURE_OEM_DATA_SUPPORT */
12342
Gupta, Kapil7c34b322015-09-30 13:12:35 +053012343 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012344#ifdef WLAN_NS_OFFLOAD
12345 // Register IPv6 notifier to notify if any change in IP
12346 // So that we can reconfigure the offload parameters
12347 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
12348 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
12349 if (ret)
12350 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012352 }
12353 else
12354 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012355 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012356 }
12357#endif
12358
12359 // Register IPv4 notifier to notify if any change in IP
12360 // So that we can reconfigure the offload parameters
12361 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
12362 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
12363 if (ret)
12364 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012365 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012366 }
12367 else
12368 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012369 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012370 }
c_manjeecfd1efb2015-09-25 19:32:34 +053012371 /*Fw mem dump procfs initialization*/
12372 memdump_init();
Bhargav shah23c94942015-10-13 12:48:35 +053012373 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012374
Jeff Johnson295189b2012-06-20 16:38:30 -070012375 goto success;
12376
Jeff Johnson295189b2012-06-20 16:38:30 -070012377err_reg_netdev:
12378 unregister_netdevice_notifier(&hdd_netdev_notifier);
12379
Jeff Johnson295189b2012-06-20 16:38:30 -070012380err_unregister_pmops:
12381 hddDevTmUnregisterNotifyCallback(pHddCtx);
12382 hddDeregisterPmOps(pHddCtx);
12383
Yue Ma0d4891e2013-08-06 17:01:45 -070012384 hdd_debugfs_exit(pHddCtx);
12385
Jeff Johnson295189b2012-06-20 16:38:30 -070012386#ifdef WLAN_BTAMP_FEATURE
12387err_bap_stop:
12388 WLANBAP_Stop(pVosContext);
12389#endif
12390
12391#ifdef WLAN_BTAMP_FEATURE
12392err_bap_close:
12393 WLANBAP_Close(pVosContext);
12394#endif
12395
Jeff Johnson295189b2012-06-20 16:38:30 -070012396err_close_adapter:
12397 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053012398#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012399err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053012400#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053012401 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012402 hdd_wlan_free_wiphy_channels(wiphy);
12403
Jeff Johnson295189b2012-06-20 16:38:30 -070012404err_vosstop:
12405 vos_stop(pVosContext);
12406
Amar Singhala49cbc52013-10-08 18:37:44 -070012407err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070012408 status = vos_sched_close( pVosContext );
12409 if (!VOS_IS_STATUS_SUCCESS(status)) {
12410 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12411 "%s: Failed to close VOSS Scheduler", __func__);
12412 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
12413 }
Amar Singhala49cbc52013-10-08 18:37:44 -070012414 vos_close(pVosContext );
12415
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012416err_nl_srv:
12417#ifdef WLAN_KD_READY_NOTIFIER
12418 nl_srv_exit(pHddCtx->ptt_pid);
12419#else
12420 nl_srv_exit();
12421#endif /* WLAN_KD_READY_NOTIFIER */
Amar Singhal0a402232013-10-11 20:57:16 -070012422err_vos_nv_close:
12423
c_hpothue6a36282014-03-19 12:27:38 +053012424#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070012425 vos_nv_close();
12426
c_hpothu70f8d812014-03-22 22:59:23 +053012427#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012428
12429err_wdclose:
12430 if(pHddCtx->cfg_ini->fIsLogpEnabled)
12431 vos_watchdog_close(pVosContext);
12432
Jeff Johnson295189b2012-06-20 16:38:30 -070012433err_config:
12434 kfree(pHddCtx->cfg_ini);
12435 pHddCtx->cfg_ini= NULL;
12436
12437err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012438 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053012439 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070012440 wiphy_free(wiphy) ;
12441 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070012442 VOS_BUG(1);
12443
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080012444 if (hdd_is_ssr_required())
12445 {
12446 /* WDI timeout had happened during load, so SSR is needed here */
12447 subsystem_restart("wcnss");
12448 msleep(5000);
12449 }
12450 hdd_set_ssr_required (VOS_FALSE);
12451
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012452 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012453
12454success:
12455 EXIT();
12456 return 0;
12457}
12458
12459/**---------------------------------------------------------------------------
12460
Jeff Johnson32d95a32012-09-10 13:15:23 -070012461 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070012462
Jeff Johnson32d95a32012-09-10 13:15:23 -070012463 This is the driver entry point - called in different timeline depending
12464 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070012465
12466 \param - None
12467
12468 \return - 0 for success, non zero for failure
12469
12470 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070012471static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070012472{
12473 VOS_STATUS status;
12474 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012475 struct device *dev = NULL;
12476 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012477#ifdef HAVE_WCNSS_CAL_DOWNLOAD
12478 int max_retries = 0;
12479#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012480#ifdef HAVE_CBC_DONE
12481 int max_cbc_retries = 0;
12482#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012483
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012484#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12485 wlan_logging_sock_init_svc();
12486#endif
12487
Jeff Johnson295189b2012-06-20 16:38:30 -070012488 ENTER();
12489
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012490 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070012491
12492 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
12493 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
12494
Jeff Johnson295189b2012-06-20 16:38:30 -070012495#ifdef ANI_BUS_TYPE_PCI
12496
12497 dev = wcnss_wlan_get_device();
12498
12499#endif // ANI_BUS_TYPE_PCI
12500
12501#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012502
12503#ifdef HAVE_WCNSS_CAL_DOWNLOAD
12504 /* wait until WCNSS driver downloads NV */
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053012505 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012506 msleep(1000);
12507 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012508
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053012509 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012510 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012511 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012512#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12513 wlan_logging_sock_deinit_svc();
12514#endif
12515
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012516 return -ENODEV;
12517 }
12518#endif
12519
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012520#ifdef HAVE_CBC_DONE
12521 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
12522 msleep(1000);
12523 }
12524 if (max_cbc_retries >= 10) {
12525 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
12526 }
12527#endif
12528
Jeff Johnson295189b2012-06-20 16:38:30 -070012529 dev = wcnss_wlan_get_device();
12530#endif // ANI_BUS_TYPE_PLATFORM
12531
12532
12533 do {
12534 if (NULL == dev) {
12535 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
12536 ret_status = -1;
12537 break;
12538 }
12539
Jeff Johnson295189b2012-06-20 16:38:30 -070012540#ifdef TIMER_MANAGER
12541 vos_timer_manager_init();
12542#endif
12543
12544 /* Preopen VOSS so that it is ready to start at least SAL */
12545 status = vos_preOpen(&pVosContext);
12546
12547 if (!VOS_IS_STATUS_SUCCESS(status))
12548 {
12549 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
12550 ret_status = -1;
12551 break;
12552 }
12553
Sushant Kaushik02beb352015-06-04 15:15:01 +053012554 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053012555 hdd_register_debug_callback();
12556
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012557#ifndef MODULE
12558 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
12559 */
12560 hdd_set_conparam((v_UINT_t)con_mode);
12561#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012562
12563 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012564 if (hdd_wlan_startup(dev))
12565 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012566 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012567 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012568 vos_preClose( &pVosContext );
12569 ret_status = -1;
12570 break;
12571 }
12572
Jeff Johnson295189b2012-06-20 16:38:30 -070012573 } while (0);
12574
12575 if (0 != ret_status)
12576 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012577#ifdef TIMER_MANAGER
12578 vos_timer_exit();
12579#endif
12580#ifdef MEMORY_DEBUG
12581 vos_mem_exit();
12582#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012583 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012584#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12585 wlan_logging_sock_deinit_svc();
12586#endif
12587
Jeff Johnson295189b2012-06-20 16:38:30 -070012588 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
12589 }
12590 else
12591 {
12592 //Send WLAN UP indication to Nlink Service
12593 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
12594
12595 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070012596 }
12597
12598 EXIT();
12599
12600 return ret_status;
12601}
12602
Jeff Johnson32d95a32012-09-10 13:15:23 -070012603/**---------------------------------------------------------------------------
12604
12605 \brief hdd_module_init() - Init Function
12606
12607 This is the driver entry point (invoked when module is loaded using insmod)
12608
12609 \param - None
12610
12611 \return - 0 for success, non zero for failure
12612
12613 --------------------------------------------------------------------------*/
12614#ifdef MODULE
12615static int __init hdd_module_init ( void)
12616{
12617 return hdd_driver_init();
12618}
Jeff Johnson32d95a32012-09-10 13:15:23 -070012619#else /* #ifdef MODULE */
12620static int __init hdd_module_init ( void)
12621{
12622 /* Driver initialization is delayed to fwpath_changed_handler */
12623 return 0;
12624}
Jeff Johnson32d95a32012-09-10 13:15:23 -070012625#endif /* #ifdef MODULE */
12626
Jeff Johnson295189b2012-06-20 16:38:30 -070012627
12628/**---------------------------------------------------------------------------
12629
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012630 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070012631
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012632 This is the driver exit point (invoked when module is unloaded using rmmod
12633 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070012634
12635 \param - None
12636
12637 \return - None
12638
12639 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012640static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070012641{
12642 hdd_context_t *pHddCtx = NULL;
12643 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053012644 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053012645 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012646
12647 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
12648
12649 //Get the global vos context
12650 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12651
12652 if(!pVosContext)
12653 {
12654 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
12655 goto done;
12656 }
12657
12658 //Get the HDD context.
12659 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
12660
12661 if(!pHddCtx)
12662 {
12663 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
12664 }
Katya Nigame7b69a82015-04-28 15:24:06 +053012665 else if (VOS_MONITOR_MODE == hdd_get_conparam())
12666 {
12667 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
12668 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
12669 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
12670 hdd_wlan_exit(pHddCtx);
12671 vos_preClose( &pVosContext );
12672 goto done;
12673 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012674 else
12675 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053012676 /* We wait for active entry threads to exit from driver
12677 * by waiting until rtnl_lock is available.
12678 */
12679 rtnl_lock();
12680 rtnl_unlock();
12681
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012682 INIT_COMPLETION(pHddCtx->ssr_comp_var);
12683 if ((pHddCtx->isLogpInProgress) && (FALSE ==
12684 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
12685 {
Siddharth Bhala204f572015-01-17 02:03:36 +053012686 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012687 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053012688 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
12689 msecs_to_jiffies(30000));
12690 if(!rc)
12691 {
12692 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12693 "%s:SSR timedout, fatal error", __func__);
12694 VOS_BUG(0);
12695 }
12696 }
12697
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012698 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
12699 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012700
c_hpothu8adb97b2014-12-08 19:38:20 +053012701 /* Driver Need to send country code 00 in below condition
12702 * 1) If gCountryCodePriority is set to 1; and last country
12703 * code set is through 11d. This needs to be done in case
12704 * when NV country code is 00.
12705 * This Needs to be done as when kernel store last country
12706 * code and if stored country code is not through 11d,
12707 * in sme_HandleChangeCountryCodeByUser we will disable 11d
12708 * in next load/unload as soon as we get any country through
12709 * 11d. In sme_HandleChangeCountryCodeByUser
12710 * pMsg->countryCode will be last countryCode and
12711 * pMac->scan.countryCode11d will be country through 11d so
12712 * due to mismatch driver will disable 11d.
12713 *
12714 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053012715
c_hpothu8adb97b2014-12-08 19:38:20 +053012716 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053012717 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053012718 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053012719 {
12720 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053012721 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053012722 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
12723 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053012724
c_hpothu8adb97b2014-12-08 19:38:20 +053012725 //Do all the cleanup before deregistering the driver
12726 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012727 }
12728
Jeff Johnson295189b2012-06-20 16:38:30 -070012729 vos_preClose( &pVosContext );
12730
12731#ifdef TIMER_MANAGER
12732 vos_timer_exit();
12733#endif
12734#ifdef MEMORY_DEBUG
12735 vos_mem_exit();
12736#endif
12737
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012738#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12739 wlan_logging_sock_deinit_svc();
12740#endif
12741
Jeff Johnson295189b2012-06-20 16:38:30 -070012742done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012743 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012744
Jeff Johnson295189b2012-06-20 16:38:30 -070012745 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
12746}
12747
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012748/**---------------------------------------------------------------------------
12749
12750 \brief hdd_module_exit() - Exit function
12751
12752 This is the driver exit point (invoked when module is unloaded using rmmod)
12753
12754 \param - None
12755
12756 \return - None
12757
12758 --------------------------------------------------------------------------*/
12759static void __exit hdd_module_exit(void)
12760{
12761 hdd_driver_exit();
12762}
12763
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012764#ifdef MODULE
12765static int fwpath_changed_handler(const char *kmessage,
12766 struct kernel_param *kp)
12767{
Jeff Johnson76052702013-04-16 13:55:05 -070012768 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012769}
12770
12771static int con_mode_handler(const char *kmessage,
12772 struct kernel_param *kp)
12773{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070012774 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012775}
12776#else /* #ifdef MODULE */
12777/**---------------------------------------------------------------------------
12778
Jeff Johnson76052702013-04-16 13:55:05 -070012779 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012780
Jeff Johnson76052702013-04-16 13:55:05 -070012781 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012782 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070012783 - invoked when module parameter fwpath is modified from userspace to signal
12784 initializing the WLAN driver or when con_mode is modified from userspace
12785 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012786
12787 \return - 0 for success, non zero for failure
12788
12789 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070012790static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012791{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070012792 int ret_status;
12793
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012794 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070012795 ret_status = hdd_driver_init();
12796 wlan_hdd_inited = ret_status ? 0 : 1;
12797 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012798 }
12799
12800 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070012801
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012802 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070012803
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070012804 ret_status = hdd_driver_init();
12805 wlan_hdd_inited = ret_status ? 0 : 1;
12806 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012807}
12808
Jeff Johnson295189b2012-06-20 16:38:30 -070012809/**---------------------------------------------------------------------------
12810
Jeff Johnson76052702013-04-16 13:55:05 -070012811 \brief fwpath_changed_handler() - Handler Function
12812
12813 Handle changes to the fwpath parameter
12814
12815 \return - 0 for success, non zero for failure
12816
12817 --------------------------------------------------------------------------*/
12818static int fwpath_changed_handler(const char *kmessage,
12819 struct kernel_param *kp)
12820{
12821 int ret;
12822
12823 ret = param_set_copystring(kmessage, kp);
12824 if (0 == ret)
12825 ret = kickstart_driver();
12826 return ret;
12827}
12828
12829/**---------------------------------------------------------------------------
12830
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012831 \brief con_mode_handler() -
12832
12833 Handler function for module param con_mode when it is changed by userspace
12834 Dynamically linked - do nothing
12835 Statically linked - exit and init driver, as in rmmod and insmod
12836
Jeff Johnson76052702013-04-16 13:55:05 -070012837 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012838
Jeff Johnson76052702013-04-16 13:55:05 -070012839 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012840
12841 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070012842static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012843{
Jeff Johnson76052702013-04-16 13:55:05 -070012844 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012845
Jeff Johnson76052702013-04-16 13:55:05 -070012846 ret = param_set_int(kmessage, kp);
12847 if (0 == ret)
12848 ret = kickstart_driver();
12849 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012850}
12851#endif /* #ifdef MODULE */
12852
12853/**---------------------------------------------------------------------------
12854
Jeff Johnson295189b2012-06-20 16:38:30 -070012855 \brief hdd_get_conparam() -
12856
12857 This is the driver exit point (invoked when module is unloaded using rmmod)
12858
12859 \param - None
12860
12861 \return - tVOS_CON_MODE
12862
12863 --------------------------------------------------------------------------*/
12864tVOS_CON_MODE hdd_get_conparam ( void )
12865{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012866#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070012867 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012868#else
12869 return (tVOS_CON_MODE)curr_con_mode;
12870#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012871}
12872void hdd_set_conparam ( v_UINT_t newParam )
12873{
12874 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012875#ifndef MODULE
12876 curr_con_mode = con_mode;
12877#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012878}
12879/**---------------------------------------------------------------------------
12880
12881 \brief hdd_softap_sta_deauth() - function
12882
12883 This to take counter measure to handle deauth req from HDD
12884
12885 \param - pAdapter - Pointer to the HDD
12886
12887 \param - enable - boolean value
12888
12889 \return - None
12890
12891 --------------------------------------------------------------------------*/
12892
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012893VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
12894 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070012895{
Jeff Johnson295189b2012-06-20 16:38:30 -070012896 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012897 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070012898
12899 ENTER();
12900
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012901 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
12902 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070012903
12904 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012905 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012906 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070012907
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012908 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070012909
12910 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012911 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070012912}
12913
12914/**---------------------------------------------------------------------------
12915
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012916 \brief hdd_del_all_sta() - function
12917
12918 This function removes all the stations associated on stopping AP/P2P GO.
12919
12920 \param - pAdapter - Pointer to the HDD
12921
12922 \return - None
12923
12924 --------------------------------------------------------------------------*/
12925
12926int hdd_del_all_sta(hdd_adapter_t *pAdapter)
12927{
12928 v_U16_t i;
12929 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012930 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12931 ptSapContext pSapCtx = NULL;
12932 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12933 if(pSapCtx == NULL){
12934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12935 FL("psapCtx is NULL"));
12936 return 1;
12937 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012938 ENTER();
12939
12940 hddLog(VOS_TRACE_LEVEL_INFO,
12941 "%s: Delete all STAs associated.",__func__);
12942 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
12943 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
12944 )
12945 {
12946 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
12947 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012948 if ((pSapCtx->aStaInfo[i].isUsed) &&
12949 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012950 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012951 struct tagCsrDelStaParams delStaParams;
12952
12953 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012954 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053012955 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
12956 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012957 &delStaParams);
12958 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012959 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012960 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012961 }
12962 }
12963 }
12964
12965 EXIT();
12966 return 0;
12967}
12968
12969/**---------------------------------------------------------------------------
12970
Jeff Johnson295189b2012-06-20 16:38:30 -070012971 \brief hdd_softap_sta_disassoc() - function
12972
12973 This to take counter measure to handle deauth req from HDD
12974
12975 \param - pAdapter - Pointer to the HDD
12976
12977 \param - enable - boolean value
12978
12979 \return - None
12980
12981 --------------------------------------------------------------------------*/
12982
12983void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
12984{
12985 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12986
12987 ENTER();
12988
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053012989 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070012990
12991 //Ignore request to disassoc bcmc station
12992 if( pDestMacAddress[0] & 0x1 )
12993 return;
12994
12995 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
12996}
12997
12998void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
12999{
13000 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13001
13002 ENTER();
13003
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053013004 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070013005
13006 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
13007}
13008
Jeff Johnson295189b2012-06-20 16:38:30 -070013009/**---------------------------------------------------------------------------
13010 *
13011 * \brief hdd_get__concurrency_mode() -
13012 *
13013 *
13014 * \param - None
13015 *
13016 * \return - CONCURRENCY MODE
13017 *
13018 * --------------------------------------------------------------------------*/
13019tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
13020{
13021 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
13022 hdd_context_t *pHddCtx;
13023
13024 if (NULL != pVosContext)
13025 {
13026 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
13027 if (NULL != pHddCtx)
13028 {
13029 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
13030 }
13031 }
13032
13033 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013034 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013035 return VOS_STA;
13036}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013037v_BOOL_t
13038wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
13039{
13040 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013041
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013042 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
13043 if (pAdapter == NULL)
13044 {
13045 hddLog(VOS_TRACE_LEVEL_INFO,
13046 FL("GO doesn't exist"));
13047 return TRUE;
13048 }
13049 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
13050 {
13051 hddLog(VOS_TRACE_LEVEL_INFO,
13052 FL("GO started"));
13053 return TRUE;
13054 }
13055 else
13056 /* wait till GO changes its interface to p2p device */
13057 hddLog(VOS_TRACE_LEVEL_INFO,
13058 FL("Del_bss called, avoid apps suspend"));
13059 return FALSE;
13060
13061}
Jeff Johnson295189b2012-06-20 16:38:30 -070013062/* Decide whether to allow/not the apps power collapse.
13063 * Allow apps power collapse if we are in connected state.
13064 * if not, allow only if we are in IMPS */
13065v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
13066{
13067 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080013068 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080013069 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070013070 hdd_config_t *pConfig = pHddCtx->cfg_ini;
13071 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13072 hdd_adapter_t *pAdapter = NULL;
13073 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080013074 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013075
Jeff Johnson295189b2012-06-20 16:38:30 -070013076 if (VOS_STA_SAP_MODE == hdd_get_conparam())
13077 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013078
Yathish9f22e662012-12-10 14:21:35 -080013079 concurrent_state = hdd_get_concurrency_mode();
13080
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013081 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
13082 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
13083 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080013084#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013085
Yathish9f22e662012-12-10 14:21:35 -080013086 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013087 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080013088 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
13089 return TRUE;
13090#endif
13091
Jeff Johnson295189b2012-06-20 16:38:30 -070013092 /*loop through all adapters. TBD fix for Concurrency */
13093 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13094 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13095 {
13096 pAdapter = pAdapterNode->pAdapter;
13097 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
13098 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
13099 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080013100 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053013101 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053013102 && pmcState != STOPPED && pmcState != STANDBY &&
13103 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080013104 (eANI_BOOLEAN_TRUE == scanRspPending) ||
13105 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070013106 {
Mukul Sharma4be88422015-03-09 20:29:07 +053013107 if(pmcState == FULL_POWER &&
13108 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
13109 {
13110 /*
13111 * When SCO indication comes from Coex module , host will
13112 * enter in to full power mode, but this should not prevent
13113 * apps processor power collapse.
13114 */
13115 hddLog(LOG1,
13116 FL("Allow apps power collapse"
13117 "even when sco indication is set"));
13118 return TRUE;
13119 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080013120 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Deepthi Gowri03a979f2016-11-03 15:20:19 +053013121 "pmcState = %d scanRspPending = %d "
13122 "inMiddleOfRoaming = %d connected = %d",
13123 __func__, pmcState, scanRspPending,
13124 inMiddleOfRoaming, hdd_connIsConnected(
13125 WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )));
13126 wlan_hdd_get_tdls_stats(pAdapter);
13127 return FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013128 }
13129 }
13130 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13131 pAdapterNode = pNext;
13132 }
13133 return TRUE;
13134}
13135
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080013136/* Decides whether to send suspend notification to Riva
13137 * if any adapter is in BMPS; then it is required */
13138v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
13139{
13140 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
13141 hdd_config_t *pConfig = pHddCtx->cfg_ini;
13142
13143 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
13144 {
13145 return TRUE;
13146 }
13147 return FALSE;
13148}
13149
Jeff Johnson295189b2012-06-20 16:38:30 -070013150void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13151{
13152 switch(mode)
13153 {
Chilam Ngc4244af2013-04-01 15:37:32 -070013154 case VOS_STA_MODE:
13155 case VOS_P2P_CLIENT_MODE:
13156 case VOS_P2P_GO_MODE:
13157 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070013158 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053013159 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070013160 break;
13161 default:
13162 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070013163 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053013164 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
13165 "Number of open sessions for mode %d = %d"),
13166 pHddCtx->concurrency_mode, mode,
13167 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070013168}
13169
13170
13171void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13172{
13173 switch(mode)
13174 {
Chilam Ngc4244af2013-04-01 15:37:32 -070013175 case VOS_STA_MODE:
13176 case VOS_P2P_CLIENT_MODE:
13177 case VOS_P2P_GO_MODE:
13178 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053013179 pHddCtx->no_of_open_sessions[mode]--;
13180 if (!(pHddCtx->no_of_open_sessions[mode]))
13181 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013182 break;
13183 default:
13184 break;
13185 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053013186 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
13187 "Number of open sessions for mode %d = %d"),
13188 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
13189
13190}
13191/**---------------------------------------------------------------------------
13192 *
13193 * \brief wlan_hdd_incr_active_session()
13194 *
13195 * This function increments the number of active sessions
13196 * maintained per device mode
13197 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
13198 * Incase of SAP/P2P GO upon bss start it is incremented
13199 *
13200 * \param pHddCtx - HDD Context
13201 * \param mode - device mode
13202 *
13203 * \return - None
13204 *
13205 * --------------------------------------------------------------------------*/
13206void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13207{
13208 switch (mode) {
13209 case VOS_STA_MODE:
13210 case VOS_P2P_CLIENT_MODE:
13211 case VOS_P2P_GO_MODE:
13212 case VOS_STA_SAP_MODE:
13213 pHddCtx->no_of_active_sessions[mode]++;
13214 break;
13215 default:
13216 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
13217 break;
13218 }
13219 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
13220 mode,
13221 pHddCtx->no_of_active_sessions[mode]);
13222}
13223
13224/**---------------------------------------------------------------------------
13225 *
13226 * \brief wlan_hdd_decr_active_session()
13227 *
13228 * This function decrements the number of active sessions
13229 * maintained per device mode
13230 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
13231 * Incase of SAP/P2P GO upon bss stop it is decremented
13232 *
13233 * \param pHddCtx - HDD Context
13234 * \param mode - device mode
13235 *
13236 * \return - None
13237 *
13238 * --------------------------------------------------------------------------*/
13239void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13240{
Bhargav Shahd0715912015-10-01 18:17:37 +053013241
Agarwal Ashish51325b52014-06-16 16:50:49 +053013242 switch (mode) {
13243 case VOS_STA_MODE:
13244 case VOS_P2P_CLIENT_MODE:
13245 case VOS_P2P_GO_MODE:
13246 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053013247 if (pHddCtx->no_of_active_sessions[mode] > 0)
13248 pHddCtx->no_of_active_sessions[mode]--;
13249 else
13250 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
13251 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053013252 break;
13253 default:
13254 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
13255 break;
13256 }
13257 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
13258 mode,
13259 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070013260}
13261
Jeff Johnsone7245742012-09-05 17:12:55 -070013262/**---------------------------------------------------------------------------
13263 *
13264 * \brief wlan_hdd_restart_init
13265 *
13266 * This function initalizes restart timer/flag. An internal function.
13267 *
13268 * \param - pHddCtx
13269 *
13270 * \return - None
13271 *
13272 * --------------------------------------------------------------------------*/
13273
13274static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
13275{
13276 /* Initialize */
13277 pHddCtx->hdd_restart_retries = 0;
13278 atomic_set(&pHddCtx->isRestartInProgress, 0);
13279 vos_timer_init(&pHddCtx->hdd_restart_timer,
13280 VOS_TIMER_TYPE_SW,
13281 wlan_hdd_restart_timer_cb,
13282 pHddCtx);
13283}
13284/**---------------------------------------------------------------------------
13285 *
13286 * \brief wlan_hdd_restart_deinit
13287 *
13288 * This function cleans up the resources used. An internal function.
13289 *
13290 * \param - pHddCtx
13291 *
13292 * \return - None
13293 *
13294 * --------------------------------------------------------------------------*/
13295
13296static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
13297{
13298
13299 VOS_STATUS vos_status;
13300 /* Block any further calls */
13301 atomic_set(&pHddCtx->isRestartInProgress, 1);
13302 /* Cleanup */
13303 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
13304 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013305 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070013306 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
13307 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013308 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070013309
13310}
13311
13312/**---------------------------------------------------------------------------
13313 *
13314 * \brief wlan_hdd_framework_restart
13315 *
13316 * This function uses a cfg80211 API to start a framework initiated WLAN
13317 * driver module unload/load.
13318 *
13319 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
13320 *
13321 *
13322 * \param - pHddCtx
13323 *
13324 * \return - VOS_STATUS_SUCCESS: Success
13325 * VOS_STATUS_E_EMPTY: Adapter is Empty
13326 * VOS_STATUS_E_NOMEM: No memory
13327
13328 * --------------------------------------------------------------------------*/
13329
13330static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
13331{
13332 VOS_STATUS status = VOS_STATUS_SUCCESS;
13333 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013334 int len = (sizeof (struct ieee80211_mgmt));
13335 struct ieee80211_mgmt *mgmt = NULL;
13336
13337 /* Prepare the DEAUTH managment frame with reason code */
13338 mgmt = kzalloc(len, GFP_KERNEL);
13339 if(mgmt == NULL)
13340 {
13341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13342 "%s: memory allocation failed (%d bytes)", __func__, len);
13343 return VOS_STATUS_E_NOMEM;
13344 }
13345 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070013346
13347 /* Iterate over all adapters/devices */
13348 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013349 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
13350 {
13351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13352 FL("fail to get adapter: %p %d"), pAdapterNode, status);
13353 goto end;
13354 }
13355
Jeff Johnsone7245742012-09-05 17:12:55 -070013356 do
13357 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013358 if(pAdapterNode->pAdapter &&
13359 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070013360 {
13361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13362 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
13363 pAdapterNode->pAdapter->dev->name,
13364 pAdapterNode->pAdapter->device_mode,
13365 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013366 /*
13367 * CFG80211 event to restart the driver
13368 *
13369 * 'cfg80211_send_unprot_deauth' sends a
13370 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
13371 * of SME(Linux Kernel) state machine.
13372 *
13373 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
13374 * the driver.
13375 *
13376 */
Abhishek Singh00b71972016-01-07 10:51:04 +053013377
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053013378#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
13379 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
13380#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013381 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053013382#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013383 }
13384 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13385 pAdapterNode = pNext;
13386 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
13387
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013388 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013389 /* Free the allocated management frame */
13390 kfree(mgmt);
13391
Jeff Johnsone7245742012-09-05 17:12:55 -070013392 /* Retry until we unload or reach max count */
13393 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
13394 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
13395
13396 return status;
13397
13398}
13399/**---------------------------------------------------------------------------
13400 *
13401 * \brief wlan_hdd_restart_timer_cb
13402 *
13403 * Restart timer callback. An internal function.
13404 *
13405 * \param - User data:
13406 *
13407 * \return - None
13408 *
13409 * --------------------------------------------------------------------------*/
13410
13411void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
13412{
13413 hdd_context_t *pHddCtx = usrDataForCallback;
13414 wlan_hdd_framework_restart(pHddCtx);
13415 return;
13416
13417}
13418
13419
13420/**---------------------------------------------------------------------------
13421 *
13422 * \brief wlan_hdd_restart_driver
13423 *
13424 * This function sends an event to supplicant to restart the WLAN driver.
13425 *
13426 * This function is called from vos_wlanRestart.
13427 *
13428 * \param - pHddCtx
13429 *
13430 * \return - VOS_STATUS_SUCCESS: Success
13431 * VOS_STATUS_E_EMPTY: Adapter is Empty
13432 * VOS_STATUS_E_ALREADY: Request already in progress
13433
13434 * --------------------------------------------------------------------------*/
13435VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
13436{
13437 VOS_STATUS status = VOS_STATUS_SUCCESS;
13438
13439 /* A tight check to make sure reentrancy */
13440 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
13441 {
Mihir Shetefd528652014-06-23 19:07:50 +053013442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070013443 "%s: WLAN restart is already in progress", __func__);
13444
13445 return VOS_STATUS_E_ALREADY;
13446 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070013447 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080013448#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053013449 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070013450#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070013451
Jeff Johnsone7245742012-09-05 17:12:55 -070013452 return status;
13453}
13454
Bhargav Shahd0715912015-10-01 18:17:37 +053013455/**
13456 * hdd_get_total_sessions() - provide total number of active sessions
13457 * @pHddCtx: Valid Global HDD context pointer
13458 *
13459 * This function iterates through pAdaptors and find the number of all active
13460 * sessions. This active sessions includes connected sta, p2p client and number
13461 * of client connected to sap/p2p go.
13462 *
13463 * Return: Total number of active sessions.
13464 */
13465v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx)
13466{
13467 v_U8_t active_session = 0;
13468 hdd_station_ctx_t *pHddStaCtx;
13469 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13470 hdd_adapter_t *pAdapter;
13471 VOS_STATUS status;
13472
13473 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13474 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
13475 pAdapter = pAdapterNode->pAdapter;
13476 switch (pAdapter->device_mode) {
13477 case VOS_STA_MODE:
13478 case VOS_P2P_CLIENT_MODE:
13479 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13480 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
13481 active_session += 1;
13482 break;
13483 case VOS_STA_SAP_MODE:
13484 case VOS_P2P_GO_MODE:
13485 active_session += hdd_softap_get_connected_sta(pAdapter);
13486 break;
13487 default:
13488 break;
13489 }
13490
13491 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
13492 pAdapterNode = pNext;
13493 }
13494
13495 return active_session;
13496}
13497
13498/**
13499 * hdd_set_delack_value() - Set delack value
13500 * @pHddCtx: Valid Global HDD context pointer
13501 * @next_rx_level: Value to set for delack
13502 *
13503 * This function compare present value and next value of delack. If the both
13504 * are diffrent then it sets next value .
13505 *
13506 * Return: void.
13507 */
13508void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
13509{
13510 if (pHddCtx->cur_rx_level != next_rx_level) {
13511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13512 "%s: TCP DELACK trigger level %d",
13513 __func__, next_rx_level);
13514 mutex_lock(&pHddCtx->cur_rx_level_lock);
13515 pHddCtx->cur_rx_level = next_rx_level;
13516 mutex_unlock(&pHddCtx->cur_rx_level_lock);
13517 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &next_rx_level,
13518 sizeof(next_rx_level));
13519 }
13520}
13521
13522/**
13523 * hdd_set_default_stop_delack_timer() - Start delack timer
13524 * @pHddCtx: Valid Global HDD context pointer
13525 *
13526 * This function stop delack timer and set delack value to default..
13527 *
13528 * Return: void.
13529 */
13530
13531void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
13532{
13533 if (VOS_TIMER_STATE_RUNNING !=
13534 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
13535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13536 "%s: Can not stop timer", __func__);
13537 return;
13538 }
13539
13540 vos_timer_stop(&pHddCtx->delack_timer);
13541 hdd_set_delack_value(pHddCtx, TP_IND_LOW);
13542}
13543
13544/**
13545 * hdd_start_delack_timer() - Start delack timer
13546 * @pHddCtx: Valid Global HDD context pointer
13547 *
13548 * This function starts the delack timer for tcpDelAckComputeInterval time
13549 * interval.The default timer value is 2 second.
13550 *
13551 * Return: void.
13552 */
13553void hdd_start_delack_timer(hdd_context_t *pHddCtx)
13554{
13555 if (VOS_TIMER_STATE_RUNNING ==
13556 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
13557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13558 "%s: Timer is already running", __func__);
13559 return;
13560 }
13561
13562 vos_timer_start(&pHddCtx->delack_timer,
13563 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
13564}
13565
13566/**
13567 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
13568 * @pHddCtx: Valid Global HDD context pointer
13569 *
13570 * This function updates the prev_rx_packets count from the corresponding
13571 * pAdapter states. This prev_rx_packets will diffed with the packet count
13572 * at the end of delack timer. That can give number of RX packet is spacific
13573 * time.
13574 *
13575 * Return: void.
13576 */
13577void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
13578{
13579 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13580 hdd_adapter_t *pAdapter;
13581 VOS_STATUS status;
13582
13583 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13584 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
13585 pAdapter = pAdapterNode->pAdapter;
13586 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
13587 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13588 pAdapterNode = pNext;
13589 }
13590}
13591
13592/**
13593 * hdd_manage_delack_timer() - start\stop delack timer
13594 * @pHddCtx: Valid Global HDD context pointer
13595 *
13596 * This function check the number of concerent session present, it starts the
13597 * delack timer if only one session is present.
13598 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
13599 *
13600 * Return: void.
13601 */
13602void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
13603{
13604 uint8_t sessions;
13605
13606 if (!pHddCtx->cfg_ini->enable_delack) {
13607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13608 "%s: TCP DELACK is not enabled", __func__);
13609 return;
13610 }
13611
13612 /* Blindly stop timer of BTCOEX and TDLS Session is up */
13613 if (pHddCtx->mode != 0) {
13614 hdd_set_default_stop_delack_timer(pHddCtx);
13615 return;
13616 }
13617
13618 sessions = hdd_get_total_sessions(pHddCtx);
13619 if (sessions == 1) {
13620 hdd_update_prev_rx_packet_count(pHddCtx);
13621 hdd_start_delack_timer(pHddCtx);
13622 } else {
13623 hdd_set_default_stop_delack_timer(pHddCtx);
13624 }
13625}
13626
Mihir Shetee1093ba2014-01-21 20:13:32 +053013627/**---------------------------------------------------------------------------
13628 *
13629 * \brief wlan_hdd_init_channels
13630 *
13631 * This function is used to initialize the channel list in CSR
13632 *
13633 * This function is called from hdd_wlan_startup
13634 *
13635 * \param - pHddCtx: HDD context
13636 *
13637 * \return - VOS_STATUS_SUCCESS: Success
13638 * VOS_STATUS_E_FAULT: Failure reported by SME
13639
13640 * --------------------------------------------------------------------------*/
13641static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
13642{
13643 eHalStatus status;
13644
13645 status = sme_InitChannels(pHddCtx->hHal);
13646 if (HAL_STATUS_SUCCESS(status))
13647 {
13648 return VOS_STATUS_SUCCESS;
13649 }
13650 else
13651 {
13652 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
13653 __func__, status);
13654 return VOS_STATUS_E_FAULT;
13655 }
13656}
13657
Mihir Shete04206452014-11-20 17:50:58 +053013658#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013659VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013660{
13661 eHalStatus status;
13662
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013663 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013664 if (HAL_STATUS_SUCCESS(status))
13665 {
13666 return VOS_STATUS_SUCCESS;
13667 }
13668 else
13669 {
13670 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
13671 __func__, status);
13672 return VOS_STATUS_E_FAULT;
13673 }
13674}
Mihir Shete04206452014-11-20 17:50:58 +053013675#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070013676/*
13677 * API to find if there is any STA or P2P-Client is connected
13678 */
13679VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
13680{
13681 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
13682}
Jeff Johnsone7245742012-09-05 17:12:55 -070013683
Mihir Shetee2ae82a2015-03-16 14:08:49 +053013684
13685/*
13686 * API to find if the firmware will send logs using DXE channel
13687 */
13688v_U8_t hdd_is_fw_logging_enabled(void)
13689{
13690 hdd_context_t *pHddCtx;
13691
13692 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
13693 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
13694
Sachin Ahuja084313e2015-05-21 17:57:10 +053013695 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053013696}
13697
Agarwal Ashish57e84372014-12-05 18:26:53 +053013698/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053013699 * API to find if the firmware will send trace logs using DXE channel
13700 */
13701v_U8_t hdd_is_fw_ev_logging_enabled(void)
13702{
13703 hdd_context_t *pHddCtx;
13704
13705 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
13706 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
13707
13708 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
13709}
13710/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053013711 * API to find if there is any session connected
13712 */
13713VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
13714{
13715 return sme_is_any_session_connected(pHddCtx->hHal);
13716}
13717
13718
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013719int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
13720{
13721 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13722 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053013723 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053013724 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013725
13726 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053013727 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013728 if (pScanInfo->mScanPending)
13729 {
c_hpothua3d45d52015-01-05 14:11:17 +053013730 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
13731 eCSR_SCAN_ABORT_DEFAULT);
13732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13733 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013734
c_hpothua3d45d52015-01-05 14:11:17 +053013735 /* If there is active scan command lets wait for the completion else
13736 * there is no need to wait as scan command might be in the SME pending
13737 * command list.
13738 */
13739 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
13740 {
c_hpothua3d45d52015-01-05 14:11:17 +053013741 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013742 &pScanInfo->abortscan_event_var,
13743 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053013744 if (0 >= status)
13745 {
13746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053013747 "%s: Timeout or Interrupt occurred while waiting for abort"
13748 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053013749 return -ETIMEDOUT;
13750 }
13751 }
13752 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
13753 {
13754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13755 FL("hdd_abort_mac_scan failed"));
13756 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013757 }
13758 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053013759 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013760}
13761
Abhishek Singh7d624e12015-11-30 14:29:27 +053013762/**
13763 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
13764 * user space
13765 * @frame_ind: Management frame data to be informed.
13766 *
13767 * This function is used to indicate management frame to
13768 * user space
13769 *
13770 * Return: None
13771 *
13772 */
13773void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
13774{
13775 hdd_context_t *hdd_ctx = NULL;
13776 hdd_adapter_t *adapter = NULL;
13777 v_CONTEXT_t vos_context = NULL;
13778
13779 /* Get the global VOSS context.*/
13780 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13781 if (!vos_context) {
13782 hddLog(LOGE, FL("Global VOS context is Null"));
13783 return;
13784 }
13785 /* Get the HDD context.*/
13786 hdd_ctx =
13787 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
13788
13789 if (0 != wlan_hdd_validate_context(hdd_ctx))
13790 {
13791 return;
13792 }
13793 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
13794 frame_ind->sessionId);
13795
13796 if ((NULL != adapter) &&
13797 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
13798 __hdd_indicate_mgmt_frame(adapter,
13799 frame_ind->frameLen,
13800 frame_ind->frameBuf,
13801 frame_ind->frameType,
13802 frame_ind->rxChan,
13803 frame_ind->rxRssi);
13804 return;
13805
13806}
13807
c_hpothu225aa7c2014-10-22 17:45:13 +053013808VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
13809{
13810 hdd_adapter_t *pAdapter;
13811 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13812 VOS_STATUS vosStatus;
13813
13814 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13815 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
13816 {
13817 pAdapter = pAdapterNode->pAdapter;
13818 if (NULL != pAdapter)
13819 {
13820 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
13821 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
13822 WLAN_HDD_P2P_GO == pAdapter->device_mode)
13823 {
13824 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
13825 pAdapter->device_mode);
13826 if (VOS_STATUS_SUCCESS !=
13827 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
13828 {
13829 hddLog(LOGE, FL("failed to abort ROC"));
13830 return VOS_STATUS_E_FAILURE;
13831 }
13832 }
13833 }
13834 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13835 pAdapterNode = pNext;
13836 }
13837 return VOS_STATUS_SUCCESS;
13838}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053013839
Mihir Shete0be28772015-02-17 18:42:14 +053013840hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
13841{
13842 hdd_adapter_t *pAdapter;
13843 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13844 hdd_cfg80211_state_t *cfgState;
13845 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
13846 VOS_STATUS vosStatus;
13847
13848 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
13849 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
13850 {
13851 pAdapter = pAdapterNode->pAdapter;
13852 if (NULL != pAdapter)
13853 {
13854 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
13855 pRemainChanCtx = cfgState->remain_on_chan_ctx;
13856 if (pRemainChanCtx)
13857 break;
13858 }
13859 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
13860 pAdapterNode = pNext;
13861 }
13862 return pRemainChanCtx;
13863}
13864
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053013865/**
13866 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
13867 *
13868 * @pHddCtx: HDD context within host driver
13869 * @dfsScanMode: dfsScanMode passed from ioctl
13870 *
13871 */
13872
13873VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
13874 tANI_U8 dfsScanMode)
13875{
13876 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13877 hdd_adapter_t *pAdapter;
13878 VOS_STATUS vosStatus;
13879 hdd_station_ctx_t *pHddStaCtx;
13880 eHalStatus status = eHAL_STATUS_SUCCESS;
13881
13882 if(!pHddCtx)
13883 {
13884 hddLog(LOGE, FL("HDD context is Null"));
13885 return eHAL_STATUS_FAILURE;
13886 }
13887
13888 if (pHddCtx->scan_info.mScanPending)
13889 {
13890 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
13891 pHddCtx->scan_info.sessionId);
13892 hdd_abort_mac_scan(pHddCtx,
13893 pHddCtx->scan_info.sessionId,
13894 eCSR_SCAN_ABORT_DEFAULT);
13895 }
13896
13897 if (!dfsScanMode)
13898 {
13899 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
13900 while ((NULL != pAdapterNode) &&
13901 (VOS_STATUS_SUCCESS == vosStatus))
13902 {
13903 pAdapter = pAdapterNode->pAdapter;
13904
13905 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
13906 {
13907 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13908
13909 if(!pHddStaCtx)
13910 {
13911 hddLog(LOGE, FL("HDD STA context is Null"));
13912 return eHAL_STATUS_FAILURE;
13913 }
13914
13915 /* if STA is already connected on DFS channel,
13916 disconnect immediately*/
13917 if (hdd_connIsConnected(pHddStaCtx) &&
13918 (NV_CHANNEL_DFS ==
13919 vos_nv_getChannelEnabledState(
13920 pHddStaCtx->conn_info.operationChannel)))
13921 {
13922 status = sme_RoamDisconnect(pHddCtx->hHal,
13923 pAdapter->sessionId,
13924 eCSR_DISCONNECT_REASON_UNSPECIFIED);
13925 hddLog(LOG1, FL("Client connected on DFS channel %d,"
13926 "sme_RoamDisconnect returned with status: %d"
13927 "for sessionid: %d"), pHddStaCtx->conn_info.
13928 operationChannel, status, pAdapter->sessionId);
13929 }
13930 }
13931
13932 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
13933 &pNext);
13934 pAdapterNode = pNext;
13935 }
13936 }
13937
13938 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
13939 sme_UpdateDFSRoamMode(pHddCtx->hHal,
13940 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
13941
13942 status = sme_HandleDFSChanScan(pHddCtx->hHal);
13943 if (!HAL_STATUS_SUCCESS(status))
13944 {
13945 hddLog(LOGE,
13946 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
13947 return status;
13948 }
13949
13950 return status;
13951}
13952
Nirav Shah7e3c8132015-06-22 23:51:42 +053013953static int hdd_log2_ceil(unsigned value)
13954{
13955 /* need to switch to unsigned math so that negative values
13956 * will right-shift towards 0 instead of -1
13957 */
13958 unsigned tmp = value;
13959 int log2 = -1;
13960
13961 if (value == 0)
13962 return 0;
13963
13964 while (tmp) {
13965 log2++;
13966 tmp >>= 1;
13967 }
13968 if (1U << log2 != value)
13969 log2++;
13970
13971 return log2;
13972}
13973
13974/**
13975 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
13976 * @pAdapter: adapter handle
13977 *
13978 * Return: vos status
13979 */
13980VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
13981{
13982 int hash_elem, log2, i;
13983
13984 spin_lock_bh( &pAdapter->sta_hash_lock);
13985 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
13986 spin_unlock_bh( &pAdapter->sta_hash_lock);
13987 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13988 "%s: hash already attached for session id %d",
13989 __func__, pAdapter->sessionId);
13990 return VOS_STATUS_SUCCESS;
13991 }
13992 spin_unlock_bh( &pAdapter->sta_hash_lock);
13993
13994 hash_elem = WLAN_MAX_STA_COUNT;
13995 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
13996 log2 = hdd_log2_ceil(hash_elem);
13997 hash_elem = 1 << log2;
13998
13999 pAdapter->sta_id_hash.mask = hash_elem - 1;
14000 pAdapter->sta_id_hash.idx_bits = log2;
14001 pAdapter->sta_id_hash.bins =
14002 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
14003 if (!pAdapter->sta_id_hash.bins) {
14004 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14005 "%s: malloc failed for session %d",
14006 __func__, pAdapter->sessionId);
14007 return VOS_STATUS_E_NOMEM;
14008 }
14009
14010 for (i = 0; i < hash_elem; i++)
14011 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
14012
14013 spin_lock_bh( &pAdapter->sta_hash_lock);
14014 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
14015 spin_unlock_bh( &pAdapter->sta_hash_lock);
14016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14017 "%s: Station ID Hash attached for session id %d",
14018 __func__, pAdapter->sessionId);
14019
14020 return VOS_STATUS_SUCCESS;
14021}
14022
14023/**
14024 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
14025 * @pAdapter: adapter handle
14026 *
14027 * Return: vos status
14028 */
14029VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
14030{
14031 int hash_elem, i;
14032 v_SIZE_t size;
14033
14034 spin_lock_bh( &pAdapter->sta_hash_lock);
14035 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14036 spin_unlock_bh( &pAdapter->sta_hash_lock);
14037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14038 "%s: hash not initialized for session id %d",
14039 __func__, pAdapter->sessionId);
14040 return VOS_STATUS_SUCCESS;
14041 }
14042
14043 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
14044 spin_unlock_bh( &pAdapter->sta_hash_lock);
14045
14046 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
14047
14048 /* free all station info*/
14049 for (i = 0; i < hash_elem; i++) {
14050 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
14051 if (size != 0) {
14052 VOS_STATUS status;
14053 hdd_staid_hash_node_t *sta_info_node = NULL;
14054 hdd_staid_hash_node_t *next_node = NULL;
14055 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
14056 (hdd_list_node_t**) &sta_info_node );
14057
14058 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14059 {
14060 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
14061 &sta_info_node->node);
14062 vos_mem_free(sta_info_node);
14063
14064 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
14065 (hdd_list_node_t*)sta_info_node,
14066 (hdd_list_node_t**)&next_node);
14067 sta_info_node = next_node;
14068 }
14069 }
14070 }
14071
14072 vos_mem_free(pAdapter->sta_id_hash.bins);
14073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14074 "%s: Station ID Hash detached for session id %d",
14075 __func__, pAdapter->sessionId);
14076 return VOS_STATUS_SUCCESS;
14077}
14078
14079/**
14080 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
14081 * @pAdapter: adapter handle
14082 * @mac_addr_in: input mac address
14083 *
14084 * Return: index derived from mac address
14085 */
14086int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
14087 v_MACADDR_t *mac_addr_in)
14088{
14089 uint16 index;
14090 struct hdd_align_mac_addr_t * mac_addr =
14091 (struct hdd_align_mac_addr_t *)mac_addr_in;
14092
14093 index = mac_addr->bytes_ab ^
14094 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
14095 index ^= index >> pAdapter->sta_id_hash.idx_bits;
14096 index &= pAdapter->sta_id_hash.mask;
14097 return index;
14098}
14099
14100/**
14101 * hdd_sta_id_hash_add_entry() - add entry in hash
14102 * @pAdapter: adapter handle
14103 * @sta_id: station id
14104 * @mac_addr: mac address
14105 *
14106 * Return: vos status
14107 */
14108VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
14109 v_U8_t sta_id, v_MACADDR_t *mac_addr)
14110{
14111 uint16 index;
14112 hdd_staid_hash_node_t *sta_info_node = NULL;
14113
Nirav Shah7e3c8132015-06-22 23:51:42 +053014114 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
14115 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
14116 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053014117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14118 "%s: malloc failed", __func__);
14119 return VOS_STATUS_E_NOMEM;
14120 }
14121
14122 sta_info_node->sta_id = sta_id;
14123 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
14124
Nirav Shah303ed5c2015-08-24 10:29:25 +053014125 spin_lock_bh( &pAdapter->sta_hash_lock);
14126 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14127 spin_unlock_bh( &pAdapter->sta_hash_lock);
14128 vos_mem_free(sta_info_node);
14129 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14130 "%s: hash is not initialized for session id %d",
14131 __func__, pAdapter->sessionId);
14132 return VOS_STATUS_E_FAILURE;
14133 }
14134
Nirav Shah7e3c8132015-06-22 23:51:42 +053014135 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
14136 (hdd_list_node_t*) sta_info_node );
14137 spin_unlock_bh( &pAdapter->sta_hash_lock);
14138 return VOS_STATUS_SUCCESS;
14139}
14140
14141/**
14142 * hdd_sta_id_hash_remove_entry() - remove entry from hash
14143 * @pAdapter: adapter handle
14144 * @sta_id: station id
14145 * @mac_addr: mac address
14146 *
14147 * Return: vos status
14148 */
14149VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
14150 v_U8_t sta_id, v_MACADDR_t *mac_addr)
14151{
14152 uint16 index;
14153 VOS_STATUS status;
14154 hdd_staid_hash_node_t *sta_info_node = NULL;
14155 hdd_staid_hash_node_t *next_node = NULL;
14156
14157 spin_lock_bh( &pAdapter->sta_hash_lock);
14158 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14159 spin_unlock_bh( &pAdapter->sta_hash_lock);
14160 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14161 "%s: hash is not initialized for session id %d",
14162 __func__, pAdapter->sessionId);
14163 return VOS_STATUS_E_FAILURE;
14164 }
14165
14166 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
14167 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
14168 (hdd_list_node_t**) &sta_info_node );
14169
14170 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14171 {
14172 if (sta_info_node->sta_id == sta_id) {
14173 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
14174 &sta_info_node->node);
14175 vos_mem_free(sta_info_node);
14176 break;
14177 }
14178 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
14179 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
14180 sta_info_node = next_node;
14181 }
14182 spin_unlock_bh( &pAdapter->sta_hash_lock);
14183 return status;
14184}
14185
14186/**
14187 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
14188 * @pAdapter: adapter handle
14189 * @mac_addr_in: mac address
14190 *
14191 * Return: station id
14192 */
14193int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
14194 v_MACADDR_t *mac_addr_in)
14195{
14196 uint8 is_found = 0;
14197 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
14198 uint16 index;
14199 VOS_STATUS status;
14200 hdd_staid_hash_node_t *sta_info_node = NULL;
14201 hdd_staid_hash_node_t *next_node = NULL;
14202
14203 spin_lock_bh( &pAdapter->sta_hash_lock);
14204 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14205 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053014206 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053014207 FL("hash is not initialized for session id %d"),
14208 pAdapter->sessionId);
14209 return HDD_WLAN_INVALID_STA_ID;
14210 }
14211
14212 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
14213 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
14214 (hdd_list_node_t**) &sta_info_node );
14215
14216 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14217 {
14218 if (vos_mem_compare(&sta_info_node->mac_addr,
14219 mac_addr_in, sizeof(v_MACADDR_t))) {
14220 is_found = 1;
14221 sta_id = sta_info_node->sta_id;
14222 break;
14223 }
14224 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
14225 (hdd_list_node_t*)sta_info_node,
14226 (hdd_list_node_t**)&next_node);
14227 sta_info_node = next_node;
14228 }
14229 spin_unlock_bh( &pAdapter->sta_hash_lock);
14230 return sta_id;
14231}
14232
c_manjeecfd1efb2015-09-25 19:32:34 +053014233/*FW memory dump feature*/
14234/**
14235 * This structure hold information about the /proc file
14236 *
14237 */
14238static struct proc_dir_entry *proc_file, *proc_dir;
14239
14240/**
14241 * memdump_read() - perform read operation in memory dump proc file
14242 *
14243 * @file - handle for the proc file.
14244 * @buf - pointer to user space buffer.
14245 * @count - number of bytes to be read.
14246 * @pos - offset in the from buffer.
14247 *
14248 * This function performs read operation for the memory dump proc file.
14249 *
14250 * Return: number of bytes read on success, error code otherwise.
14251 */
14252static ssize_t memdump_read(struct file *file, char __user *buf,
14253 size_t count, loff_t *pos)
14254{
14255 int status;
14256 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
14257 size_t ret_count;
c_manjeef1495642015-10-13 18:35:01 +053014258 loff_t bytes_left;
c_manjeecfd1efb2015-09-25 19:32:34 +053014259 ENTER();
14260
14261 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
14262 status = wlan_hdd_validate_context(hdd_ctx);
14263 if (0 != status) {
14264 return -EINVAL;
14265 }
14266
14267 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
14268 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
14269 return -EINVAL;
14270 }
14271
14272 /* run fs_read_handler in an atomic context*/
14273 vos_ssr_protect(__func__);
c_manjeef1495642015-10-13 18:35:01 +053014274 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left);
14275 if(bytes_left == 0)
c_manjeecfd1efb2015-09-25 19:32:34 +053014276 {
14277 /*Free the fwr mem dump buffer */
14278 wlan_free_fwr_mem_dump_buffer();
14279 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeef1495642015-10-13 18:35:01 +053014280 ret_count=0;
c_manjeecfd1efb2015-09-25 19:32:34 +053014281 }
14282 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
14283 vos_ssr_unprotect(__func__);
14284 EXIT();
14285 return ret_count;
14286}
14287
14288/**
14289 * struct memdump_fops - file operations for memory dump feature
14290 * @read - read function for memory dump operation.
14291 *
14292 * This structure initialize the file operation handle for memory
14293 * dump feature
14294 */
14295static const struct file_operations memdump_fops = {
14296 read: memdump_read
14297};
14298
14299/*
14300* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
14301* To be passed by HDD to WDA and called upon receiving of response
14302* from firmware
14303* @fwMemDumpReqContext : memory dump request context
14304* @dump_rsp : dump response from HAL
14305* Returns none
14306*/
14307void wlan_hdd_fw_mem_dump_cb(void *fwMemDumpReqContext,
14308 tAniFwrDumpRsp *dump_rsp)
14309{
c_manjeef1495642015-10-13 18:35:01 +053014310 struct hdd_fw_mem_dump_req_ctx *pHddFwMemDumpCtx = (struct hdd_fw_mem_dump_req_ctx *)fwMemDumpReqContext;
c_manjeecfd1efb2015-09-25 19:32:34 +053014311
c_manjeef1495642015-10-13 18:35:01 +053014312 ENTER();
14313 spin_lock(&hdd_context_lock);
14314 if(!pHddFwMemDumpCtx || (FW_MEM_DUMP_MAGIC != pHddFwMemDumpCtx->magic)) {
14315 spin_unlock(&hdd_context_lock);
14316 return;
14317 }
14318 /* report the status to requesting function and free mem.*/
c_manjeecfd1efb2015-09-25 19:32:34 +053014319 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
c_manjeef1495642015-10-13 18:35:01 +053014320 hddLog(LOGE, FL("fw dump request declined by fwr"));
14321 //set the request completion variable
14322 complete(&(pHddFwMemDumpCtx->req_completion));
c_manjeecfd1efb2015-09-25 19:32:34 +053014323 //Free the allocated fwr dump
14324 wlan_free_fwr_mem_dump_buffer();
14325 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeecfd1efb2015-09-25 19:32:34 +053014326 }
c_manjeef1495642015-10-13 18:35:01 +053014327 else {
14328 hddLog(LOG1, FL("fw dump request accepted by fwr"));
14329 /* register the HDD callback which will be called by SVC */
14330 wlan_set_svc_fw_mem_dump_req_cb((void*)wlan_hdd_fw_mem_dump_req_cb,(void*)pHddFwMemDumpCtx);
14331 }
14332 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014333 EXIT();
14334
14335}
14336
14337/**
14338 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
14339 *
14340 * This function removes file/dir under proc file system that was
14341 * processing firmware memory dump
14342 *
14343 * Return: None
14344 */
14345static void memdump_procfs_remove(void)
14346{
14347 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
14348 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
14349 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
14350 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
14351 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
14352}
14353
14354/**
14355 * memdump_procfs_init() - Initialize procfs for memory dump
14356 *
14357 * @vos_ctx - Global vos context.
14358 *
14359 * This function create file under proc file system to be used later for
14360 * processing firmware memory dump
14361 *
14362 * Return: 0 on success, error code otherwise.
14363 */
14364static int memdump_procfs_init(void *vos_ctx)
14365{
14366 hdd_context_t *hdd_ctx;
14367
14368 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14369 if (!hdd_ctx) {
14370 hddLog(LOGE , FL("Invalid HDD context"));
14371 return -EINVAL;
14372 }
14373
14374 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
14375 if (proc_dir == NULL) {
14376 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
14377 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
14378 PROCFS_MEMDUMP_DIR);
14379 return -ENOMEM;
14380 }
14381
14382 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
14383 S_IRUSR | S_IWUSR, proc_dir,
14384 &memdump_fops, hdd_ctx);
14385 if (proc_file == NULL) {
14386 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
14387 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
14388 PROCFS_MEMDUMP_NAME);
14389 return -ENOMEM;
14390 }
14391
14392 hddLog(LOG1 , FL("/proc/%s/%s created"),
14393 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
14394
14395 return 0;
14396}
14397
14398/**
14399 * memdump_init() - Initialization function for memory dump feature
14400 *
14401 * This function creates proc file for memdump feature and registers
14402 * HDD callback function with SME.
14403 *
14404 * Return - 0 on success, error otherwise
14405 */
14406int memdump_init(void)
14407{
14408 hdd_context_t *hdd_ctx;
14409 void *vos_ctx;
14410 int status = 0;
14411
14412 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14413 if (!vos_ctx) {
14414 hddLog(LOGE, FL("Invalid VOS context"));
14415 return -EINVAL;
14416 }
14417
14418 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14419 if (!hdd_ctx) {
14420 hddLog(LOGE , FL("Invalid HDD context"));
14421 return -EINVAL;
14422 }
14423
14424 status = memdump_procfs_init(vos_ctx);
14425 if (status) {
14426 hddLog(LOGE , FL("Failed to create proc file"));
14427 return status;
14428 }
14429
14430 return 0;
14431}
14432
14433/**
14434 * memdump_deinit() - De initialize memdump feature
14435 *
14436 * This function removes proc file created for memdump feature.
14437 *
14438 * Return: None
14439 */
14440int memdump_deinit(void)
14441{
14442 hdd_context_t *hdd_ctx;
14443 void *vos_ctx;
14444
14445 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14446 if (!vos_ctx) {
14447 hddLog(LOGE, FL("Invalid VOS context"));
14448 return -EINVAL;
14449 }
14450
14451 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14452 if(!hdd_ctx) {
14453 hddLog(LOGE , FL("Invalid HDD context"));
14454 return -EINVAL;
14455 }
14456
14457 memdump_procfs_remove();
14458 return 0;
14459}
14460
14461/**
14462 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
14463 * Return: HAL status
14464 */
14465
14466int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
14467{
14468 tAniFwrDumpReq fw_mem_dump_req={0};
c_manjeef1495642015-10-13 18:35:01 +053014469 struct hdd_fw_mem_dump_req_ctx fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053014470 eHalStatus status = eHAL_STATUS_FAILURE;
Abhishek Singh4eca9822015-12-09 18:07:34 +053014471 int ret=0, result;
c_manjeecfd1efb2015-09-25 19:32:34 +053014472 ENTER();
c_manjeef1495642015-10-13 18:35:01 +053014473
c_manjeecfd1efb2015-09-25 19:32:34 +053014474 /*Check whether a dump request is already going on
14475 *Caution this function will free previously held memory if new dump request is allowed*/
14476 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
14477 hddLog(LOGE, FL("Fw memdump already in progress"));
14478 return -EBUSY;
14479 }
14480 //Allocate memory for fw mem dump buffer
14481 ret = wlan_fwr_mem_dump_buffer_allocation();
14482 if(ret == -EFAULT)
14483 {
14484 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
14485 return ret;
14486 }
14487 if (0 != ret) {
14488 hddLog(LOGE, FL("Fwr mem Allocation failed"));
14489 return -ENOMEM;
14490 }
c_manjeef1495642015-10-13 18:35:01 +053014491 init_completion(&fw_mem_dump_ctx.req_completion);
14492 fw_mem_dump_ctx.magic = FW_MEM_DUMP_MAGIC;
14493 fw_mem_dump_ctx.status = false;
14494
c_manjeecfd1efb2015-09-25 19:32:34 +053014495 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
c_manjeef1495642015-10-13 18:35:01 +053014496 fw_mem_dump_req.fwMemDumpReqContext = &fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053014497 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
14498 if(eHAL_STATUS_SUCCESS != status)
14499 {
14500 hddLog(VOS_TRACE_LEVEL_ERROR,
14501 "%s: fw_mem_dump_req failed ", __func__);
14502 wlan_free_fwr_mem_dump_buffer();
c_manjeef1495642015-10-13 18:35:01 +053014503 ret = -EFAULT;
14504 goto cleanup;
c_manjeecfd1efb2015-09-25 19:32:34 +053014505 }
c_manjeef1495642015-10-13 18:35:01 +053014506 /*wait for fw mem dump completion to send event to userspace*/
Abhishek Singh4eca9822015-12-09 18:07:34 +053014507 result =
14508 wait_for_completion_timeout(&fw_mem_dump_ctx.req_completion,
14509 msecs_to_jiffies(FW_MEM_DUMP_TIMEOUT_MS));
14510 if (0 >= result )
c_manjeef1495642015-10-13 18:35:01 +053014511 {
14512 hddLog(VOS_TRACE_LEVEL_ERROR,
Abhishek Singh4eca9822015-12-09 18:07:34 +053014513 "%s: fw_mem_dump_req timeout %d ", __func__,result);
14514 ret = -ETIMEDOUT;
c_manjeef1495642015-10-13 18:35:01 +053014515 }
14516cleanup:
14517 spin_lock(&hdd_context_lock);
14518 fw_mem_dump_ctx.magic = 0;
Abhishek Singh4eca9822015-12-09 18:07:34 +053014519 if(!ret && !fw_mem_dump_ctx.status)
14520 ret = -EFAULT;
c_manjeef1495642015-10-13 18:35:01 +053014521 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014522
c_manjeef1495642015-10-13 18:35:01 +053014523 EXIT();
Abhishek Singh4eca9822015-12-09 18:07:34 +053014524 return ret;
c_manjeef1495642015-10-13 18:35:01 +053014525}
14526
14527/**
14528 * HDD callback which will be called by SVC to indicate mem dump completion.
14529 */
14530void wlan_hdd_fw_mem_dump_req_cb(struct hdd_fw_mem_dump_req_ctx* pHddFwMemDumpCtx)
14531{
14532 if (!pHddFwMemDumpCtx) {
14533 hddLog(VOS_TRACE_LEVEL_ERROR,
14534 "%s: HDD context not valid ", __func__);
14535 return;
14536 }
14537 spin_lock(&hdd_context_lock);
14538 /* check the req magic and set status */
14539 if (pHddFwMemDumpCtx->magic == FW_MEM_DUMP_MAGIC)
14540 {
14541 pHddFwMemDumpCtx->status = true;
14542 //signal the completion
14543 complete(&(pHddFwMemDumpCtx->req_completion));
14544 }
14545 else
14546 {
14547 hddLog(VOS_TRACE_LEVEL_ERROR,
14548 "%s: fw mem dump request possible timeout ", __func__);
14549 }
14550 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014551}
14552
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053014553void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
14554{
14555 if (NULL == pAdapter)
14556 {
14557 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
14558 return;
14559 }
14560 init_completion(&pAdapter->session_open_comp_var);
14561 init_completion(&pAdapter->session_close_comp_var);
14562 init_completion(&pAdapter->disconnect_comp_var);
14563 init_completion(&pAdapter->linkup_event_var);
14564 init_completion(&pAdapter->cancel_rem_on_chan_var);
14565 init_completion(&pAdapter->rem_on_chan_ready_event);
14566 init_completion(&pAdapter->pno_comp_var);
14567#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14568 init_completion(&pAdapter->offchannel_tx_event);
14569#endif
14570 init_completion(&pAdapter->tx_action_cnf_event);
14571#ifdef FEATURE_WLAN_TDLS
14572 init_completion(&pAdapter->tdls_add_station_comp);
14573 init_completion(&pAdapter->tdls_del_station_comp);
14574 init_completion(&pAdapter->tdls_mgmt_comp);
14575 init_completion(&pAdapter->tdls_link_establish_req_comp);
14576#endif
14577
14578#ifdef WLAN_FEATURE_RMC
14579 init_completion(&pAdapter->ibss_peer_info_comp);
14580#endif /* WLAN_FEATURE_RMC */
14581 init_completion(&pAdapter->ula_complete);
14582 init_completion(&pAdapter->change_country_code);
14583
14584#ifdef FEATURE_WLAN_BATCH_SCAN
14585 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
14586 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
14587#endif
14588
14589 return;
14590}
c_manjeecfd1efb2015-09-25 19:32:34 +053014591
14592
Jeff Johnson295189b2012-06-20 16:38:30 -070014593//Register the module init/exit functions
14594module_init(hdd_module_init);
14595module_exit(hdd_module_exit);
14596
14597MODULE_LICENSE("Dual BSD/GPL");
14598MODULE_AUTHOR("Qualcomm Atheros, Inc.");
14599MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
14600
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014601module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
14602 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070014603
Jeff Johnson76052702013-04-16 13:55:05 -070014604module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070014605 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080014606
14607module_param(enable_dfs_chan_scan, int,
14608 S_IRUSR | S_IRGRP | S_IROTH);
14609
14610module_param(enable_11d, int,
14611 S_IRUSR | S_IRGRP | S_IROTH);
14612
14613module_param(country_code, charp,
14614 S_IRUSR | S_IRGRP | S_IROTH);