blob: faae74f646ab374a6c885e7d016f5398394edf13 [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
Anurag Chouhan83026002016-12-13 22:46:21 +05308967VOS_STATUS hdd_cleanup_ap_events(hdd_adapter_t *adapter)
8968{
8969#ifdef DHCP_SERVER_OFFLOAD
8970 vos_event_destroy(&adapter->dhcp_status.vos_event);
8971#endif
8972 return VOS_STATUS_SUCCESS;
8973}
8974
8975
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308976VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
8977 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07008978{
8979 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
8980 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308981 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008982 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05308983 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308984 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05308985 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008986
Anand N Sunkad26d71b92014-12-24 18:08:22 +05308987 if (pHddCtx->isLogpInProgress) {
8988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8989 "%s:LOGP in Progress. Ignore!!!",__func__);
8990 return VOS_STATUS_E_FAILURE;
8991 }
8992
Jeff Johnson295189b2012-06-20 16:38:30 -07008993 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308994
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308995 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07008996 switch(pAdapter->device_mode)
8997 {
Nirav Shah0cf4d892015-11-05 16:27:27 +05308998 case WLAN_HDD_IBSS:
8999 if ( VOS_TRUE == bCloseSession )
9000 {
9001 status = hdd_sta_id_hash_detach(pAdapter);
9002 if (status != VOS_STATUS_SUCCESS)
9003 hddLog(VOS_TRACE_LEVEL_ERROR,
9004 FL("sta id hash detach failed"));
9005 }
9006
Jeff Johnson295189b2012-06-20 16:38:30 -07009007 case WLAN_HDD_INFRA_STATION:
9008 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009009 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309010 {
9011 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05309012#ifdef FEATURE_WLAN_TDLS
9013 mutex_lock(&pHddCtx->tdls_lock);
9014 wlan_hdd_tdls_exit(pAdapter, TRUE);
9015 mutex_unlock(&pHddCtx->tdls_lock);
9016#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309017 if( hdd_connIsConnected(pstation) ||
9018 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009019 {
9020 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
9021 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
9022 pAdapter->sessionId,
9023 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
9024 else
9025 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
9026 pAdapter->sessionId,
9027 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Abhishek Singh7b52ed52016-02-11 17:45:54 +05309028 /* Success implies disconnect command got queued up successfully
9029 * Or cmd not queued as scan for SSID is in progress
9030 */
9031 if((eHAL_STATUS_SUCCESS == halStatus) ||
9032 (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07009033 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309034 ret = wait_for_completion_interruptible_timeout(
9035 &pAdapter->disconnect_comp_var,
9036 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singh7b52ed52016-02-11 17:45:54 +05309037 if (ret <= 0 &&
9038 (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309039 {
9040 hddLog(VOS_TRACE_LEVEL_ERROR,
9041 "%s: wait on disconnect_comp_var failed %ld",
9042 __func__, ret);
9043 }
9044 }
9045 else
9046 {
9047 hddLog(LOGE, "%s: failed to post disconnect event to SME",
9048 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009049 }
9050 memset(&wrqu, '\0', sizeof(wrqu));
9051 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
9052 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
9053 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
9054 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309055 else if(pstation->conn_info.connState ==
9056 eConnectionState_Disconnecting)
9057 {
9058 ret = wait_for_completion_interruptible_timeout(
9059 &pAdapter->disconnect_comp_var,
9060 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
9061 if (ret <= 0)
9062 {
9063 hddLog(VOS_TRACE_LEVEL_ERROR,
9064 FL("wait on disconnect_comp_var failed %ld"), ret);
9065 }
9066 }
Sachin Ahuja27dd2402016-08-01 20:30:31 +05309067 if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07009068 {
Mahesh A Saptasagar0b61dcc2016-02-15 14:23:38 +05309069 wlan_hdd_scan_abort(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009070 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +05309071 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
9072 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309073 {
9074 while (pAdapter->is_roc_inprogress)
9075 {
9076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9077 "%s: ROC in progress for session %d!!!",
9078 __func__, pAdapter->sessionId);
9079 // waiting for ROC to expire
9080 msleep(500);
9081 /* In GO present case , if retry exceeds 3,
9082 it means something went wrong. */
9083 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
9084 {
9085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9086 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05309087 if (eHAL_STATUS_SUCCESS !=
9088 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
9089 pAdapter->sessionId ))
9090 {
9091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9092 FL("Failed to Cancel Remain on Channel"));
9093 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309094 wait_for_completion_interruptible_timeout(
9095 &pAdapter->cancel_rem_on_chan_var,
9096 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
9097 break;
9098 }
9099 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309100 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309101 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309102#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309103 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309104#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309105
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309106 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309107
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309108 /* It is possible that the caller of this function does not
9109 * wish to close the session
9110 */
9111 if (VOS_TRUE == bCloseSession &&
9112 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009113 {
9114 INIT_COMPLETION(pAdapter->session_close_comp_var);
9115 if (eHAL_STATUS_SUCCESS ==
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05309116 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, FALSE,
9117 VOS_FALSE, hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07009118 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309119 unsigned long ret;
9120
Jeff Johnson295189b2012-06-20 16:38:30 -07009121 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309122 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309123 &pAdapter->session_close_comp_var,
9124 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309125 if ( 0 >= ret)
9126 {
9127 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309128 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309129 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009130 }
9131 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309132 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009133 break;
9134
9135 case WLAN_HDD_SOFTAP:
9136 case WLAN_HDD_P2P_GO:
Nirav Shah0cf4d892015-11-05 16:27:27 +05309137 if ( VOS_TRUE == bCloseSession )
9138 {
9139 status = hdd_sta_id_hash_detach(pAdapter);
9140 if (status != VOS_STATUS_SUCCESS)
9141 hddLog(VOS_TRACE_LEVEL_ERROR,
9142 FL("sta id hash detach failed"));
9143 }
9144
Jeff Johnson295189b2012-06-20 16:38:30 -07009145 //Any softap specific cleanup here...
Anurag Chouhan83026002016-12-13 22:46:21 +05309146 hdd_cleanup_ap_events(pAdapter);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309147 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
9148 while (pAdapter->is_roc_inprogress) {
9149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9150 "%s: ROC in progress for session %d!!!",
9151 __func__, pAdapter->sessionId);
9152 msleep(500);
9153 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
9154 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9155 "%s: ROC completion is not received.!!!", __func__);
9156 WLANSAP_CancelRemainOnChannel(
9157 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
9158 wait_for_completion_interruptible_timeout(
9159 &pAdapter->cancel_rem_on_chan_var,
9160 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
9161 break;
9162 }
9163 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309164
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309165 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309166 }
Agrawal Ashish17ef5082016-10-17 18:33:21 +05309167#ifdef SAP_AUTH_OFFLOAD
9168 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
9169 hdd_set_sap_auth_offload(pAdapter, FALSE);
9170#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009171 mutex_lock(&pHddCtx->sap_lock);
9172 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9173 {
9174 VOS_STATUS status;
9175 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9176
9177 //Stop Bss.
9178 status = WLANSAP_StopBss(pHddCtx->pvosContext);
9179 if (VOS_IS_STATUS_SUCCESS(status))
9180 {
9181 hdd_hostapd_state_t *pHostapdState =
9182 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9183
9184 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9185
9186 if (!VOS_IS_STATUS_SUCCESS(status))
9187 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309188 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
9189 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009190 }
9191 }
9192 else
9193 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009194 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009195 }
9196 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309197 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009198
9199 if (eHAL_STATUS_FAILURE ==
9200 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
9201 0, NULL, eANI_BOOLEAN_FALSE))
9202 {
9203 hddLog(LOGE,
9204 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009205 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009206 }
9207
9208 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
9209 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9210 eANI_BOOLEAN_FALSE) )
9211 {
9212 hddLog(LOGE,
9213 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
9214 }
9215
9216 // Reset WNI_CFG_PROBE_RSP Flags
9217 wlan_hdd_reset_prob_rspies(pAdapter);
9218 kfree(pAdapter->sessionCtx.ap.beacon);
9219 pAdapter->sessionCtx.ap.beacon = NULL;
9220 }
9221 mutex_unlock(&pHddCtx->sap_lock);
9222 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009223
Jeff Johnson295189b2012-06-20 16:38:30 -07009224 case WLAN_HDD_MONITOR:
9225 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009226
Jeff Johnson295189b2012-06-20 16:38:30 -07009227 default:
9228 break;
9229 }
9230
9231 EXIT();
9232 return VOS_STATUS_SUCCESS;
9233}
9234
9235VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
9236{
9237 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9238 VOS_STATUS status;
9239 hdd_adapter_t *pAdapter;
9240
9241 ENTER();
9242
9243 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9244
9245 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9246 {
9247 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009248
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309249 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009250
9251 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9252 pAdapterNode = pNext;
9253 }
9254
9255 EXIT();
9256
9257 return VOS_STATUS_SUCCESS;
9258}
9259
Rajeev Kumarf999e582014-01-09 17:33:29 -08009260
9261#ifdef FEATURE_WLAN_BATCH_SCAN
9262/**---------------------------------------------------------------------------
9263
9264 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
9265 structures
9266
9267 \param - pAdapter Pointer to HDD adapter
9268
9269 \return - None
9270
9271 --------------------------------------------------------------------------*/
9272void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
9273{
9274 tHddBatchScanRsp *pNode;
9275 tHddBatchScanRsp *pPrev;
9276
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05309277 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08009278 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05309279 hddLog(VOS_TRACE_LEVEL_ERROR,
9280 "%s: Adapter context is Null", __func__);
9281 return;
9282 }
9283
9284 pNode = pAdapter->pBatchScanRsp;
9285 while (pNode)
9286 {
9287 pPrev = pNode;
9288 pNode = pNode->pNext;
9289 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08009290 }
9291
9292 pAdapter->pBatchScanRsp = NULL;
9293 pAdapter->numScanList = 0;
9294 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
9295 pAdapter->prev_batch_id = 0;
9296
9297 return;
9298}
9299#endif
9300
9301
Jeff Johnson295189b2012-06-20 16:38:30 -07009302VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
9303{
9304 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9305 VOS_STATUS status;
9306 hdd_adapter_t *pAdapter;
9307
9308 ENTER();
9309
9310 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9311
9312 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9313 {
9314 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309315 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009316 netif_tx_disable(pAdapter->dev);
9317 netif_carrier_off(pAdapter->dev);
9318
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07009319 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
9320
Jeff Johnson295189b2012-06-20 16:38:30 -07009321 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05309322
Katya Nigam1fd24402015-02-16 14:52:19 +05309323 if(pAdapter->device_mode == WLAN_HDD_IBSS )
9324 hdd_ibss_deinit_tx_rx(pAdapter);
9325
Nirav Shah7e3c8132015-06-22 23:51:42 +05309326 status = hdd_sta_id_hash_detach(pAdapter);
9327 if (status != VOS_STATUS_SUCCESS)
9328 hddLog(VOS_TRACE_LEVEL_ERROR,
9329 FL("sta id hash detach failed for session id %d"),
9330 pAdapter->sessionId);
9331
Agarwal Ashish6267caa2014-08-06 19:16:21 +05309332 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
9333
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05309334 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9335 {
9336 hdd_wmm_adapter_close( pAdapter );
9337 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9338 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009339
Siddharth Bhal2db319d2014-12-03 12:37:18 +05309340 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9341 {
9342 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
9343 }
9344
Rajeev Kumarf999e582014-01-09 17:33:29 -08009345#ifdef FEATURE_WLAN_BATCH_SCAN
9346 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
9347 {
9348 hdd_deinit_batch_scan(pAdapter);
9349 }
9350#endif
9351
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05309352#ifdef FEATURE_WLAN_TDLS
9353 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05309354 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05309355 mutex_unlock(&pHddCtx->tdls_lock);
9356#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009357 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9358 pAdapterNode = pNext;
9359 }
9360
9361 EXIT();
9362
9363 return VOS_STATUS_SUCCESS;
9364}
9365
9366VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
9367{
9368 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9369 VOS_STATUS status;
9370 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309371 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07009372
9373 ENTER();
9374
9375 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9376
9377 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9378 {
9379 pAdapter = pAdapterNode->pAdapter;
9380
Kumar Anand82c009f2014-05-29 00:29:42 -07009381 hdd_wmm_init( pAdapter );
9382
Jeff Johnson295189b2012-06-20 16:38:30 -07009383 switch(pAdapter->device_mode)
9384 {
9385 case WLAN_HDD_INFRA_STATION:
9386 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009387 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309388
9389 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
9390
Jeff Johnson295189b2012-06-20 16:38:30 -07009391 hdd_init_station_mode(pAdapter);
9392 /* Open the gates for HDD to receive Wext commands */
9393 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009394 pHddCtx->scan_info.mScanPending = FALSE;
9395 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009396
9397 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +05309398 if (!pHddCtx->isLogpInProgress)
9399 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009400
9401 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309402 if (eConnectionState_Associated == connState ||
9403 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07009404 {
9405 union iwreq_data wrqu;
9406 memset(&wrqu, '\0', sizeof(wrqu));
9407 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
9408 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
9409 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07009410 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009411
Jeff Johnson295189b2012-06-20 16:38:30 -07009412 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagar9ff4bcc2016-06-01 17:17:50 +05309413 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, false,
Mahesh A Saptasagarb5a15142016-05-25 11:27:43 +05309414 WLAN_REASON_UNSPECIFIED);
Jeff Johnson295189b2012-06-20 16:38:30 -07009415 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309416 else if (eConnectionState_Connecting == connState)
9417 {
9418 /*
9419 * Indicate connect failure to supplicant if we were in the
9420 * process of connecting
9421 */
9422 cfg80211_connect_result(pAdapter->dev, NULL,
9423 NULL, 0, NULL, 0,
9424 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
9425 GFP_KERNEL);
9426 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009427 break;
9428
9429 case WLAN_HDD_SOFTAP:
9430 /* softAP can handle SSR */
9431 break;
9432
9433 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07009434 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07009435 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07009436 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009437 break;
9438
9439 case WLAN_HDD_MONITOR:
9440 /* monitor interface start */
9441 break;
9442 default:
9443 break;
9444 }
9445
9446 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9447 pAdapterNode = pNext;
9448 }
9449
9450 EXIT();
9451
9452 return VOS_STATUS_SUCCESS;
9453}
9454
9455VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
9456{
9457 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9458 hdd_adapter_t *pAdapter;
9459 VOS_STATUS status;
9460 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309461 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009462
9463 ENTER();
9464
9465 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9466
9467 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9468 {
9469 pAdapter = pAdapterNode->pAdapter;
9470
9471 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9472 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9473 {
9474 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9475 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9476
Abhishek Singhf4669da2014-05-26 15:07:49 +05309477 hddLog(VOS_TRACE_LEVEL_INFO,
9478 "%s: Set HDD connState to eConnectionState_NotConnected",
9479 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +05309480 spin_lock_bh(&pAdapter->lock_for_active_session);
9481 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
9482 {
9483 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
9484 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009485 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +05309486 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07009487 init_completion(&pAdapter->disconnect_comp_var);
9488 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
9489 eCSR_DISCONNECT_REASON_UNSPECIFIED);
9490
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309491 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009492 &pAdapter->disconnect_comp_var,
9493 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309494 if (0 >= ret)
9495 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
9496 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07009497
9498 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
9499 pHddCtx->isAmpAllowed = VOS_FALSE;
9500 sme_RoamConnect(pHddCtx->hHal,
9501 pAdapter->sessionId, &(pWextState->roamProfile),
9502 &roamId);
9503 }
9504
9505 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9506 pAdapterNode = pNext;
9507 }
9508
9509 EXIT();
9510
9511 return VOS_STATUS_SUCCESS;
9512}
9513
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009514void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
9515{
9516 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9517 VOS_STATUS status;
9518 hdd_adapter_t *pAdapter;
9519 hdd_station_ctx_t *pHddStaCtx;
9520 hdd_ap_ctx_t *pHddApCtx;
9521 hdd_hostapd_state_t * pHostapdState;
9522 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
9523 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
9524 const char *p2pMode = "DEV";
9525 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009526
9527 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9528 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9529 {
9530 pAdapter = pAdapterNode->pAdapter;
9531 switch (pAdapter->device_mode) {
9532 case WLAN_HDD_INFRA_STATION:
9533 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9534 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
9535 staChannel = pHddStaCtx->conn_info.operationChannel;
9536 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
9537 }
9538 break;
9539 case WLAN_HDD_P2P_CLIENT:
9540 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9541 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
9542 p2pChannel = pHddStaCtx->conn_info.operationChannel;
9543 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
9544 p2pMode = "CLI";
9545 }
9546 break;
9547 case WLAN_HDD_P2P_GO:
9548 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9549 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9550 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
9551 p2pChannel = pHddApCtx->operatingChannel;
9552 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
9553 }
9554 p2pMode = "GO";
9555 break;
9556 case WLAN_HDD_SOFTAP:
9557 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9558 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9559 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
9560 apChannel = pHddApCtx->operatingChannel;
9561 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
9562 }
9563 break;
9564 default:
9565 break;
9566 }
9567 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9568 pAdapterNode = pNext;
9569 }
9570 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
9571 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
9572 }
SaidiReddy Yenugaa8b32f92016-07-27 19:29:18 +05309573 hddLog(VOS_TRACE_LEVEL_INFO, "wlan(%d) " MAC_ADDRESS_STR " %s",
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009574 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
9575 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05309576 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009577 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
9578 }
9579 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05309580 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009581 apChannel, MAC_ADDR_ARRAY(apBssid));
9582 }
9583
9584 if (p2pChannel > 0 && apChannel > 0) {
9585 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
9586 }
9587}
9588
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009589bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009590{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009591 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07009592}
9593
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009594/* Once SSR is disabled then it cannot be set. */
9595void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07009596{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009597 if (HDD_SSR_DISABLED == isSsrRequired)
9598 return;
9599
Jeff Johnson295189b2012-06-20 16:38:30 -07009600 isSsrRequired = value;
9601}
9602
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05309603void hdd_set_pre_close( hdd_context_t *pHddCtx)
9604{
9605 sme_PreClose(pHddCtx->hHal);
9606}
9607
Jeff Johnson295189b2012-06-20 16:38:30 -07009608VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
9609 hdd_adapter_list_node_t** ppAdapterNode)
9610{
9611 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309612 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009613 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
9614 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309615 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009616 return status;
9617}
9618
9619VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
9620 hdd_adapter_list_node_t* pAdapterNode,
9621 hdd_adapter_list_node_t** pNextAdapterNode)
9622{
9623 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309624 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009625 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
9626 (hdd_list_node_t*) pAdapterNode,
9627 (hdd_list_node_t**)pNextAdapterNode );
9628
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309629 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009630 return status;
9631}
9632
9633VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
9634 hdd_adapter_list_node_t* pAdapterNode)
9635{
9636 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309637 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009638 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
9639 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309640 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009641 return status;
9642}
9643
9644VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
9645 hdd_adapter_list_node_t** ppAdapterNode)
9646{
9647 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309648 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009649 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
9650 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309651 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009652 return status;
9653}
9654
9655VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
9656 hdd_adapter_list_node_t* pAdapterNode)
9657{
9658 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309659 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009660 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
9661 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309662 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009663 return status;
9664}
9665
9666VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
9667 hdd_adapter_list_node_t* pAdapterNode)
9668{
9669 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309670 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009671 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
9672 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309673 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009674 return status;
9675}
9676
9677hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
9678 tSirMacAddr macAddr )
9679{
9680 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9681 hdd_adapter_t *pAdapter;
9682 VOS_STATUS status;
9683
9684 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9685
9686 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9687 {
9688 pAdapter = pAdapterNode->pAdapter;
9689
9690 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
9691 macAddr, sizeof(tSirMacAddr) ) )
9692 {
9693 return pAdapter;
9694 }
9695 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9696 pAdapterNode = pNext;
9697 }
9698
9699 return NULL;
9700
9701}
9702
9703hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
9704{
9705 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9706 hdd_adapter_t *pAdapter;
9707 VOS_STATUS status;
9708
9709 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9710
9711 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9712 {
9713 pAdapter = pAdapterNode->pAdapter;
9714
9715 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
9716 IFNAMSIZ ) )
9717 {
9718 return pAdapter;
9719 }
9720 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9721 pAdapterNode = pNext;
9722 }
9723
9724 return NULL;
9725
9726}
9727
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +05309728hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
9729 tANI_U32 sme_session_id )
9730{
9731 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9732 hdd_adapter_t *pAdapter;
9733 VOS_STATUS vos_status;
9734
9735
9736 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
9737
9738 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
9739 {
9740 pAdapter = pAdapterNode->pAdapter;
9741
9742 if (pAdapter->sessionId == sme_session_id)
9743 return pAdapter;
9744
9745 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
9746 pAdapterNode = pNext;
9747 }
9748
9749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9750 "%s: sme_session_id %d does not exist with host",
9751 __func__, sme_session_id);
9752
9753 return NULL;
9754}
9755
Jeff Johnson295189b2012-06-20 16:38:30 -07009756hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
9757{
9758 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9759 hdd_adapter_t *pAdapter;
9760 VOS_STATUS status;
9761
9762 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9763
9764 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9765 {
9766 pAdapter = pAdapterNode->pAdapter;
9767
9768 if( pAdapter && (mode == pAdapter->device_mode) )
9769 {
9770 return pAdapter;
9771 }
9772 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9773 pAdapterNode = pNext;
9774 }
9775
9776 return NULL;
9777
9778}
9779
9780//Remove this function later
9781hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
9782{
9783 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9784 hdd_adapter_t *pAdapter;
9785 VOS_STATUS status;
9786
9787 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9788
9789 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9790 {
9791 pAdapter = pAdapterNode->pAdapter;
9792
9793 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
9794 {
9795 return pAdapter;
9796 }
9797
9798 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9799 pAdapterNode = pNext;
9800 }
9801
9802 return NULL;
9803
9804}
9805
Jeff Johnson295189b2012-06-20 16:38:30 -07009806/**---------------------------------------------------------------------------
9807
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05309808 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07009809
9810 This API returns the operating channel of the requested device mode
9811
9812 \param - pHddCtx - Pointer to the HDD context.
9813 - mode - Device mode for which operating channel is required
9814 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
9815 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
9816 \return - channel number. "0" id the requested device is not found OR it is not connected.
9817 --------------------------------------------------------------------------*/
9818v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
9819{
9820 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9821 VOS_STATUS status;
9822 hdd_adapter_t *pAdapter;
9823 v_U8_t operatingChannel = 0;
9824
9825 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9826
9827 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9828 {
9829 pAdapter = pAdapterNode->pAdapter;
9830
9831 if( mode == pAdapter->device_mode )
9832 {
9833 switch(pAdapter->device_mode)
9834 {
9835 case WLAN_HDD_INFRA_STATION:
9836 case WLAN_HDD_P2P_CLIENT:
9837 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
9838 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
9839 break;
9840 case WLAN_HDD_SOFTAP:
9841 case WLAN_HDD_P2P_GO:
9842 /*softap connection info */
9843 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9844 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
9845 break;
9846 default:
9847 break;
9848 }
9849
9850 break; //Found the device of interest. break the loop
9851 }
9852
9853 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9854 pAdapterNode = pNext;
9855 }
9856 return operatingChannel;
9857}
9858
9859#ifdef WLAN_FEATURE_PACKET_FILTERING
9860/**---------------------------------------------------------------------------
9861
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309862 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07009863
9864 This used to set the multicast address list.
9865
9866 \param - dev - Pointer to the WLAN device.
9867 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309868 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07009869
9870 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309871static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07009872{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309873 hdd_adapter_t *pAdapter;
9874 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009875 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309876 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009877 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309878
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309879 ENTER();
9880
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309881 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309882 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009883 {
9884 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309885 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009886 return;
9887 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309888 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9889 ret = wlan_hdd_validate_context(pHddCtx);
9890 if (0 != ret)
9891 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309892 return;
9893 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009894 if (dev->flags & IFF_ALLMULTI)
9895 {
9896 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009897 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309898 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009899 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309900 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009901 {
9902 mc_count = netdev_mc_count(dev);
9903 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009904 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07009905 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
9906 {
9907 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009908 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309909 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009910 return;
9911 }
9912
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309913 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07009914
9915 netdev_for_each_mc_addr(ha, dev) {
9916 if (i == mc_count)
9917 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309918 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
9919 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08009920 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309921 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309922 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07009923 i++;
9924 }
9925 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309926
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +05309927 if (pHddCtx->hdd_wlan_suspended)
9928 {
9929 /*
9930 * Configure the Mcast address list to FW
9931 * If wlan is already in suspend mode
9932 */
9933 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
9934 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309935 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009936 return;
9937}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309938
9939static void hdd_set_multicast_list(struct net_device *dev)
9940{
9941 vos_ssr_protect(__func__);
9942 __hdd_set_multicast_list(dev);
9943 vos_ssr_unprotect(__func__);
9944}
Jeff Johnson295189b2012-06-20 16:38:30 -07009945#endif
9946
9947/**---------------------------------------------------------------------------
9948
9949 \brief hdd_select_queue() -
9950
9951 This function is registered with the Linux OS for network
9952 core to decide which queue to use first.
9953
9954 \param - dev - Pointer to the WLAN device.
9955 - skb - Pointer to OS packet (sk_buff).
9956 \return - ac, Queue Index/access category corresponding to UP in IP header
9957
9958 --------------------------------------------------------------------------*/
9959v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309960 struct sk_buff *skb
9961#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
9962 , void *accel_priv
9963#endif
9964#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9965 , select_queue_fallback_t fallback
9966#endif
9967)
Jeff Johnson295189b2012-06-20 16:38:30 -07009968{
9969 return hdd_wmm_select_queue(dev, skb);
9970}
9971
9972
9973/**---------------------------------------------------------------------------
9974
9975 \brief hdd_wlan_initial_scan() -
9976
9977 This function triggers the initial scan
9978
9979 \param - pAdapter - Pointer to the HDD adapter.
9980
9981 --------------------------------------------------------------------------*/
9982void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
9983{
9984 tCsrScanRequest scanReq;
9985 tCsrChannelInfo channelInfo;
9986 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07009987 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07009988 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9989
9990 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
9991 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
9992 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
9993
9994 if(sme_Is11dSupported(pHddCtx->hHal))
9995 {
9996 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
9997 if ( HAL_STATUS_SUCCESS( halStatus ) )
9998 {
9999 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
10000 if( !scanReq.ChannelInfo.ChannelList )
10001 {
10002 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
10003 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080010004 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010005 return;
10006 }
10007 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
10008 channelInfo.numOfChannels);
10009 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
10010 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080010011 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010012 }
10013
10014 scanReq.scanType = eSIR_PASSIVE_SCAN;
10015 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
10016 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
10017 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
10018 }
10019 else
10020 {
10021 scanReq.scanType = eSIR_ACTIVE_SCAN;
10022 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10023 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
10024 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
10025 }
10026
10027 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
10028 if ( !HAL_STATUS_SUCCESS( halStatus ) )
10029 {
10030 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
10031 __func__, halStatus );
10032 }
10033
10034 if(sme_Is11dSupported(pHddCtx->hHal))
10035 vos_mem_free(scanReq.ChannelInfo.ChannelList);
10036}
10037
Jeff Johnson295189b2012-06-20 16:38:30 -070010038/**---------------------------------------------------------------------------
10039
10040 \brief hdd_full_power_callback() - HDD full power callback function
10041
10042 This is the function invoked by SME to inform the result of a full power
10043 request issued by HDD
10044
10045 \param - callbackcontext - Pointer to cookie
10046 \param - status - result of request
10047
10048 \return - None
10049
10050 --------------------------------------------------------------------------*/
10051static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
10052{
Jeff Johnson72a40512013-12-19 10:14:15 -080010053 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010054
10055 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010056 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010057
10058 if (NULL == callbackContext)
10059 {
10060 hddLog(VOS_TRACE_LEVEL_ERROR,
10061 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010062 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010063 return;
10064 }
10065
Jeff Johnson72a40512013-12-19 10:14:15 -080010066 /* there is a race condition that exists between this callback
10067 function and the caller since the caller could time out either
10068 before or while this code is executing. we use a spinlock to
10069 serialize these actions */
10070 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010071
10072 if (POWER_CONTEXT_MAGIC != pContext->magic)
10073 {
10074 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -080010075 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010076 hddLog(VOS_TRACE_LEVEL_WARN,
10077 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010078 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -070010079 return;
10080 }
10081
Jeff Johnson72a40512013-12-19 10:14:15 -080010082 /* context is valid so caller is still waiting */
10083
10084 /* paranoia: invalidate the magic */
10085 pContext->magic = 0;
10086
10087 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -070010088 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -080010089
10090 /* serialization is complete */
10091 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010092}
10093
Katya Nigamf0511f62015-05-05 16:40:57 +053010094void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
10095{
10096 pMonCtx->typeSubtypeBitmap = 0;
10097 if( type%10 ) /* Management Packets */
10098 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
10099 type/=10;
10100 if( type%10 ) /* Control Packets */
10101 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
10102 type/=10;
10103 if( type%10 ) /* Data Packets */
10104 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
10105}
10106
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010107VOS_STATUS wlan_hdd_mon_postMsg(tANI_U32 *magic, struct completion *cmpVar,
10108 hdd_mon_ctx_t *pMonCtx , void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +053010109{
10110 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010111 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053010112
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010113 if (MON_MODE_START == pMonCtx->state)
10114 monMsg.type = WDA_MON_START_REQ;
10115 else if (MON_MODE_STOP == pMonCtx->state)
10116 monMsg.type = WDA_MON_STOP_REQ;
10117 else {
10118 hddLog(VOS_TRACE_LEVEL_ERROR,
10119 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +053010120 return VOS_STATUS_E_FAILURE;
10121 }
10122
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010123 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
10124 if (pMonModeReq == NULL) {
10125 hddLog(VOS_TRACE_LEVEL_ERROR,
10126 FL("fail to allocate memory for monitor mode req"));
10127 return VOS_STATUS_E_FAILURE;
10128 }
Katya Nigamf0511f62015-05-05 16:40:57 +053010129
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010130 pMonModeReq->magic = magic;
10131 pMonModeReq->cmpVar = cmpVar;
10132 pMonModeReq->data = pMonCtx;
10133 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +053010134
Katya Nigamf0511f62015-05-05 16:40:57 +053010135 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010136 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053010137 monMsg.bodyval = 0;
10138
10139 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
10140 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
10141 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010142 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +053010143 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010144 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +053010145}
10146
Katya Nigame7b69a82015-04-28 15:24:06 +053010147void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
10148{
10149 VOS_STATUS vosStatus;
10150 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010151 long ret;
10152 hdd_mon_ctx_t *pMonCtx = NULL;
10153 v_U32_t magic;
10154 struct completion cmpVar;
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053010155
Katya Nigame7b69a82015-04-28 15:24:06 +053010156 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
10157 if(pAdapter == NULL || pVosContext == NULL)
10158 {
10159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
10160 return ;
10161 }
Katya Nigamf0511f62015-05-05 16:40:57 +053010162
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010163 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
10164 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
10165 pMonCtx->state = MON_MODE_STOP;
10166 magic = MON_MODE_MSG_MAGIC;
10167 init_completion(&cmpVar);
10168 if (VOS_STATUS_SUCCESS !=
10169 wlan_hdd_mon_postMsg(&magic, &cmpVar,
10170 pMonCtx, hdd_monPostMsgCb)) {
10171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10172 FL("failed to post MON MODE REQ"));
10173 pMonCtx->state = MON_MODE_START;
10174 magic = 0;
10175 return;
10176 }
10177 ret = wait_for_completion_timeout(&cmpVar, MON_MODE_MSG_TIMEOUT);
10178 magic = 0;
10179 if (ret <= 0 ) {
10180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10181 FL("timeout on monitor mode completion %ld"), ret);
10182 }
10183 }
10184
Katya Nigame7b69a82015-04-28 15:24:06 +053010185 hdd_UnregisterWext(pAdapter->dev);
10186
10187 vos_mon_stop( pVosContext );
10188
10189 vosStatus = vos_sched_close( pVosContext );
10190 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
10191 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10192 "%s: Failed to close VOSS Scheduler",__func__);
10193 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10194 }
10195
10196 vosStatus = vos_nv_close();
10197 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10198 {
10199 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10200 "%s: Failed to close NV", __func__);
10201 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10202 }
10203
10204 vos_close(pVosContext);
10205
10206 #ifdef WLAN_KD_READY_NOTIFIER
10207 nl_srv_exit(pHddCtx->ptt_pid);
10208 #else
10209 nl_srv_exit();
10210 #endif
10211
Katya Nigame7b69a82015-04-28 15:24:06 +053010212 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +053010213}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053010214/**
10215 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
10216 * @ wiphy: the wiphy to validate against
10217 *
10218 * Return: void
10219 */
10220void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
10221{
10222 int i =0;
10223 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
10224 {
10225 if (NULL != wiphy->bands[i] &&
10226 (NULL != wiphy->bands[i]->channels))
10227 {
10228 vos_mem_free(wiphy->bands[i]->channels);
10229 wiphy->bands[i]->channels = NULL;
10230 }
10231 }
10232}
Jeff Johnson295189b2012-06-20 16:38:30 -070010233/**---------------------------------------------------------------------------
10234
10235 \brief hdd_wlan_exit() - HDD WLAN exit function
10236
10237 This is the driver exit point (invoked during rmmod)
10238
10239 \param - pHddCtx - Pointer to the HDD Context
10240
10241 \return - None
10242
10243 --------------------------------------------------------------------------*/
10244void hdd_wlan_exit(hdd_context_t *pHddCtx)
10245{
10246 eHalStatus halStatus;
10247 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
10248 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +053010249 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080010250 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -080010251 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010252 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +053010253 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010254
10255 ENTER();
10256
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010257
Katya Nigame7b69a82015-04-28 15:24:06 +053010258 if (VOS_MONITOR_MODE == hdd_get_conparam())
10259 {
10260 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
10261 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053010262 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +053010263 }
10264 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -080010265 {
10266 // Unloading, restart logic is no more required.
10267 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -070010268
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053010269#ifdef FEATURE_WLAN_TDLS
10270 /* At the time of driver unloading; if tdls connection is present;
10271 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
10272 * wlan_hdd_tdls_find_peer always checks for valid context;
10273 * as load/unload in progress there can be a race condition.
10274 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
10275 * when tdls state is enabled.
10276 * As soon as driver set load/unload flag; tdls flag also needs
10277 * to be disabled so that hdd_rx_packet_cbk won't call
10278 * wlan_hdd_tdls_find_peer.
10279 */
Masti, Narayanraddi20494af2015-12-17 20:56:42 +053010280 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE,
10281 HDD_SET_TDLS_MODE_SOURCE_USER);
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053010282#endif
10283
c_hpothu5ab05e92014-06-13 17:34:05 +053010284 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10285 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -070010286 {
c_hpothu5ab05e92014-06-13 17:34:05 +053010287 pAdapter = pAdapterNode->pAdapter;
10288 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070010289 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053010290 /* Disable TX on the interface, after this hard_start_xmit() will
10291 * not be called on that interface
10292 */
10293 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10294 netif_tx_disable(pAdapter->dev);
10295
10296 /* Mark the interface status as "down" for outside world */
10297 netif_carrier_off(pAdapter->dev);
10298
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053010299 /* DeInit the adapter. This ensures that all data packets
10300 * are freed.
10301 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053010302#ifdef FEATURE_WLAN_TDLS
10303 mutex_lock(&pHddCtx->tdls_lock);
10304#endif
c_hpothu002231a2015-02-05 14:58:51 +053010305 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053010306#ifdef FEATURE_WLAN_TDLS
10307 mutex_unlock(&pHddCtx->tdls_lock);
10308#endif
Masti, Narayanraddi26378462016-01-05 18:20:28 +053010309 vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work);
10310
10311 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053010312
c_hpothu5ab05e92014-06-13 17:34:05 +053010313 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10314 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
10315 {
10316 wlan_hdd_cfg80211_deregister_frames(pAdapter);
10317 hdd_UnregisterWext(pAdapter->dev);
10318 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010319
Jeff Johnson295189b2012-06-20 16:38:30 -070010320 }
c_hpothu5ab05e92014-06-13 17:34:05 +053010321 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10322 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010323 }
mukul sharmabab477d2015-06-11 17:14:55 +053010324
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010325 // Cancel any outstanding scan requests. We are about to close all
10326 // of our adapters, but an adapter structure is what SME passes back
10327 // to our callback function. Hence if there are any outstanding scan
10328 // requests then there is a race condition between when the adapter
10329 // is closed and when the callback is invoked.We try to resolve that
10330 // race condition here by canceling any outstanding scans before we
10331 // close the adapters.
10332 // Note that the scans may be cancelled in an asynchronous manner,
10333 // so ideally there needs to be some kind of synchronization. Rather
10334 // than introduce a new synchronization here, we will utilize the
10335 // fact that we are about to Request Full Power, and since that is
10336 // synchronized, the expectation is that by the time Request Full
10337 // Power has completed all scans will be cancelled.
10338 if (pHddCtx->scan_info.mScanPending)
10339 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +053010340 if(NULL != pAdapter)
10341 {
10342 hddLog(VOS_TRACE_LEVEL_INFO,
10343 FL("abort scan mode: %d sessionId: %d"),
10344 pAdapter->device_mode,
10345 pAdapter->sessionId);
10346 }
10347 hdd_abort_mac_scan(pHddCtx,
10348 pHddCtx->scan_info.sessionId,
10349 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010350 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010351 }
c_hpothu5ab05e92014-06-13 17:34:05 +053010352 else
Jeff Johnson88ba7742013-02-27 14:36:02 -080010353 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010354 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +053010355 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
10356 {
10357 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
10358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10359 "%s: in middle of FTM START", __func__);
10360 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
10361 msecs_to_jiffies(20000));
10362 if(!lrc)
10363 {
10364 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10365 "%s: timedout on ftmStartCmpVar fatal error", __func__);
10366 }
10367 }
Jeff Johnson88ba7742013-02-27 14:36:02 -080010368 wlan_hdd_ftm_close(pHddCtx);
10369 goto free_hdd_ctx;
10370 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010371
Jeff Johnson295189b2012-06-20 16:38:30 -070010372 /* DeRegister with platform driver as client for Suspend/Resume */
10373 vosStatus = hddDeregisterPmOps(pHddCtx);
10374 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
10375 {
10376 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
10377 VOS_ASSERT(0);
10378 }
10379
10380 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
10381 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
10382 {
10383 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
10384 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010385
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010386 //Stop the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053010387 if ((pHddCtx->cfg_ini->dynSplitscan) && (VOS_TIMER_STATE_RUNNING ==
10388 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010389 {
10390 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
10391 }
10392
10393 // Destroy the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053010394 if ((pHddCtx->cfg_ini->dynSplitscan) &&
10395 (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
10396 &pHddCtx->tx_rx_trafficTmr))))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010397 {
10398 hddLog(VOS_TRACE_LEVEL_ERROR,
10399 "%s: Cannot deallocate Traffic monitor timer", __func__);
10400 }
10401
Bhargav Shahd0715912015-10-01 18:17:37 +053010402 if (VOS_TIMER_STATE_RUNNING ==
10403 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
10404 vos_timer_stop(&pHddCtx->delack_timer);
10405 }
10406
10407 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
10408 &pHddCtx->delack_timer))) {
10409 hddLog(VOS_TRACE_LEVEL_ERROR,
10410 "%s: Cannot deallocate Bus bandwidth timer", __func__);
10411 }
10412
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053010413 if (VOS_TIMER_STATE_RUNNING ==
10414 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) {
10415 vos_timer_stop(&pHddCtx->tdls_source_timer);
10416 }
10417
10418 vos_timer_destroy(&pHddCtx->tdls_source_timer);
10419
Jeff Johnson295189b2012-06-20 16:38:30 -070010420 //Disable IMPS/BMPS as we do not want the device to enter any power
10421 //save mode during shutdown
10422 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
10423 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
10424 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
10425
10426 //Ensure that device is in full power as we will touch H/W during vos_Stop
10427 init_completion(&powerContext.completion);
10428 powerContext.magic = POWER_CONTEXT_MAGIC;
10429
10430 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
10431 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
10432
10433 if (eHAL_STATUS_SUCCESS != halStatus)
10434 {
10435 if (eHAL_STATUS_PMC_PENDING == halStatus)
10436 {
10437 /* request was sent -- wait for the response */
10438 lrc = wait_for_completion_interruptible_timeout(
10439 &powerContext.completion,
10440 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -070010441 if (lrc <= 0)
10442 {
10443 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010444 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -070010445 }
10446 }
10447 else
10448 {
10449 hddLog(VOS_TRACE_LEVEL_ERROR,
10450 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010451 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -070010452 /* continue -- need to clean up as much as possible */
10453 }
10454 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +053010455 if ((eHAL_STATUS_SUCCESS == halStatus) ||
10456 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
10457 {
10458 /* This will issue a dump command which will clean up
10459 BTQM queues and unblock MC thread */
10460 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
10461 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010462
Jeff Johnson72a40512013-12-19 10:14:15 -080010463 /* either we never sent a request, we sent a request and received a
10464 response or we sent a request and timed out. if we never sent a
10465 request or if we sent a request and got a response, we want to
10466 clear the magic out of paranoia. if we timed out there is a
10467 race condition such that the callback function could be
10468 executing at the same time we are. of primary concern is if the
10469 callback function had already verified the "magic" but had not
10470 yet set the completion variable when a timeout occurred. we
10471 serialize these activities by invalidating the magic while
10472 holding a shared spinlock which will cause us to block if the
10473 callback is currently executing */
10474 spin_lock(&hdd_context_lock);
10475 powerContext.magic = 0;
10476 spin_unlock(&hdd_context_lock);
10477
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +053010478 /* If Device is shutdown, no point for SME to wait for responses
10479 from device. Pre Close SME */
10480 if(wcnss_device_is_shutdown())
10481 {
10482 sme_PreClose(pHddCtx->hHal);
10483 }
Yue Ma0d4891e2013-08-06 17:01:45 -070010484 hdd_debugfs_exit(pHddCtx);
10485
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010486#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +053010487 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010488 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10489#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +053010490 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010491 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10492
Jeff Johnson295189b2012-06-20 16:38:30 -070010493 // Unregister the Net Device Notifier
10494 unregister_netdevice_notifier(&hdd_netdev_notifier);
10495
Jeff Johnson295189b2012-06-20 16:38:30 -070010496 hdd_stop_all_adapters( pHddCtx );
10497
Jeff Johnson295189b2012-06-20 16:38:30 -070010498#ifdef WLAN_BTAMP_FEATURE
10499 vosStatus = WLANBAP_Stop(pVosContext);
10500 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10501 {
10502 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10503 "%s: Failed to stop BAP",__func__);
10504 }
10505#endif //WLAN_BTAMP_FEATURE
10506
10507 //Stop all the modules
10508 vosStatus = vos_stop( pVosContext );
10509 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10510 {
10511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10512 "%s: Failed to stop VOSS",__func__);
10513 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053010514 if (isSsrPanicOnFailure())
10515 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070010516 }
10517
Jeff Johnson295189b2012-06-20 16:38:30 -070010518 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -070010519 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010520
10521 //Close the scheduler before calling vos_close to make sure no thread is
10522 // scheduled after the each module close is called i.e after all the data
10523 // structures are freed.
10524 vosStatus = vos_sched_close( pVosContext );
10525 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
10526 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10527 "%s: Failed to close VOSS Scheduler",__func__);
10528 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10529 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010530#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10531 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010532 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070010533#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010534 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010535 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010536
Mihir Shete7a24b5f2013-12-21 12:18:31 +053010537#ifdef CONFIG_ENABLE_LINUX_REG
10538 vosStatus = vos_nv_close();
10539 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10540 {
10541 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10542 "%s: Failed to close NV", __func__);
10543 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10544 }
10545#endif
10546
Jeff Johnson295189b2012-06-20 16:38:30 -070010547 //Close VOSS
10548 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
10549 vos_close(pVosContext);
10550
Jeff Johnson295189b2012-06-20 16:38:30 -070010551 //Close Watchdog
10552 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10553 vos_watchdog_close(pVosContext);
10554
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053010555 //Clean up HDD Nlink Service
10556 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053010557
Manjeet Singh47ee8472016-04-11 11:57:18 +053010558 hdd_close_tx_queues(pHddCtx);
c_manjeecfd1efb2015-09-25 19:32:34 +053010559 wlan_free_fwr_mem_dump_buffer();
10560 memdump_deinit();
10561
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010562#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010563 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010564 {
10565 wlan_logging_sock_deactivate_svc();
10566 }
10567#endif
10568
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053010569#ifdef WLAN_KD_READY_NOTIFIER
10570 nl_srv_exit(pHddCtx->ptt_pid);
10571#else
10572 nl_srv_exit();
10573#endif /* WLAN_KD_READY_NOTIFIER */
10574
Abhishek Singh00b71972016-01-07 10:51:04 +053010575#ifdef WLAN_FEATURE_RMC
10576 hdd_close_cesium_nl_sock();
10577#endif /* WLAN_FEATURE_RMC */
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053010578
Jeff Johnson295189b2012-06-20 16:38:30 -070010579 hdd_close_all_adapters( pHddCtx );
10580
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053010581 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
10582
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +053010583free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -070010584 /* free the power on lock from platform driver */
10585 if (free_riva_power_on_lock("wlan"))
10586 {
10587 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
10588 __func__);
10589 }
10590
c_hpothu78c7b602014-05-17 17:35:49 +053010591 //Free up dynamically allocated members inside HDD Adapter
10592 if (pHddCtx->cfg_ini)
10593 {
10594 kfree(pHddCtx->cfg_ini);
10595 pHddCtx->cfg_ini= NULL;
10596 }
10597
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053010598 /* FTM/MONITOR mode, WIPHY did not registered
Leo Changf04ddad2013-09-18 13:46:38 -070010599 If un-register here, system crash will happen */
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053010600 if (!(VOS_FTM_MODE == hdd_get_conparam() ||
10601 VOS_MONITOR_MODE == hdd_get_conparam()))
Leo Changf04ddad2013-09-18 13:46:38 -070010602 {
10603 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053010604 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -070010605 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010606 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010607 if (hdd_is_ssr_required())
10608 {
10609 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -070010610 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -070010611 msleep(5000);
10612 }
10613 hdd_set_ssr_required (VOS_FALSE);
10614}
10615
10616
10617/**---------------------------------------------------------------------------
10618
10619 \brief hdd_update_config_from_nv() - Function to update the contents of
10620 the running configuration with parameters taken from NV storage
10621
10622 \param - pHddCtx - Pointer to the HDD global context
10623
10624 \return - VOS_STATUS_SUCCESS if successful
10625
10626 --------------------------------------------------------------------------*/
10627static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
10628{
Jeff Johnson295189b2012-06-20 16:38:30 -070010629 v_BOOL_t itemIsValid = VOS_FALSE;
10630 VOS_STATUS status;
10631 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
10632 v_U8_t macLoop;
10633
10634 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
10635 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
10636 if(status != VOS_STATUS_SUCCESS)
10637 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010638 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070010639 return VOS_STATUS_E_FAILURE;
10640 }
10641
10642 if (itemIsValid == VOS_TRUE)
10643 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010644 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -070010645 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
10646 VOS_MAX_CONCURRENCY_PERSONA);
10647 if(status != VOS_STATUS_SUCCESS)
10648 {
10649 /* Get MAC from NV fail, not update CFG info
10650 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -080010651 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070010652 return VOS_STATUS_E_FAILURE;
10653 }
10654
10655 /* If first MAC is not valid, treat all others are not valid
10656 * Then all MACs will be got from ini file */
10657 if(vos_is_macaddr_zero(&macFromNV[0]))
10658 {
10659 /* MAC address in NV file is not configured yet */
10660 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
10661 return VOS_STATUS_E_INVAL;
10662 }
10663
10664 /* Get MAC address from NV, update CFG info */
10665 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
10666 {
10667 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
10668 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010669 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -070010670 /* This MAC is not valid, skip it
10671 * This MAC will be got from ini file */
10672 }
10673 else
10674 {
10675 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
10676 (v_U8_t *)&macFromNV[macLoop].bytes[0],
10677 VOS_MAC_ADDR_SIZE);
10678 }
10679 }
10680 }
10681 else
10682 {
10683 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
10684 return VOS_STATUS_E_FAILURE;
10685 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010686
Jeff Johnson295189b2012-06-20 16:38:30 -070010687
10688 return VOS_STATUS_SUCCESS;
10689}
10690
10691/**---------------------------------------------------------------------------
10692
10693 \brief hdd_post_voss_start_config() - HDD post voss start config helper
10694
10695 \param - pAdapter - Pointer to the HDD
10696
10697 \return - None
10698
10699 --------------------------------------------------------------------------*/
10700VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
10701{
10702 eHalStatus halStatus;
10703 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010704 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -070010705
Jeff Johnson295189b2012-06-20 16:38:30 -070010706
10707 // Send ready indication to the HDD. This will kick off the MAC
10708 // into a 'running' state and should kick off an initial scan.
10709 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
10710 if ( !HAL_STATUS_SUCCESS( halStatus ) )
10711 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010712 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -070010713 "code %08d [x%08x]",__func__, halStatus, halStatus );
10714 return VOS_STATUS_E_FAILURE;
10715 }
10716
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010717 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -070010718 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
10719 // And RIVA will crash
10720 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
10721 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010722 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
10723 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
10724
10725
Jeff Johnson295189b2012-06-20 16:38:30 -070010726 return VOS_STATUS_SUCCESS;
10727}
10728
Jeff Johnson295189b2012-06-20 16:38:30 -070010729/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010730void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070010731{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010732
10733 vos_wake_lock_acquire(&wlan_wake_lock, reason);
10734
Jeff Johnson295189b2012-06-20 16:38:30 -070010735}
10736
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010737void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070010738{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010739
10740 vos_wake_lock_release(&wlan_wake_lock, reason);
10741
Jeff Johnson295189b2012-06-20 16:38:30 -070010742}
10743
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010744void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010745{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010746
10747 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
10748 reason);
10749
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010750}
10751
Jeff Johnson295189b2012-06-20 16:38:30 -070010752/**---------------------------------------------------------------------------
10753
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010754 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
10755 information between Host and Riva
10756
10757 This function gets reported version of FW
10758 It also finds the version of Riva headers used to compile the host
10759 It compares the above two and prints a warning if they are different
10760 It gets the SW and HW version string
10761 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
10762 indicating the features they support through a bitmap
10763
10764 \param - pHddCtx - Pointer to HDD context
10765
10766 \return - void
10767
10768 --------------------------------------------------------------------------*/
10769
10770void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
10771{
10772
10773 tSirVersionType versionCompiled;
10774 tSirVersionType versionReported;
10775 tSirVersionString versionString;
10776 tANI_U8 fwFeatCapsMsgSupported = 0;
10777 VOS_STATUS vstatus;
10778
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080010779 memset(&versionCompiled, 0, sizeof(versionCompiled));
10780 memset(&versionReported, 0, sizeof(versionReported));
10781
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010782 /* retrieve and display WCNSS version information */
10783 do {
10784
10785 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
10786 &versionCompiled);
10787 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10788 {
10789 hddLog(VOS_TRACE_LEVEL_FATAL,
10790 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010791 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010792 break;
10793 }
10794
10795 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
10796 &versionReported);
10797 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10798 {
10799 hddLog(VOS_TRACE_LEVEL_FATAL,
10800 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010801 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010802 break;
10803 }
10804
10805 if ((versionCompiled.major != versionReported.major) ||
10806 (versionCompiled.minor != versionReported.minor) ||
10807 (versionCompiled.version != versionReported.version) ||
10808 (versionCompiled.revision != versionReported.revision))
10809 {
10810 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
10811 "Host expected %u.%u.%u.%u\n",
10812 WLAN_MODULE_NAME,
10813 (int)versionReported.major,
10814 (int)versionReported.minor,
10815 (int)versionReported.version,
10816 (int)versionReported.revision,
10817 (int)versionCompiled.major,
10818 (int)versionCompiled.minor,
10819 (int)versionCompiled.version,
10820 (int)versionCompiled.revision);
10821 }
10822 else
10823 {
10824 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
10825 WLAN_MODULE_NAME,
10826 (int)versionReported.major,
10827 (int)versionReported.minor,
10828 (int)versionReported.version,
10829 (int)versionReported.revision);
10830 }
10831
10832 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
10833 versionString,
10834 sizeof(versionString));
10835 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10836 {
10837 hddLog(VOS_TRACE_LEVEL_FATAL,
10838 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010839 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010840 break;
10841 }
10842
10843 pr_info("%s: WCNSS software version %s\n",
10844 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +053010845 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010846
10847 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
10848 versionString,
10849 sizeof(versionString));
10850 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10851 {
10852 hddLog(VOS_TRACE_LEVEL_FATAL,
10853 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010854 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010855 break;
10856 }
10857
10858 pr_info("%s: WCNSS hardware version %s\n",
10859 WLAN_MODULE_NAME, versionString);
10860
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010861 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
10862 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010863 send the message only if it the riva is 1.1
10864 minor numbers for different riva branches:
10865 0 -> (1.0)Mainline Build
10866 1 -> (1.1)Mainline Build
10867 2->(1.04) Stability Build
10868 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010869 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010870 ((versionReported.minor>=1) && (versionReported.version>=1)))
10871 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
10872 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010873
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010874 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -080010875 {
10876#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
10877 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
10878 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
10879#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -070010880 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
10881 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
10882 {
10883 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
10884 }
10885
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010886 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -080010887 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010888
10889 } while (0);
10890
10891}
Neelansh Mittaledafed22014-09-04 18:54:39 +053010892void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
10893{
10894 struct sk_buff *skb;
10895 struct nlmsghdr *nlh;
10896 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053010897 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +053010898 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +053010899
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053010900 if (in_interrupt() || irqs_disabled() || in_atomic())
10901 flags = GFP_ATOMIC;
10902
10903 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +053010904
10905 if(skb == NULL) {
10906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10907 "%s: alloc_skb failed", __func__);
10908 return;
10909 }
10910
10911 nlh = (struct nlmsghdr *)skb->data;
10912 nlh->nlmsg_pid = 0; /* from kernel */
10913 nlh->nlmsg_flags = 0;
10914 nlh->nlmsg_seq = 0;
10915 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
10916
10917 ani_hdr = NLMSG_DATA(nlh);
10918 ani_hdr->type = type;
10919
10920 switch(type) {
10921 case WLAN_SVC_SAP_RESTART_IND:
10922 ani_hdr->length = 0;
10923 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
10924 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
10925 break;
Bhargav Shahd0715912015-10-01 18:17:37 +053010926 case WLAN_SVC_WLAN_TP_IND:
10927 ani_hdr->length = len;
10928 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
10929 + len));
10930 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
10931 memcpy(nl_data, data, len);
10932 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
10933 break;
Bhargav shah23c94942015-10-13 12:48:35 +053010934 case WLAN_MSG_RPS_ENABLE_IND:
10935 ani_hdr->length = len;
10936 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
10937 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
10938 memcpy(nl_data, data, len);
10939 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
10940 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +053010941 default:
10942 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10943 "Attempt to send unknown nlink message %d", type);
10944 kfree_skb(skb);
10945 return;
10946 }
10947
10948 nl_srv_bcast(skb);
10949
10950 return;
10951}
10952
Bhargav Shahd0715912015-10-01 18:17:37 +053010953/**
10954 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
10955 * @pHddCtx: Valid Global HDD context pointer
10956 * @rx_packets: Number of RX packet in perticular time
10957 *
10958 * Based on the RX packet this function calculate next value of tcp delack.
10959 * This function compare rx packet value to high and low threshold limit.
10960 *
10961 * Return: void
10962 */
10963void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
10964{
10965 /* average of rx_packets and prev_rx is taken so that
10966 bus width doesnot fluctuate much */
10967 uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
10968 TP_IND_TYPE next_rx_level = pHddCtx->cur_rx_level;
Neelansh Mittaledafed22014-09-04 18:54:39 +053010969
Bhargav Shahd0715912015-10-01 18:17:37 +053010970 pHddCtx->prev_rx = rx_packets;
10971 if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
10972 next_rx_level = TP_IND_HIGH;
10973 else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
10974 next_rx_level = TP_IND_LOW;
10975
10976 hdd_set_delack_value(pHddCtx, next_rx_level);
10977}
10978
10979#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))
10980
10981/**
10982 * hdd_tcp_delack_compute_function() - get link status
10983 * @priv: Valid Global HDD context pointer
10984 *
10985 * This function find number of RX packet during timer life span.
10986 * It request tcp delack with number of RX packet and re-configure delack timer
10987 * for tcpDelAckComputeInterval timer interval.
10988 *
10989 * Return: void
10990 */
10991void hdd_tcp_delack_compute_function(void *priv)
10992{
10993 hdd_context_t *pHddCtx = (hdd_context_t *)priv;
10994 hdd_adapter_t *pAdapter = NULL;
10995 v_U32_t rx_packets = 0;
10996 hdd_adapter_list_node_t *pAdapterNode = NULL;
10997 VOS_STATUS status = 0;
10998
10999 for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
11000 NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
11001 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
11002 if ((pAdapter = pAdapterNode->pAdapter) == NULL)
11003 continue;
11004
11005 rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
11006 pAdapter->prev_rx_packets);
11007 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
11008 }
11009
11010 hdd_request_tcp_delack(pHddCtx, rx_packets);
11011
11012 vos_timer_start(&pHddCtx->delack_timer,
11013 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
11014}
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011015
11016/**---------------------------------------------------------------------------
11017
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011018 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
11019
11020 \param - pHddCtx - Pointer to the hdd context
11021
11022 \return - true if hardware supports 5GHz
11023
11024 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +053011025boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011026{
11027 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
11028 * then hardware support 5Ghz.
11029 */
11030 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
11031 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053011032 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011033 return true;
11034 }
11035 else
11036 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053011037 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011038 __func__);
11039 return false;
11040 }
11041}
11042
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011043/**---------------------------------------------------------------------------
11044
11045 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
11046 generate function
11047
11048 This is generate the random mac address for WLAN interface
11049
11050 \param - pHddCtx - Pointer to HDD context
11051 idx - Start interface index to get auto
11052 generated mac addr.
11053 mac_addr - Mac address
11054
11055 \return - 0 for success, < 0 for failure
11056
11057 --------------------------------------------------------------------------*/
11058
11059static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
11060 int idx, v_MACADDR_t mac_addr)
11061{
11062 int i;
11063 unsigned int serialno;
11064 serialno = wcnss_get_serial_number();
11065
11066 if (0 != serialno)
11067 {
11068 /* MAC address has 3 bytes of OUI so we have a maximum of 3
11069 bytes of the serial number that can be used to generate
11070 the other 3 bytes of the MAC address. Mask off all but
11071 the lower 3 bytes (this will also make sure we don't
11072 overflow in the next step) */
11073 serialno &= 0x00FFFFFF;
11074
11075 /* we need a unique address for each session */
11076 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
11077
11078 /* autogen other Mac addresses */
11079 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
11080 {
11081 /* start with the entire default address */
11082 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
11083 /* then replace the lower 3 bytes */
11084 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
11085 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
11086 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
11087
11088 serialno++;
11089 hddLog(VOS_TRACE_LEVEL_ERROR,
11090 "%s: Derived Mac Addr: "
11091 MAC_ADDRESS_STR, __func__,
11092 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
11093 }
11094
11095 }
11096 else
11097 {
11098 hddLog(LOGE, FL("Failed to Get Serial NO"));
11099 return -1;
11100 }
11101 return 0;
11102}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011103
Katya Nigame7b69a82015-04-28 15:24:06 +053011104int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
11105{
11106 VOS_STATUS status;
11107 v_CONTEXT_t pVosContext= NULL;
11108 hdd_adapter_t *pAdapter= NULL;
11109
11110 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11111
11112 if (NULL == pVosContext)
11113 {
11114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11115 "%s: Trying to open VOSS without a PreOpen", __func__);
11116 VOS_ASSERT(0);
11117 return VOS_STATUS_E_FAILURE;
11118 }
11119
11120 status = vos_nv_open();
11121 if (!VOS_IS_STATUS_SUCCESS(status))
11122 {
11123 /* NV module cannot be initialized */
11124 hddLog( VOS_TRACE_LEVEL_FATAL,
11125 "%s: vos_nv_open failed", __func__);
11126 return VOS_STATUS_E_FAILURE;
11127 }
11128
11129 status = vos_init_wiphy_from_nv_bin();
11130 if (!VOS_IS_STATUS_SUCCESS(status))
11131 {
11132 /* NV module cannot be initialized */
11133 hddLog( VOS_TRACE_LEVEL_FATAL,
11134 "%s: vos_init_wiphy failed", __func__);
11135 goto err_vos_nv_close;
11136 }
11137
11138 status = vos_open( &pVosContext, pHddCtx->parent_dev);
11139 if ( !VOS_IS_STATUS_SUCCESS( status ))
11140 {
11141 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
11142 goto err_vos_nv_close;
11143 }
11144
11145 status = vos_mon_start( pVosContext );
11146 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11147 {
11148 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
11149 goto err_vosclose;
11150 }
11151
11152 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
11153 WDA_featureCapsExchange(pVosContext);
11154 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
11155
11156 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
11157 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
11158 if( pAdapter == NULL )
11159 {
11160 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
11161 goto err_close_adapter;
11162 }
11163
11164 //Initialize the nlink service
11165 if(nl_srv_init() != 0)
11166 {
11167 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
11168 goto err_close_adapter;
11169 }
11170 return VOS_STATUS_SUCCESS;
11171
11172err_close_adapter:
11173 hdd_close_all_adapters( pHddCtx );
11174 vos_mon_stop( pVosContext );
11175err_vosclose:
11176 status = vos_sched_close( pVosContext );
11177 if (!VOS_IS_STATUS_SUCCESS(status)) {
11178 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
11179 "%s: Failed to close VOSS Scheduler", __func__);
11180 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
11181 }
11182 vos_close(pVosContext );
11183
11184err_vos_nv_close:
11185 vos_nv_close();
11186
11187return status;
11188}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011189/**---------------------------------------------------------------------------
11190
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011191 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
11192 completed to flush out the scan results
11193
11194 11d scan is done during driver load and is a passive scan on all
11195 channels supported by the device, 11d scans may find some APs on
11196 frequencies which are forbidden to be used in the regulatory domain
11197 the device is operating in. If these APs are notified to the supplicant
11198 it may try to connect to these APs, thus flush out all the scan results
11199 which are present in SME after 11d scan is done.
11200
11201 \return - eHalStatus
11202
11203 --------------------------------------------------------------------------*/
11204static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
11205 tANI_U32 scanId, eCsrScanStatus status)
11206{
11207 ENTER();
11208
11209 sme_ScanFlushResult(halHandle, 0);
11210
11211 EXIT();
11212
11213 return eHAL_STATUS_SUCCESS;
11214}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011215/**---------------------------------------------------------------------------
11216
11217 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
11218 logging is completed successfully.
11219
11220 \return - None
11221
11222 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +053011223void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011224{
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011225 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011226
11227 if (NULL == pHddCtx)
11228 {
11229 hddLog(VOS_TRACE_LEVEL_ERROR,
11230 "%s: HDD context is NULL",__func__);
11231 return;
11232 }
11233
c_manjeecfd1efb2015-09-25 19:32:34 +053011234 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +053011235 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011236 {
11237 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
11238 pHddCtx->mgmt_frame_logging = TRUE;
11239 }
11240 else
11241 {
11242 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
11243 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +053011244 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011245 }
11246
c_manjeecfd1efb2015-09-25 19:32:34 +053011247 /*Check feature supported by FW*/
11248 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
11249 {
11250 //Store fwr mem dump size given by firmware.
11251 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
11252 }
11253 else
11254 {
11255 wlan_store_fwr_mem_dump_size(0);
11256 }
11257
11258
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011259}
11260/**---------------------------------------------------------------------------
11261
11262 \brief hdd_init_frame_logging - function to initialize frame logging.
11263 Currently only Mgmt Frames are logged in both TX
11264 and Rx direction and are sent to userspace
11265 application using logger thread when queried.
11266
11267 \return - None
11268
11269 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011270void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011271{
11272 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011273 tSirFWLoggingInitParam wlanFWLoggingInitParam = {0};
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011274
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011275 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
11276 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011277 {
11278 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
11279 return;
11280 }
11281
c_manjeecfd1efb2015-09-25 19:32:34 +053011282 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011283 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
11284 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +053011285 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
11286 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011287
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011288 if (pHddCtx->cfg_ini->enableFWLogging ||
11289 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011290 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011291 wlanFWLoggingInitParam.enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011292 }
11293
Sushant Kaushik46804902015-07-08 14:46:03 +053011294 if (pHddCtx->cfg_ini->enableMgmtLogging)
11295 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011296 wlanFWLoggingInitParam.enableFlag |= WLAN_FRAME_LOG_EN;
Sushant Kaushik46804902015-07-08 14:46:03 +053011297 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011298 if (pHddCtx->cfg_ini->enableBMUHWtracing)
11299 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011300 wlanFWLoggingInitParam.enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011301 }
c_manjeecfd1efb2015-09-25 19:32:34 +053011302 if(pHddCtx->cfg_ini->enableFwrMemDump &&
11303 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
11304 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011305 wlanFWLoggingInitParam.enableFlag |= WLAN_FW_MEM_DUMP_EN;
c_manjeecfd1efb2015-09-25 19:32:34 +053011306 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011307 if( wlanFWLoggingInitParam.enableFlag == 0 )
c_manjeecfd1efb2015-09-25 19:32:34 +053011308 {
11309 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
11310 return;
11311 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011312 wlanFWLoggingInitParam.frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
11313 wlanFWLoggingInitParam.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
11314 wlanFWLoggingInitParam.bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
11315 wlanFWLoggingInitParam.continuousFrameLogging =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011316 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011317
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011318 wlanFWLoggingInitParam.enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011319
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011320 wlanFWLoggingInitParam.minLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011321 pHddCtx->cfg_ini->minLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011322 wlanFWLoggingInitParam.maxLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011323 pHddCtx->cfg_ini->maxLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011324 wlanFWLoggingInitParam.fwlogInitCallback = hdd_init_frame_logging_done;
11325 wlanFWLoggingInitParam.fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011326
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011327 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, &wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011328
11329 if (eHAL_STATUS_SUCCESS != halStatus)
11330 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011331 hddLog(LOGE, FL("sme_InitMgmtFrameLogging failed, returned %d"),
11332 halStatus);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011333 }
11334
11335 return;
11336}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011337
Bhargav shah23c94942015-10-13 12:48:35 +053011338static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
11339{
11340 hdd_adapter_t *adapter;
11341 hdd_adapter_list_node_t *adapter_node, *next;
11342 VOS_STATUS status = VOS_STATUS_SUCCESS;
11343 struct wlan_rps_data rps_data;
11344 int count;
11345
11346 if(!hdd_ctxt->cfg_ini->rps_mask)
11347 {
11348 return;
11349 }
11350
11351 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
11352 {
11353 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
11354 }
11355
11356 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
11357
11358 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
11359 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
11360 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
11361
11362 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
11363
11364 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
11365 {
11366 adapter = adapter_node->pAdapter;
11367 if (NULL != adapter) {
11368 strlcpy(rps_data.ifname, adapter->dev->name,
11369 sizeof(rps_data.ifname));
11370 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
11371 (void *)&rps_data,sizeof(rps_data));
11372 }
11373 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
11374 adapter_node = next;
11375 }
11376}
11377
Masti, Narayanraddi26378462016-01-05 18:20:28 +053011378void wlan_hdd_schedule_defer_scan(struct work_struct *work)
11379{
11380 scan_context_t *scan_ctx =
11381 container_of(work, scan_context_t, scan_work.work);
11382
11383 if (NULL == scan_ctx)
11384 {
11385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11386 FL("scan_ctx is NULL"));
11387 return;
11388 }
11389
11390 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
11391 return;
11392
11393 scan_ctx->attempt++;
11394
11395 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
11396#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11397 scan_ctx->dev,
11398#endif
11399 scan_ctx->scan_request);
11400}
11401
11402int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx,
11403 struct wiphy *wiphy,
11404#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11405 struct net_device *dev,
11406#endif
11407 struct cfg80211_scan_request *request)
11408{
11409 scan_context_t *scan_ctx;
11410
11411 ENTER();
11412 if (0 != (wlan_hdd_validate_context(pHddCtx)))
11413 {
11414 return -1;
11415 }
11416
11417 scan_ctx = &pHddCtx->scan_ctxt;
11418
11419 scan_ctx->wiphy = wiphy;
11420#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11421 scan_ctx->dev = dev;
11422#endif
11423
11424 scan_ctx->scan_request = request;
11425
11426 EXIT();
11427 return 0;
11428}
11429
11430void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
11431 struct wiphy *wiphy,
11432#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11433 struct net_device *dev,
11434#endif
11435 struct cfg80211_scan_request *request,
11436 unsigned long delay)
11437{
11438 if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic)
11439 {
11440#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11441 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request);
11442#else
11443 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request);
11444#endif
11445 pHddCtx->scan_ctxt.attempt = 0;
11446 pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC;
11447 }
11448 schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay);
11449}
11450
11451void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx)
11452{
11453 scan_ctx->magic = 0;
11454 scan_ctx->attempt = 0;
11455 scan_ctx->reject = 0;
11456 scan_ctx->scan_request = NULL;
11457
11458 return;
11459}
11460
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011461/**---------------------------------------------------------------------------
11462
Jeff Johnson295189b2012-06-20 16:38:30 -070011463 \brief hdd_wlan_startup() - HDD init function
11464
11465 This is the driver startup code executed once a WLAN device has been detected
11466
11467 \param - dev - Pointer to the underlying device
11468
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011469 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -070011470
11471 --------------------------------------------------------------------------*/
11472
11473int hdd_wlan_startup(struct device *dev )
11474{
11475 VOS_STATUS status;
11476 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011477 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011478 hdd_context_t *pHddCtx = NULL;
11479 v_CONTEXT_t pVosContext= NULL;
11480#ifdef WLAN_BTAMP_FEATURE
11481 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
11482 WLANBAP_ConfigType btAmpConfig;
11483 hdd_config_t *pConfig;
11484#endif
11485 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011486 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011487 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -070011488
11489 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011490 /*
11491 * cfg80211: wiphy allocation
11492 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011493 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070011494
11495 if(wiphy == NULL)
11496 {
11497 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011498 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011499 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011500 pHddCtx = wiphy_priv(wiphy);
11501
Jeff Johnson295189b2012-06-20 16:38:30 -070011502 //Initialize the adapter context to zeros.
11503 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
11504
Jeff Johnson295189b2012-06-20 16:38:30 -070011505 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011506 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +053011507 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011508
11509 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
11510
Siddharth Bhalcd92b782015-06-29 12:25:40 +053011511 /* register for riva power on lock to platform driver
11512 * Locking power early to ensure FW doesn't reset by kernel while
11513 * host driver is busy initializing itself */
11514 if (req_riva_power_on_lock("wlan"))
11515 {
11516 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
11517 __func__);
11518 goto err_free_hdd_context;
11519 }
11520
Jeff Johnson295189b2012-06-20 16:38:30 -070011521 /*Get vos context here bcoz vos_open requires it*/
11522 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11523
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -080011524 if(pVosContext == NULL)
11525 {
11526 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
11527 goto err_free_hdd_context;
11528 }
11529
Jeff Johnson295189b2012-06-20 16:38:30 -070011530 //Save the Global VOSS context in adapter context for future.
11531 pHddCtx->pvosContext = pVosContext;
11532
11533 //Save the adapter context in global context for future.
11534 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
11535
Jeff Johnson295189b2012-06-20 16:38:30 -070011536 pHddCtx->parent_dev = dev;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053011537 pHddCtx->last_scan_reject_session_id = 0xFF;
11538 pHddCtx->last_scan_reject_reason = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053011539 pHddCtx->last_scan_reject_timestamp = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011540
11541 init_completion(&pHddCtx->full_pwr_comp_var);
11542 init_completion(&pHddCtx->standby_comp_var);
11543 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011544 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080011545 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +053011546 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053011547 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053011548 init_completion(&pHddCtx->mc_sus_event_var);
11549 init_completion(&pHddCtx->tx_sus_event_var);
11550 init_completion(&pHddCtx->rx_sus_event_var);
11551
Amar Singhala49cbc52013-10-08 18:37:44 -070011552
mukul sharma4bd8d2e2015-08-13 20:33:25 +053011553 hdd_init_ll_stats_ctx(pHddCtx);
11554
Amar Singhala49cbc52013-10-08 18:37:44 -070011555#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -070011556 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -070011557#else
11558 init_completion(&pHddCtx->driver_crda_req);
11559#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011560
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +053011561#ifdef WLAN_FEATURE_EXTSCAN
11562 init_completion(&pHddCtx->ext_scan_context.response_event);
11563#endif /* WLAN_FEATURE_EXTSCAN */
11564
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053011565 spin_lock_init(&pHddCtx->schedScan_lock);
11566
Jeff Johnson295189b2012-06-20 16:38:30 -070011567 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
11568
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053011569 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
11570 hdd_processSpoofMacAddrRequest);
11571
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011572#ifdef FEATURE_WLAN_TDLS
11573 /* tdls_lock is initialized before an hdd_open_adapter ( which is
11574 * invoked by other instances also) to protect the concurrent
11575 * access for the Adapters by TDLS module.
11576 */
11577 mutex_init(&pHddCtx->tdls_lock);
11578#endif
Siddharth Bhal76972212014-10-15 16:22:51 +053011579 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +053011580 mutex_init(&pHddCtx->wmmLock);
11581
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +053011582 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +053011583 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011584
Agarwal Ashish1f422872014-07-22 00:11:55 +053011585 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011586 // Load all config first as TL config is needed during vos_open
11587 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
11588 if(pHddCtx->cfg_ini == NULL)
11589 {
11590 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
11591 goto err_free_hdd_context;
11592 }
11593
11594 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
11595
11596 // Read and parse the qcom_cfg.ini file
11597 status = hdd_parse_config_ini( pHddCtx );
11598 if ( VOS_STATUS_SUCCESS != status )
11599 {
11600 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
11601 __func__, WLAN_INI_FILE);
11602 goto err_config;
11603 }
Arif Hussaind5218912013-12-05 01:10:55 -080011604#ifdef MEMORY_DEBUG
11605 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
11606 vos_mem_init();
11607
11608 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
11609 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
11610#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011611
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +053011612 /* INI has been read, initialise the configuredMcastBcastFilter with
11613 * INI value as this will serve as the default value
11614 */
11615 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
11616 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
11617 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011618
11619 if (false == hdd_is_5g_supported(pHddCtx))
11620 {
11621 //5Ghz is not supported.
11622 if (1 != pHddCtx->cfg_ini->nBandCapability)
11623 {
11624 hddLog(VOS_TRACE_LEVEL_INFO,
11625 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
11626 pHddCtx->cfg_ini->nBandCapability = 1;
11627 }
11628 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053011629
11630 /* If SNR Monitoring is enabled, FW has to parse all beacons
11631 * for calcaluting and storing the average SNR, so set Nth beacon
11632 * filter to 1 to enable FW to parse all the beaocons
11633 */
11634 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
11635 {
11636 /* The log level is deliberately set to WARN as overriding
11637 * nthBeaconFilter to 1 will increase power cosumption and this
11638 * might just prove helpful to detect the power issue.
11639 */
11640 hddLog(VOS_TRACE_LEVEL_WARN,
11641 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
11642 pHddCtx->cfg_ini->nthBeaconFilter = 1;
11643 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011644 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011645 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -070011646 */
Manjeet Singh61016fa2016-12-02 11:10:19 +053011647 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
Jeff Johnson295189b2012-06-20 16:38:30 -070011648 {
Manjeet Singh61016fa2016-12-02 11:10:19 +053011649 hddLog(VOS_TRACE_LEVEL_FATAL,
11650 "%s: wlan_hdd_cfg80211_init return failure", __func__);
11651 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070011652 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011653
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011654 // Update VOS trace levels based upon the cfg.ini
11655 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
11656 pHddCtx->cfg_ini->vosTraceEnableBAP);
11657 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
11658 pHddCtx->cfg_ini->vosTraceEnableTL);
11659 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
11660 pHddCtx->cfg_ini->vosTraceEnableWDI);
11661 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
11662 pHddCtx->cfg_ini->vosTraceEnableHDD);
11663 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
11664 pHddCtx->cfg_ini->vosTraceEnableSME);
11665 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
11666 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +053011667 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
11668 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011669 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
11670 pHddCtx->cfg_ini->vosTraceEnableWDA);
11671 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
11672 pHddCtx->cfg_ini->vosTraceEnableSYS);
11673 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
11674 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011675 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
11676 pHddCtx->cfg_ini->vosTraceEnableSAP);
11677 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
11678 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011679
Jeff Johnson295189b2012-06-20 16:38:30 -070011680 // Update WDI trace levels based upon the cfg.ini
11681 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
11682 pHddCtx->cfg_ini->wdiTraceEnableDAL);
11683 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
11684 pHddCtx->cfg_ini->wdiTraceEnableCTL);
11685 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
11686 pHddCtx->cfg_ini->wdiTraceEnableDAT);
11687 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
11688 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -070011689
Jeff Johnson88ba7742013-02-27 14:36:02 -080011690 if (VOS_FTM_MODE == hdd_get_conparam())
11691 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011692 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
11693 {
11694 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
11695 goto err_free_hdd_context;
11696 }
11697 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +053011698 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +053011699 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011700 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -080011701 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011702
Katya Nigame7b69a82015-04-28 15:24:06 +053011703 if( VOS_MONITOR_MODE == hdd_get_conparam())
11704 {
11705 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
11706 {
11707 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
11708 goto err_free_hdd_context;
11709 }
11710 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
11711 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
11712 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
11713 return VOS_STATUS_SUCCESS;
11714 }
11715
Jeff Johnson88ba7742013-02-27 14:36:02 -080011716 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -070011717 if(pHddCtx->cfg_ini->fIsLogpEnabled)
11718 {
11719 status = vos_watchdog_open(pVosContext,
11720 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
11721
11722 if(!VOS_IS_STATUS_SUCCESS( status ))
11723 {
11724 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011725 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011726 }
11727 }
11728
11729 pHddCtx->isLogpInProgress = FALSE;
11730 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
11731
Amar Singhala49cbc52013-10-08 18:37:44 -070011732#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070011733 /* initialize the NV module. This is required so that
11734 we can initialize the channel information in wiphy
11735 from the NV.bin data. The channel information in
11736 wiphy needs to be initialized before wiphy registration */
11737
11738 status = vos_nv_open();
11739 if (!VOS_IS_STATUS_SUCCESS(status))
11740 {
11741 /* NV module cannot be initialized */
11742 hddLog( VOS_TRACE_LEVEL_FATAL,
11743 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +053011744 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -070011745 }
11746
11747 status = vos_init_wiphy_from_nv_bin();
11748 if (!VOS_IS_STATUS_SUCCESS(status))
11749 {
11750 /* NV module cannot be initialized */
11751 hddLog( VOS_TRACE_LEVEL_FATAL,
11752 "%s: vos_init_wiphy failed", __func__);
11753 goto err_vos_nv_close;
11754 }
11755
Amar Singhala49cbc52013-10-08 18:37:44 -070011756#endif
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053011757 //Initialize the nlink service
11758 if(nl_srv_init() != 0)
11759 {
11760 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
11761 goto err_vos_nv_close;
11762 }
11763
11764#ifdef WLAN_KD_READY_NOTIFIER
11765 pHddCtx->kd_nl_init = 1;
11766#endif /* WLAN_KD_READY_NOTIFIER */
11767
Girish Gowlibf0e1ab2015-01-19 16:05:16 +053011768 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053011769 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070011770 if ( !VOS_IS_STATUS_SUCCESS( status ))
11771 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011772 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053011773 goto err_nl_srv;
Jeff Johnson295189b2012-06-20 16:38:30 -070011774 }
11775
Jeff Johnson295189b2012-06-20 16:38:30 -070011776 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
11777
11778 if ( NULL == pHddCtx->hHal )
11779 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011780 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011781 goto err_vosclose;
11782 }
11783
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011784 status = vos_preStart( pHddCtx->pvosContext );
11785 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11786 {
11787 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011788 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011789 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011790
Arif Hussaineaf68602013-12-30 23:10:44 -080011791 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
11792 {
11793 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
11794 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
11795 __func__, enable_dfs_chan_scan);
11796 }
11797 if (0 == enable_11d || 1 == enable_11d)
11798 {
11799 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
11800 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
11801 __func__, enable_11d);
11802 }
11803
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011804 /* Note that the vos_preStart() sequence triggers the cfg download.
11805 The cfg download must occur before we update the SME config
11806 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -070011807 status = hdd_set_sme_config( pHddCtx );
11808
11809 if ( VOS_STATUS_SUCCESS != status )
11810 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011811 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011812 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011813 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011814
Jeff Johnson295189b2012-06-20 16:38:30 -070011815 /* In the integrated architecture we update the configuration from
11816 the INI file and from NV before vOSS has been started so that
11817 the final contents are available to send down to the cCPU */
11818
11819 // Apply the cfg.ini to cfg.dat
11820 if (FALSE == hdd_update_config_dat(pHddCtx))
11821 {
11822 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011823 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011824 }
11825
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011826 // Get mac addr from platform driver
11827 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
11828
11829 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011830 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011831 /* Store the mac addr for first interface */
11832 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
11833
11834 hddLog(VOS_TRACE_LEVEL_ERROR,
11835 "%s: WLAN Mac Addr: "
11836 MAC_ADDRESS_STR, __func__,
11837 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
11838
11839 /* Here, passing Arg2 as 1 because we do not want to change the
11840 last 3 bytes (means non OUI bytes) of first interface mac
11841 addr.
11842 */
11843 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
11844 {
11845 hddLog(VOS_TRACE_LEVEL_ERROR,
11846 "%s: Failed to generate wlan interface mac addr "
11847 "using MAC from ini file ", __func__);
11848 }
11849 }
11850 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
11851 {
11852 // Apply the NV to cfg.dat
11853 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070011854#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
11855 /* There was not a valid set of MAC Addresses in NV. See if the
11856 default addresses were modified by the cfg.ini settings. If so,
11857 we'll use them, but if not, we'll autogenerate a set of MAC
11858 addresses based upon the device serial number */
11859
11860 static const v_MACADDR_t default_address =
11861 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070011862
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011863 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
11864 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011865 {
11866 /* cfg.ini has the default address, invoke autogen logic */
11867
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011868 /* Here, passing Arg2 as 0 because we want to change the
11869 last 3 bytes (means non OUI bytes) of all the interfaces
11870 mac addr.
11871 */
11872 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
11873 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070011874 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011875 hddLog(VOS_TRACE_LEVEL_ERROR,
11876 "%s: Failed to generate wlan interface mac addr "
11877 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
11878 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070011879 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011880 }
11881 else
11882#endif //WLAN_AUTOGEN_MACADDR_FEATURE
11883 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011884 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011885 "%s: Invalid MAC address in NV, using MAC from ini file "
11886 MAC_ADDRESS_STR, __func__,
11887 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
11888 }
11889 }
11890 {
11891 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011892
11893 /* Set the MAC Address Currently this is used by HAL to
11894 * add self sta. Remove this once self sta is added as
11895 * part of session open.
11896 */
Jeff Johnson295189b2012-06-20 16:38:30 -070011897 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
11898 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
11899 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011900
Jeff Johnson295189b2012-06-20 16:38:30 -070011901 if (!HAL_STATUS_SUCCESS( halStatus ))
11902 {
11903 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
11904 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011905 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011906 }
11907 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011908
11909 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
11910 Note: Firmware image will be read and downloaded inside vos_start API */
11911 status = vos_start( pHddCtx->pvosContext );
11912 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11913 {
11914 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053011915 if (isSsrPanicOnFailure())
11916 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011917 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011918 }
11919
Leo Chang6cec3e22014-01-21 15:33:49 -080011920#ifdef FEATURE_WLAN_CH_AVOID
11921 /* Plug in avoid channel notification callback
11922 * This should happen before ADD_SELF_STA
11923 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053011924
11925 /* check the Channel Avoidance is enabled */
11926 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
11927 {
11928 sme_AddChAvoidCallback(pHddCtx->hHal,
11929 hdd_hostapd_ch_avoid_cb);
11930 }
Leo Chang6cec3e22014-01-21 15:33:49 -080011931#endif /* FEATURE_WLAN_CH_AVOID */
11932
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011933 /* Exchange capability info between Host and FW and also get versioning info from FW */
11934 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011935
Agarwal Ashishad9281b2014-06-10 14:57:30 +053011936#ifdef CONFIG_ENABLE_LINUX_REG
11937 status = wlan_hdd_init_channels(pHddCtx);
11938 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11939 {
11940 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
11941 __func__);
11942 goto err_vosstop;
11943 }
11944#endif
11945
Jeff Johnson295189b2012-06-20 16:38:30 -070011946 status = hdd_post_voss_start_config( pHddCtx );
11947 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11948 {
11949 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
11950 __func__);
11951 goto err_vosstop;
11952 }
Amar Singhala49cbc52013-10-08 18:37:44 -070011953
11954#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011955 wlan_hdd_cfg80211_update_reg_info( wiphy );
11956
11957 /* registration of wiphy dev with cfg80211 */
11958 if (0 > wlan_hdd_cfg80211_register(wiphy))
11959 {
11960 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
11961 goto err_vosstop;
11962 }
Amar Singhala49cbc52013-10-08 18:37:44 -070011963#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011964
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011965#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011966 /* registration of wiphy dev with cfg80211 */
11967 if (0 > wlan_hdd_cfg80211_register(wiphy))
11968 {
11969 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
11970 goto err_vosstop;
11971 }
11972
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011973 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011974 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11975 {
11976 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
11977 __func__);
11978 goto err_unregister_wiphy;
11979 }
11980#endif
11981
c_hpothu4a298be2014-12-22 21:12:51 +053011982 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
11983
Jeff Johnson295189b2012-06-20 16:38:30 -070011984 if (VOS_STA_SAP_MODE == hdd_get_conparam())
11985 {
11986 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
11987 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
11988 }
11989 else
11990 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011991 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
11992 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
11993 if (pAdapter != NULL)
11994 {
Katya Nigama7d81d72014-11-12 12:44:34 +053011995 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070011996 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053011997 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
11998 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
11999 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070012000
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053012001 /* Generate the P2P Device Address. This consists of the device's
12002 * primary MAC address with the locally administered bit set.
12003 */
12004 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070012005 }
12006 else
12007 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053012008 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
12009 if (p2p_dev_addr != NULL)
12010 {
12011 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
12012 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
12013 }
12014 else
12015 {
12016 hddLog(VOS_TRACE_LEVEL_FATAL,
12017 "%s: Failed to allocate mac_address for p2p_device",
12018 __func__);
12019 goto err_close_adapter;
12020 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012021 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012022
12023 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
12024 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
12025 if ( NULL == pP2pAdapter )
12026 {
12027 hddLog(VOS_TRACE_LEVEL_FATAL,
12028 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012029 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070012030 goto err_close_adapter;
12031 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012032 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012033 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012034
12035 if( pAdapter == NULL )
12036 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012037 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
12038 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070012039 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012040
Arif Hussain66559122013-11-21 10:11:40 -080012041 if (country_code)
12042 {
12043 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080012044 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080012045 hdd_checkandupdate_dfssetting(pAdapter, country_code);
12046#ifndef CONFIG_ENABLE_LINUX_REG
12047 hdd_checkandupdate_phymode(pAdapter, country_code);
12048#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080012049 ret = sme_ChangeCountryCode(pHddCtx->hHal,
12050 (void *)(tSmeChangeCountryCallback)
12051 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080012052 country_code,
12053 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012054 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080012055 if (eHAL_STATUS_SUCCESS == ret)
12056 {
Arif Hussaincb607082013-12-20 11:57:42 -080012057 ret = wait_for_completion_interruptible_timeout(
12058 &pAdapter->change_country_code,
12059 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
12060
12061 if (0 >= ret)
12062 {
12063 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12064 "%s: SME while setting country code timed out", __func__);
12065 }
Arif Hussain66559122013-11-21 10:11:40 -080012066 }
12067 else
12068 {
Arif Hussaincb607082013-12-20 11:57:42 -080012069 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12070 "%s: SME Change Country code from module param fail ret=%d",
12071 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080012072 }
12073 }
12074
Jeff Johnson295189b2012-06-20 16:38:30 -070012075#ifdef WLAN_BTAMP_FEATURE
12076 vStatus = WLANBAP_Open(pVosContext);
12077 if(!VOS_IS_STATUS_SUCCESS(vStatus))
12078 {
12079 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12080 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070012081 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070012082 }
12083
12084 vStatus = BSL_Init(pVosContext);
12085 if(!VOS_IS_STATUS_SUCCESS(vStatus))
12086 {
12087 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12088 "%s: Failed to Init BSL",__func__);
12089 goto err_bap_close;
12090 }
12091 vStatus = WLANBAP_Start(pVosContext);
12092 if (!VOS_IS_STATUS_SUCCESS(vStatus))
12093 {
12094 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12095 "%s: Failed to start TL",__func__);
12096 goto err_bap_close;
12097 }
12098
12099 pConfig = pHddCtx->cfg_ini;
12100 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
12101 status = WLANBAP_SetConfig(&btAmpConfig);
12102
12103#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070012104
Mihir Shete9c238772014-10-15 14:35:16 +053012105 /*
12106 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
12107 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
12108 * which is greater than 0xf. So the below check is safe to make
12109 * sure that there is no entry for UapsdMask in the ini
12110 */
12111 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
12112 {
12113 if(IS_DYNAMIC_WMM_PS_ENABLED)
12114 {
12115 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
12116 __func__);
12117 pHddCtx->cfg_ini->UapsdMask =
12118 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
12119 }
12120 else
12121 {
12122 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
12123 __func__);
12124 pHddCtx->cfg_ini->UapsdMask =
12125 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
12126 }
12127 }
12128
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070012129#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
12130 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
12131 {
12132 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
12133 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
12134 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
12135 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
12136 }
12137#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012138
Agarwal Ashish4b87f922014-06-18 03:03:21 +053012139 wlan_hdd_tdls_init(pHddCtx);
12140
Masti, Narayanraddi26378462016-01-05 18:20:28 +053012141 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
12142
12143 vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work,
12144 wlan_hdd_schedule_defer_scan);
12145
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053012146 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
12147
Jeff Johnson295189b2012-06-20 16:38:30 -070012148 /* Register with platform driver as client for Suspend/Resume */
12149 status = hddRegisterPmOps(pHddCtx);
12150 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12151 {
12152 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
12153#ifdef WLAN_BTAMP_FEATURE
12154 goto err_bap_stop;
12155#else
Jeff Johnsone7245742012-09-05 17:12:55 -070012156 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070012157#endif //WLAN_BTAMP_FEATURE
12158 }
12159
Yue Ma0d4891e2013-08-06 17:01:45 -070012160 /* Open debugfs interface */
12161 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
12162 {
12163 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12164 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070012165 }
12166
Jeff Johnson295189b2012-06-20 16:38:30 -070012167 /* Register TM level change handler function to the platform */
12168 status = hddDevTmRegisterNotifyCallback(pHddCtx);
12169 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12170 {
12171 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
12172 goto err_unregister_pmops;
12173 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012174
Jeff Johnson295189b2012-06-20 16:38:30 -070012175 // register net device notifier for device change notification
12176 ret = register_netdevice_notifier(&hdd_netdev_notifier);
12177
12178 if(ret < 0)
12179 {
12180 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053012181 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070012182 }
12183
Jeff Johnson295189b2012-06-20 16:38:30 -070012184 //Initialize the BTC service
12185 if(btc_activate_service(pHddCtx) != 0)
12186 {
12187 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012188 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070012189 }
12190
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053012191#ifdef FEATURE_OEM_DATA_SUPPORT
12192 //Initialize the OEM service
12193 if (oem_activate_service(pHddCtx) != 0)
12194 {
12195 hddLog(VOS_TRACE_LEVEL_FATAL,
12196 "%s: oem_activate_service failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012197 goto err_reg_netdev;
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053012198 }
12199#endif
12200
Jeff Johnson295189b2012-06-20 16:38:30 -070012201#ifdef PTT_SOCK_SVC_ENABLE
12202 //Initialize the PTT service
12203 if(ptt_sock_activate_svc(pHddCtx) != 0)
12204 {
12205 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012206 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070012207 }
12208#endif
12209
Abhishek Singh00b71972016-01-07 10:51:04 +053012210#ifdef WLAN_FEATURE_RMC
12211 if (hdd_open_cesium_nl_sock() < 0)
12212 {
12213 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
12214 goto err_reg_netdev;
12215 }
12216#endif
12217
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012218#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12219 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
12220 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053012221 if(wlan_logging_sock_activate_svc(
12222 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053012223 pHddCtx->cfg_ini->wlanLoggingNumBuf,
12224 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
12225 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053012226 {
12227 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
12228 " failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012229 goto err_reg_netdev;
Deepthi Gowri78083a32014-11-04 12:55:51 +053012230 }
12231 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
12232 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053012233 if (!pHddCtx->cfg_ini->gEnableDebugLog)
12234 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053012235 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
12236 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012237 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012238
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012239 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
12240 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053012241 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053012242 pHddCtx->cfg_ini->enableContFWLogging ||
12243 pHddCtx->cfg_ini->enableFwrMemDump )
12244 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012245 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012246 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012247 }
12248 else
12249 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012250 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012251 }
12252
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012253#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012254
Agrawal Ashish17ef5082016-10-17 18:33:21 +053012255#ifdef SAP_AUTH_OFFLOAD
12256 if (!sme_IsFeatureSupportedByFW(SAP_OFFLOADS))
12257 {
12258 hddLog(VOS_TRACE_LEVEL_INFO, FL(" SAP AUTH OFFLOAD not supp by FW"));
12259 pHddCtx->cfg_ini->enable_sap_auth_offload = 0;
12260 }
12261#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012262
Sushant Kaushik215778f2015-05-21 14:05:36 +053012263 if (vos_is_multicast_logging())
12264 wlan_logging_set_log_level();
12265
Jeff Johnson295189b2012-06-20 16:38:30 -070012266 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012267 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070012268 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070012269 /* Action frame registered in one adapter which will
12270 * applicable to all interfaces
12271 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053012272 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012273 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012274
12275 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053012276 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012277
Jeff Johnsone7245742012-09-05 17:12:55 -070012278#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
12279 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012280 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070012281 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012282
Jeff Johnsone7245742012-09-05 17:12:55 -070012283#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012284 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012285 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012286 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012287
Jeff Johnsone7245742012-09-05 17:12:55 -070012288
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012289 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
12290 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012291
Katya Nigam5c306ea2014-06-19 15:39:54 +053012292 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012293 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012294 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053012295
12296#ifdef FEATURE_WLAN_SCAN_PNO
12297 /*SME must send channel update configuration to RIVA*/
12298 sme_UpdateChannelConfig(pHddCtx->hHal);
12299#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053012300 /* Send the update default channel list to the FW*/
12301 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053012302
12303 /* Fwr capabilities received, Set the Dot11 mode */
Abhishek Singh41ebce12016-02-03 10:43:21 +053012304 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
12305 hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode));
Mukul Sharma45063942015-04-01 20:07:59 +053012306 sme_SetDefDot11Mode(pHddCtx->hHal);
12307
Abhishek Singha306a442013-11-07 18:39:01 +053012308#ifndef CONFIG_ENABLE_LINUX_REG
12309 /*updating wiphy so that regulatory user hints can be processed*/
12310 if (wiphy)
12311 {
12312 regulatory_hint(wiphy, "00");
12313 }
12314#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012315 // Initialize the restart logic
12316 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053012317
Hanumanth Reddy Pothula146bca42016-11-08 12:01:07 +053012318 if (pHddCtx->cfg_ini->fIsLogpEnabled) {
12319 vos_wdthread_init_timer_work(vos_process_wd_timer);
12320 /* Initialize the timer to detect thread stuck issues */
12321 vos_thread_stuck_timer_init(
12322 &((VosContextType*)pVosContext)->vosWatchdog);
12323 }
12324
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012325 //Register the traffic monitor timer now
12326 if ( pHddCtx->cfg_ini->dynSplitscan)
12327 {
12328 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
12329 VOS_TIMER_TYPE_SW,
12330 hdd_tx_rx_pkt_cnt_stat_timer_handler,
12331 (void *)pHddCtx);
12332 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053012333 wlan_hdd_cfg80211_nan_init(pHddCtx);
12334
Bhargav Shahd0715912015-10-01 18:17:37 +053012335 mutex_init(&pHddCtx->cur_rx_level_lock);
12336 vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
12337 hdd_tcp_delack_compute_function,(void *)pHddCtx);
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012338 vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW,
12339 wlan_hdd_change_tdls_mode, (void *)pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +053012340
Dino Mycle6fb96c12014-06-10 11:52:40 +053012341#ifdef WLAN_FEATURE_EXTSCAN
12342 sme_EXTScanRegisterCallback(pHddCtx->hHal,
12343 wlan_hdd_cfg80211_extscan_callback,
12344 pHddCtx);
12345#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012346
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053012347#ifdef FEATURE_OEM_DATA_SUPPORT
12348 sme_OemDataRegisterCallback(pHddCtx->hHal,
12349 wlan_hdd_cfg80211_oemdata_callback,
12350 pHddCtx);
12351#endif /* FEATURE_OEM_DATA_SUPPORT */
12352
Gupta, Kapil7c34b322015-09-30 13:12:35 +053012353 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012354#ifdef WLAN_NS_OFFLOAD
12355 // Register IPv6 notifier to notify if any change in IP
12356 // So that we can reconfigure the offload parameters
12357 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
12358 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
12359 if (ret)
12360 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012361 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012362 }
12363 else
12364 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012365 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012366 }
12367#endif
12368
Sravan Kumar Kairamb0edc612016-10-26 13:55:24 +053012369 vos_mem_set((uint8_t *)&pHddCtx->bad_sta, HDD_MAX_STA_COUNT, 0);
12370
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012371 // Register IPv4 notifier to notify if any change in IP
12372 // So that we can reconfigure the offload parameters
12373 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
12374 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
12375 if (ret)
12376 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012377 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012378 }
12379 else
12380 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012381 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012382 }
c_manjeecfd1efb2015-09-25 19:32:34 +053012383 /*Fw mem dump procfs initialization*/
12384 memdump_init();
Bhargav shah23c94942015-10-13 12:48:35 +053012385 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012386
Jeff Johnson295189b2012-06-20 16:38:30 -070012387 goto success;
12388
Jeff Johnson295189b2012-06-20 16:38:30 -070012389err_reg_netdev:
12390 unregister_netdevice_notifier(&hdd_netdev_notifier);
12391
Jeff Johnson295189b2012-06-20 16:38:30 -070012392err_unregister_pmops:
12393 hddDevTmUnregisterNotifyCallback(pHddCtx);
12394 hddDeregisterPmOps(pHddCtx);
12395
Yue Ma0d4891e2013-08-06 17:01:45 -070012396 hdd_debugfs_exit(pHddCtx);
12397
Jeff Johnson295189b2012-06-20 16:38:30 -070012398#ifdef WLAN_BTAMP_FEATURE
12399err_bap_stop:
12400 WLANBAP_Stop(pVosContext);
12401#endif
12402
12403#ifdef WLAN_BTAMP_FEATURE
12404err_bap_close:
12405 WLANBAP_Close(pVosContext);
12406#endif
12407
Jeff Johnson295189b2012-06-20 16:38:30 -070012408err_close_adapter:
12409 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053012410#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012411err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053012412#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053012413 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012414 hdd_wlan_free_wiphy_channels(wiphy);
12415
Jeff Johnson295189b2012-06-20 16:38:30 -070012416err_vosstop:
12417 vos_stop(pVosContext);
12418
Amar Singhala49cbc52013-10-08 18:37:44 -070012419err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070012420 status = vos_sched_close( pVosContext );
12421 if (!VOS_IS_STATUS_SUCCESS(status)) {
12422 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12423 "%s: Failed to close VOSS Scheduler", __func__);
12424 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
12425 }
Amar Singhala49cbc52013-10-08 18:37:44 -070012426 vos_close(pVosContext );
12427
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012428err_nl_srv:
12429#ifdef WLAN_KD_READY_NOTIFIER
12430 nl_srv_exit(pHddCtx->ptt_pid);
12431#else
12432 nl_srv_exit();
12433#endif /* WLAN_KD_READY_NOTIFIER */
Amar Singhal0a402232013-10-11 20:57:16 -070012434err_vos_nv_close:
12435
c_hpothue6a36282014-03-19 12:27:38 +053012436#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070012437 vos_nv_close();
12438
c_hpothu70f8d812014-03-22 22:59:23 +053012439#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012440
12441err_wdclose:
12442 if(pHddCtx->cfg_ini->fIsLogpEnabled)
12443 vos_watchdog_close(pVosContext);
12444
Jeff Johnson295189b2012-06-20 16:38:30 -070012445err_config:
12446 kfree(pHddCtx->cfg_ini);
12447 pHddCtx->cfg_ini= NULL;
12448
12449err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012450 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053012451 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070012452 wiphy_free(wiphy) ;
12453 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070012454 VOS_BUG(1);
12455
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080012456 if (hdd_is_ssr_required())
12457 {
12458 /* WDI timeout had happened during load, so SSR is needed here */
12459 subsystem_restart("wcnss");
12460 msleep(5000);
12461 }
12462 hdd_set_ssr_required (VOS_FALSE);
12463
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012464 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012465
12466success:
12467 EXIT();
12468 return 0;
12469}
12470
12471/**---------------------------------------------------------------------------
12472
Jeff Johnson32d95a32012-09-10 13:15:23 -070012473 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070012474
Jeff Johnson32d95a32012-09-10 13:15:23 -070012475 This is the driver entry point - called in different timeline depending
12476 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070012477
12478 \param - None
12479
12480 \return - 0 for success, non zero for failure
12481
12482 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070012483static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070012484{
12485 VOS_STATUS status;
12486 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012487 struct device *dev = NULL;
12488 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012489#ifdef HAVE_WCNSS_CAL_DOWNLOAD
12490 int max_retries = 0;
12491#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012492#ifdef HAVE_CBC_DONE
12493 int max_cbc_retries = 0;
12494#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012495
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012496#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12497 wlan_logging_sock_init_svc();
12498#endif
12499
Jeff Johnson295189b2012-06-20 16:38:30 -070012500 ENTER();
12501
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012502 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070012503
12504 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
12505 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
12506
Jeff Johnson295189b2012-06-20 16:38:30 -070012507#ifdef ANI_BUS_TYPE_PCI
12508
12509 dev = wcnss_wlan_get_device();
12510
12511#endif // ANI_BUS_TYPE_PCI
12512
12513#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012514
12515#ifdef HAVE_WCNSS_CAL_DOWNLOAD
12516 /* wait until WCNSS driver downloads NV */
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053012517 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012518 msleep(1000);
12519 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012520
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053012521 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012522 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012523 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012524#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12525 wlan_logging_sock_deinit_svc();
12526#endif
12527
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012528 return -ENODEV;
12529 }
12530#endif
12531
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012532#ifdef HAVE_CBC_DONE
12533 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
12534 msleep(1000);
12535 }
12536 if (max_cbc_retries >= 10) {
12537 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
12538 }
12539#endif
12540
Jeff Johnson295189b2012-06-20 16:38:30 -070012541 dev = wcnss_wlan_get_device();
12542#endif // ANI_BUS_TYPE_PLATFORM
12543
12544
12545 do {
12546 if (NULL == dev) {
12547 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
12548 ret_status = -1;
12549 break;
12550 }
12551
Jeff Johnson295189b2012-06-20 16:38:30 -070012552#ifdef TIMER_MANAGER
12553 vos_timer_manager_init();
12554#endif
12555
12556 /* Preopen VOSS so that it is ready to start at least SAL */
12557 status = vos_preOpen(&pVosContext);
12558
12559 if (!VOS_IS_STATUS_SUCCESS(status))
12560 {
12561 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
12562 ret_status = -1;
12563 break;
12564 }
12565
Sushant Kaushik02beb352015-06-04 15:15:01 +053012566 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053012567 hdd_register_debug_callback();
12568
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012569#ifndef MODULE
12570 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
12571 */
12572 hdd_set_conparam((v_UINT_t)con_mode);
12573#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012574
12575 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012576 if (hdd_wlan_startup(dev))
12577 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012578 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012579 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012580 vos_preClose( &pVosContext );
12581 ret_status = -1;
12582 break;
12583 }
12584
Jeff Johnson295189b2012-06-20 16:38:30 -070012585 } while (0);
12586
12587 if (0 != ret_status)
12588 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012589#ifdef TIMER_MANAGER
12590 vos_timer_exit();
12591#endif
12592#ifdef MEMORY_DEBUG
12593 vos_mem_exit();
12594#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012595 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012596#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12597 wlan_logging_sock_deinit_svc();
12598#endif
12599
Jeff Johnson295189b2012-06-20 16:38:30 -070012600 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
12601 }
12602 else
12603 {
12604 //Send WLAN UP indication to Nlink Service
12605 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
12606
12607 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070012608 }
12609
12610 EXIT();
12611
12612 return ret_status;
12613}
12614
Jeff Johnson32d95a32012-09-10 13:15:23 -070012615/**---------------------------------------------------------------------------
12616
12617 \brief hdd_module_init() - Init Function
12618
12619 This is the driver entry point (invoked when module is loaded using insmod)
12620
12621 \param - None
12622
12623 \return - 0 for success, non zero for failure
12624
12625 --------------------------------------------------------------------------*/
12626#ifdef MODULE
12627static int __init hdd_module_init ( void)
12628{
12629 return hdd_driver_init();
12630}
Jeff Johnson32d95a32012-09-10 13:15:23 -070012631#else /* #ifdef MODULE */
12632static int __init hdd_module_init ( void)
12633{
12634 /* Driver initialization is delayed to fwpath_changed_handler */
12635 return 0;
12636}
Jeff Johnson32d95a32012-09-10 13:15:23 -070012637#endif /* #ifdef MODULE */
12638
Jeff Johnson295189b2012-06-20 16:38:30 -070012639
12640/**---------------------------------------------------------------------------
12641
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012642 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070012643
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012644 This is the driver exit point (invoked when module is unloaded using rmmod
12645 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070012646
12647 \param - None
12648
12649 \return - None
12650
12651 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012652static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070012653{
12654 hdd_context_t *pHddCtx = NULL;
12655 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053012656 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053012657 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012658
12659 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
12660
12661 //Get the global vos context
12662 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12663
12664 if(!pVosContext)
12665 {
12666 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
12667 goto done;
12668 }
12669
12670 //Get the HDD context.
12671 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
12672
12673 if(!pHddCtx)
12674 {
12675 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
12676 }
Katya Nigame7b69a82015-04-28 15:24:06 +053012677 else if (VOS_MONITOR_MODE == hdd_get_conparam())
12678 {
12679 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
12680 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
12681 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
12682 hdd_wlan_exit(pHddCtx);
12683 vos_preClose( &pVosContext );
12684 goto done;
12685 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012686 else
12687 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053012688 /* We wait for active entry threads to exit from driver
12689 * by waiting until rtnl_lock is available.
12690 */
12691 rtnl_lock();
12692 rtnl_unlock();
12693
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012694 INIT_COMPLETION(pHddCtx->ssr_comp_var);
12695 if ((pHddCtx->isLogpInProgress) && (FALSE ==
12696 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
12697 {
Siddharth Bhala204f572015-01-17 02:03:36 +053012698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012699 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053012700 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
12701 msecs_to_jiffies(30000));
12702 if(!rc)
12703 {
12704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12705 "%s:SSR timedout, fatal error", __func__);
12706 VOS_BUG(0);
12707 }
12708 }
12709
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012710 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
12711 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012712
c_hpothu8adb97b2014-12-08 19:38:20 +053012713 /* Driver Need to send country code 00 in below condition
12714 * 1) If gCountryCodePriority is set to 1; and last country
12715 * code set is through 11d. This needs to be done in case
12716 * when NV country code is 00.
12717 * This Needs to be done as when kernel store last country
12718 * code and if stored country code is not through 11d,
12719 * in sme_HandleChangeCountryCodeByUser we will disable 11d
12720 * in next load/unload as soon as we get any country through
12721 * 11d. In sme_HandleChangeCountryCodeByUser
12722 * pMsg->countryCode will be last countryCode and
12723 * pMac->scan.countryCode11d will be country through 11d so
12724 * due to mismatch driver will disable 11d.
12725 *
12726 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053012727
c_hpothu8adb97b2014-12-08 19:38:20 +053012728 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053012729 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053012730 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053012731 {
12732 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053012733 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053012734 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
12735 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053012736
c_hpothu8adb97b2014-12-08 19:38:20 +053012737 //Do all the cleanup before deregistering the driver
12738 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012739 }
12740
Jeff Johnson295189b2012-06-20 16:38:30 -070012741 vos_preClose( &pVosContext );
12742
12743#ifdef TIMER_MANAGER
12744 vos_timer_exit();
12745#endif
12746#ifdef MEMORY_DEBUG
12747 vos_mem_exit();
12748#endif
12749
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012750#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12751 wlan_logging_sock_deinit_svc();
12752#endif
12753
Jeff Johnson295189b2012-06-20 16:38:30 -070012754done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012755 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012756
Jeff Johnson295189b2012-06-20 16:38:30 -070012757 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
12758}
12759
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012760/**---------------------------------------------------------------------------
12761
12762 \brief hdd_module_exit() - Exit function
12763
12764 This is the driver exit point (invoked when module is unloaded using rmmod)
12765
12766 \param - None
12767
12768 \return - None
12769
12770 --------------------------------------------------------------------------*/
12771static void __exit hdd_module_exit(void)
12772{
12773 hdd_driver_exit();
12774}
12775
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012776#ifdef MODULE
12777static int fwpath_changed_handler(const char *kmessage,
12778 struct kernel_param *kp)
12779{
Jeff Johnson76052702013-04-16 13:55:05 -070012780 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012781}
12782
12783static int con_mode_handler(const char *kmessage,
12784 struct kernel_param *kp)
12785{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070012786 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012787}
12788#else /* #ifdef MODULE */
12789/**---------------------------------------------------------------------------
12790
Jeff Johnson76052702013-04-16 13:55:05 -070012791 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012792
Jeff Johnson76052702013-04-16 13:55:05 -070012793 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012794 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070012795 - invoked when module parameter fwpath is modified from userspace to signal
12796 initializing the WLAN driver or when con_mode is modified from userspace
12797 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012798
12799 \return - 0 for success, non zero for failure
12800
12801 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070012802static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012803{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070012804 int ret_status;
12805
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012806 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070012807 ret_status = hdd_driver_init();
12808 wlan_hdd_inited = ret_status ? 0 : 1;
12809 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012810 }
12811
12812 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070012813
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012814 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070012815
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070012816 ret_status = hdd_driver_init();
12817 wlan_hdd_inited = ret_status ? 0 : 1;
12818 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012819}
12820
Jeff Johnson295189b2012-06-20 16:38:30 -070012821/**---------------------------------------------------------------------------
12822
Jeff Johnson76052702013-04-16 13:55:05 -070012823 \brief fwpath_changed_handler() - Handler Function
12824
12825 Handle changes to the fwpath parameter
12826
12827 \return - 0 for success, non zero for failure
12828
12829 --------------------------------------------------------------------------*/
12830static int fwpath_changed_handler(const char *kmessage,
12831 struct kernel_param *kp)
12832{
12833 int ret;
12834
12835 ret = param_set_copystring(kmessage, kp);
12836 if (0 == ret)
12837 ret = kickstart_driver();
12838 return ret;
12839}
12840
12841/**---------------------------------------------------------------------------
12842
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012843 \brief con_mode_handler() -
12844
12845 Handler function for module param con_mode when it is changed by userspace
12846 Dynamically linked - do nothing
12847 Statically linked - exit and init driver, as in rmmod and insmod
12848
Jeff Johnson76052702013-04-16 13:55:05 -070012849 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012850
Jeff Johnson76052702013-04-16 13:55:05 -070012851 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012852
12853 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070012854static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012855{
Jeff Johnson76052702013-04-16 13:55:05 -070012856 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012857
Jeff Johnson76052702013-04-16 13:55:05 -070012858 ret = param_set_int(kmessage, kp);
12859 if (0 == ret)
12860 ret = kickstart_driver();
12861 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012862}
12863#endif /* #ifdef MODULE */
12864
12865/**---------------------------------------------------------------------------
12866
Jeff Johnson295189b2012-06-20 16:38:30 -070012867 \brief hdd_get_conparam() -
12868
12869 This is the driver exit point (invoked when module is unloaded using rmmod)
12870
12871 \param - None
12872
12873 \return - tVOS_CON_MODE
12874
12875 --------------------------------------------------------------------------*/
12876tVOS_CON_MODE hdd_get_conparam ( void )
12877{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012878#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070012879 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012880#else
12881 return (tVOS_CON_MODE)curr_con_mode;
12882#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012883}
12884void hdd_set_conparam ( v_UINT_t newParam )
12885{
12886 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012887#ifndef MODULE
12888 curr_con_mode = con_mode;
12889#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012890}
12891/**---------------------------------------------------------------------------
12892
12893 \brief hdd_softap_sta_deauth() - function
12894
12895 This to take counter measure to handle deauth req from HDD
12896
12897 \param - pAdapter - Pointer to the HDD
12898
12899 \param - enable - boolean value
12900
12901 \return - None
12902
12903 --------------------------------------------------------------------------*/
12904
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012905VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
12906 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070012907{
Jeff Johnson295189b2012-06-20 16:38:30 -070012908 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012909 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070012910
12911 ENTER();
12912
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012913 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
12914 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070012915
12916 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012917 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012918 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070012919
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012920 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070012921
12922 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012923 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070012924}
12925
12926/**---------------------------------------------------------------------------
12927
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012928 \brief hdd_del_all_sta() - function
12929
12930 This function removes all the stations associated on stopping AP/P2P GO.
12931
12932 \param - pAdapter - Pointer to the HDD
12933
12934 \return - None
12935
12936 --------------------------------------------------------------------------*/
12937
12938int hdd_del_all_sta(hdd_adapter_t *pAdapter)
12939{
12940 v_U16_t i;
12941 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012942 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12943 ptSapContext pSapCtx = NULL;
12944 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12945 if(pSapCtx == NULL){
12946 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12947 FL("psapCtx is NULL"));
12948 return 1;
12949 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012950 ENTER();
12951
12952 hddLog(VOS_TRACE_LEVEL_INFO,
12953 "%s: Delete all STAs associated.",__func__);
12954 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
12955 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
12956 )
12957 {
12958 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
12959 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012960 if ((pSapCtx->aStaInfo[i].isUsed) &&
12961 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012962 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012963 struct tagCsrDelStaParams delStaParams;
12964
12965 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012966 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053012967 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
12968 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012969 &delStaParams);
12970 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012971 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012972 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012973 }
12974 }
12975 }
12976
12977 EXIT();
12978 return 0;
12979}
12980
12981/**---------------------------------------------------------------------------
12982
Jeff Johnson295189b2012-06-20 16:38:30 -070012983 \brief hdd_softap_sta_disassoc() - function
12984
12985 This to take counter measure to handle deauth req from HDD
12986
12987 \param - pAdapter - Pointer to the HDD
12988
12989 \param - enable - boolean value
12990
12991 \return - None
12992
12993 --------------------------------------------------------------------------*/
12994
12995void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
12996{
12997 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12998
12999 ENTER();
13000
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053013001 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070013002
13003 //Ignore request to disassoc bcmc station
13004 if( pDestMacAddress[0] & 0x1 )
13005 return;
13006
13007 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
13008}
13009
13010void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
13011{
13012 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13013
13014 ENTER();
13015
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053013016 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070013017
13018 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
13019}
13020
Jeff Johnson295189b2012-06-20 16:38:30 -070013021/**---------------------------------------------------------------------------
13022 *
13023 * \brief hdd_get__concurrency_mode() -
13024 *
13025 *
13026 * \param - None
13027 *
13028 * \return - CONCURRENCY MODE
13029 *
13030 * --------------------------------------------------------------------------*/
13031tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
13032{
13033 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
13034 hdd_context_t *pHddCtx;
13035
13036 if (NULL != pVosContext)
13037 {
13038 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
13039 if (NULL != pHddCtx)
13040 {
13041 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
13042 }
13043 }
13044
13045 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013046 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013047 return VOS_STA;
13048}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013049v_BOOL_t
13050wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
13051{
13052 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013053
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013054 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
13055 if (pAdapter == NULL)
13056 {
13057 hddLog(VOS_TRACE_LEVEL_INFO,
13058 FL("GO doesn't exist"));
13059 return TRUE;
13060 }
13061 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
13062 {
13063 hddLog(VOS_TRACE_LEVEL_INFO,
13064 FL("GO started"));
13065 return TRUE;
13066 }
13067 else
13068 /* wait till GO changes its interface to p2p device */
13069 hddLog(VOS_TRACE_LEVEL_INFO,
13070 FL("Del_bss called, avoid apps suspend"));
13071 return FALSE;
13072
13073}
Jeff Johnson295189b2012-06-20 16:38:30 -070013074/* Decide whether to allow/not the apps power collapse.
13075 * Allow apps power collapse if we are in connected state.
13076 * if not, allow only if we are in IMPS */
13077v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
13078{
13079 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080013080 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080013081 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070013082 hdd_config_t *pConfig = pHddCtx->cfg_ini;
13083 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13084 hdd_adapter_t *pAdapter = NULL;
13085 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080013086 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013087
Jeff Johnson295189b2012-06-20 16:38:30 -070013088 if (VOS_STA_SAP_MODE == hdd_get_conparam())
13089 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013090
Yathish9f22e662012-12-10 14:21:35 -080013091 concurrent_state = hdd_get_concurrency_mode();
13092
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013093 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
13094 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
13095 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080013096#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013097
Yathish9f22e662012-12-10 14:21:35 -080013098 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013099 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080013100 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
13101 return TRUE;
13102#endif
13103
Jeff Johnson295189b2012-06-20 16:38:30 -070013104 /*loop through all adapters. TBD fix for Concurrency */
13105 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13106 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13107 {
13108 pAdapter = pAdapterNode->pAdapter;
13109 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
13110 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
13111 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080013112 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053013113 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053013114 && pmcState != STOPPED && pmcState != STANDBY &&
13115 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080013116 (eANI_BOOLEAN_TRUE == scanRspPending) ||
13117 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070013118 {
Mukul Sharma4be88422015-03-09 20:29:07 +053013119 if(pmcState == FULL_POWER &&
13120 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
13121 {
13122 /*
13123 * When SCO indication comes from Coex module , host will
13124 * enter in to full power mode, but this should not prevent
13125 * apps processor power collapse.
13126 */
13127 hddLog(LOG1,
13128 FL("Allow apps power collapse"
13129 "even when sco indication is set"));
13130 return TRUE;
13131 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080013132 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Deepthi Gowri03a979f2016-11-03 15:20:19 +053013133 "pmcState = %d scanRspPending = %d "
13134 "inMiddleOfRoaming = %d connected = %d",
13135 __func__, pmcState, scanRspPending,
13136 inMiddleOfRoaming, hdd_connIsConnected(
13137 WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )));
13138 wlan_hdd_get_tdls_stats(pAdapter);
13139 return FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013140 }
13141 }
13142 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13143 pAdapterNode = pNext;
13144 }
13145 return TRUE;
13146}
13147
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080013148/* Decides whether to send suspend notification to Riva
13149 * if any adapter is in BMPS; then it is required */
13150v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
13151{
13152 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
13153 hdd_config_t *pConfig = pHddCtx->cfg_ini;
13154
13155 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
13156 {
13157 return TRUE;
13158 }
13159 return FALSE;
13160}
13161
Jeff Johnson295189b2012-06-20 16:38:30 -070013162void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13163{
13164 switch(mode)
13165 {
Chilam Ngc4244af2013-04-01 15:37:32 -070013166 case VOS_STA_MODE:
13167 case VOS_P2P_CLIENT_MODE:
13168 case VOS_P2P_GO_MODE:
13169 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070013170 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053013171 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070013172 break;
13173 default:
13174 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070013175 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053013176 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
13177 "Number of open sessions for mode %d = %d"),
13178 pHddCtx->concurrency_mode, mode,
13179 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070013180}
13181
13182
13183void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13184{
13185 switch(mode)
13186 {
Chilam Ngc4244af2013-04-01 15:37:32 -070013187 case VOS_STA_MODE:
13188 case VOS_P2P_CLIENT_MODE:
13189 case VOS_P2P_GO_MODE:
13190 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053013191 pHddCtx->no_of_open_sessions[mode]--;
13192 if (!(pHddCtx->no_of_open_sessions[mode]))
13193 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013194 break;
13195 default:
13196 break;
13197 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053013198 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
13199 "Number of open sessions for mode %d = %d"),
13200 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
13201
13202}
13203/**---------------------------------------------------------------------------
13204 *
13205 * \brief wlan_hdd_incr_active_session()
13206 *
13207 * This function increments the number of active sessions
13208 * maintained per device mode
13209 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
13210 * Incase of SAP/P2P GO upon bss start it is incremented
13211 *
13212 * \param pHddCtx - HDD Context
13213 * \param mode - device mode
13214 *
13215 * \return - None
13216 *
13217 * --------------------------------------------------------------------------*/
13218void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13219{
13220 switch (mode) {
13221 case VOS_STA_MODE:
13222 case VOS_P2P_CLIENT_MODE:
13223 case VOS_P2P_GO_MODE:
13224 case VOS_STA_SAP_MODE:
13225 pHddCtx->no_of_active_sessions[mode]++;
13226 break;
13227 default:
13228 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
13229 break;
13230 }
13231 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
13232 mode,
13233 pHddCtx->no_of_active_sessions[mode]);
13234}
13235
13236/**---------------------------------------------------------------------------
13237 *
13238 * \brief wlan_hdd_decr_active_session()
13239 *
13240 * This function decrements the number of active sessions
13241 * maintained per device mode
13242 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
13243 * Incase of SAP/P2P GO upon bss stop it is decremented
13244 *
13245 * \param pHddCtx - HDD Context
13246 * \param mode - device mode
13247 *
13248 * \return - None
13249 *
13250 * --------------------------------------------------------------------------*/
13251void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13252{
Bhargav Shahd0715912015-10-01 18:17:37 +053013253
Agarwal Ashish51325b52014-06-16 16:50:49 +053013254 switch (mode) {
13255 case VOS_STA_MODE:
13256 case VOS_P2P_CLIENT_MODE:
13257 case VOS_P2P_GO_MODE:
13258 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053013259 if (pHddCtx->no_of_active_sessions[mode] > 0)
13260 pHddCtx->no_of_active_sessions[mode]--;
13261 else
13262 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
13263 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053013264 break;
13265 default:
13266 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
13267 break;
13268 }
13269 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
13270 mode,
13271 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070013272}
13273
Jeff Johnsone7245742012-09-05 17:12:55 -070013274/**---------------------------------------------------------------------------
13275 *
13276 * \brief wlan_hdd_restart_init
13277 *
13278 * This function initalizes restart timer/flag. An internal function.
13279 *
13280 * \param - pHddCtx
13281 *
13282 * \return - None
13283 *
13284 * --------------------------------------------------------------------------*/
13285
13286static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
13287{
13288 /* Initialize */
13289 pHddCtx->hdd_restart_retries = 0;
13290 atomic_set(&pHddCtx->isRestartInProgress, 0);
13291 vos_timer_init(&pHddCtx->hdd_restart_timer,
13292 VOS_TIMER_TYPE_SW,
13293 wlan_hdd_restart_timer_cb,
13294 pHddCtx);
13295}
13296/**---------------------------------------------------------------------------
13297 *
13298 * \brief wlan_hdd_restart_deinit
13299 *
13300 * This function cleans up the resources used. An internal function.
13301 *
13302 * \param - pHddCtx
13303 *
13304 * \return - None
13305 *
13306 * --------------------------------------------------------------------------*/
13307
13308static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
13309{
13310
13311 VOS_STATUS vos_status;
13312 /* Block any further calls */
13313 atomic_set(&pHddCtx->isRestartInProgress, 1);
13314 /* Cleanup */
13315 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
13316 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013317 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070013318 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
13319 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013320 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070013321
13322}
13323
13324/**---------------------------------------------------------------------------
13325 *
13326 * \brief wlan_hdd_framework_restart
13327 *
13328 * This function uses a cfg80211 API to start a framework initiated WLAN
13329 * driver module unload/load.
13330 *
13331 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
13332 *
13333 *
13334 * \param - pHddCtx
13335 *
13336 * \return - VOS_STATUS_SUCCESS: Success
13337 * VOS_STATUS_E_EMPTY: Adapter is Empty
13338 * VOS_STATUS_E_NOMEM: No memory
13339
13340 * --------------------------------------------------------------------------*/
13341
13342static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
13343{
13344 VOS_STATUS status = VOS_STATUS_SUCCESS;
13345 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013346 int len = (sizeof (struct ieee80211_mgmt));
13347 struct ieee80211_mgmt *mgmt = NULL;
13348
13349 /* Prepare the DEAUTH managment frame with reason code */
13350 mgmt = kzalloc(len, GFP_KERNEL);
13351 if(mgmt == NULL)
13352 {
13353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13354 "%s: memory allocation failed (%d bytes)", __func__, len);
13355 return VOS_STATUS_E_NOMEM;
13356 }
13357 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070013358
13359 /* Iterate over all adapters/devices */
13360 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013361 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
13362 {
13363 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13364 FL("fail to get adapter: %p %d"), pAdapterNode, status);
13365 goto end;
13366 }
13367
Jeff Johnsone7245742012-09-05 17:12:55 -070013368 do
13369 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013370 if(pAdapterNode->pAdapter &&
13371 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070013372 {
13373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13374 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
13375 pAdapterNode->pAdapter->dev->name,
13376 pAdapterNode->pAdapter->device_mode,
13377 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013378 /*
13379 * CFG80211 event to restart the driver
13380 *
13381 * 'cfg80211_send_unprot_deauth' sends a
13382 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
13383 * of SME(Linux Kernel) state machine.
13384 *
13385 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
13386 * the driver.
13387 *
13388 */
Abhishek Singh00b71972016-01-07 10:51:04 +053013389
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053013390#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
13391 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
13392#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013393 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053013394#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013395 }
13396 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13397 pAdapterNode = pNext;
13398 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
13399
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013400 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013401 /* Free the allocated management frame */
13402 kfree(mgmt);
13403
Jeff Johnsone7245742012-09-05 17:12:55 -070013404 /* Retry until we unload or reach max count */
13405 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
13406 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
13407
13408 return status;
13409
13410}
13411/**---------------------------------------------------------------------------
13412 *
13413 * \brief wlan_hdd_restart_timer_cb
13414 *
13415 * Restart timer callback. An internal function.
13416 *
13417 * \param - User data:
13418 *
13419 * \return - None
13420 *
13421 * --------------------------------------------------------------------------*/
13422
13423void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
13424{
13425 hdd_context_t *pHddCtx = usrDataForCallback;
13426 wlan_hdd_framework_restart(pHddCtx);
13427 return;
13428
13429}
13430
13431
13432/**---------------------------------------------------------------------------
13433 *
13434 * \brief wlan_hdd_restart_driver
13435 *
13436 * This function sends an event to supplicant to restart the WLAN driver.
13437 *
13438 * This function is called from vos_wlanRestart.
13439 *
13440 * \param - pHddCtx
13441 *
13442 * \return - VOS_STATUS_SUCCESS: Success
13443 * VOS_STATUS_E_EMPTY: Adapter is Empty
13444 * VOS_STATUS_E_ALREADY: Request already in progress
13445
13446 * --------------------------------------------------------------------------*/
13447VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
13448{
13449 VOS_STATUS status = VOS_STATUS_SUCCESS;
13450
13451 /* A tight check to make sure reentrancy */
13452 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
13453 {
Mihir Shetefd528652014-06-23 19:07:50 +053013454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070013455 "%s: WLAN restart is already in progress", __func__);
13456
13457 return VOS_STATUS_E_ALREADY;
13458 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070013459 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080013460#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053013461 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070013462#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070013463
Jeff Johnsone7245742012-09-05 17:12:55 -070013464 return status;
13465}
13466
Bhargav Shahd0715912015-10-01 18:17:37 +053013467/**
13468 * hdd_get_total_sessions() - provide total number of active sessions
13469 * @pHddCtx: Valid Global HDD context pointer
13470 *
13471 * This function iterates through pAdaptors and find the number of all active
13472 * sessions. This active sessions includes connected sta, p2p client and number
13473 * of client connected to sap/p2p go.
13474 *
13475 * Return: Total number of active sessions.
13476 */
13477v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx)
13478{
13479 v_U8_t active_session = 0;
13480 hdd_station_ctx_t *pHddStaCtx;
13481 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13482 hdd_adapter_t *pAdapter;
13483 VOS_STATUS status;
13484
13485 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13486 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
13487 pAdapter = pAdapterNode->pAdapter;
13488 switch (pAdapter->device_mode) {
13489 case VOS_STA_MODE:
13490 case VOS_P2P_CLIENT_MODE:
13491 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13492 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
13493 active_session += 1;
13494 break;
13495 case VOS_STA_SAP_MODE:
13496 case VOS_P2P_GO_MODE:
13497 active_session += hdd_softap_get_connected_sta(pAdapter);
13498 break;
13499 default:
13500 break;
13501 }
13502
13503 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
13504 pAdapterNode = pNext;
13505 }
13506
13507 return active_session;
13508}
13509
13510/**
13511 * hdd_set_delack_value() - Set delack value
13512 * @pHddCtx: Valid Global HDD context pointer
13513 * @next_rx_level: Value to set for delack
13514 *
13515 * This function compare present value and next value of delack. If the both
13516 * are diffrent then it sets next value .
13517 *
13518 * Return: void.
13519 */
13520void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
13521{
13522 if (pHddCtx->cur_rx_level != next_rx_level) {
13523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13524 "%s: TCP DELACK trigger level %d",
13525 __func__, next_rx_level);
13526 mutex_lock(&pHddCtx->cur_rx_level_lock);
13527 pHddCtx->cur_rx_level = next_rx_level;
13528 mutex_unlock(&pHddCtx->cur_rx_level_lock);
13529 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &next_rx_level,
13530 sizeof(next_rx_level));
13531 }
13532}
13533
13534/**
13535 * hdd_set_default_stop_delack_timer() - Start delack timer
13536 * @pHddCtx: Valid Global HDD context pointer
13537 *
13538 * This function stop delack timer and set delack value to default..
13539 *
13540 * Return: void.
13541 */
13542
13543void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
13544{
13545 if (VOS_TIMER_STATE_RUNNING !=
13546 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
13547 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13548 "%s: Can not stop timer", __func__);
13549 return;
13550 }
13551
13552 vos_timer_stop(&pHddCtx->delack_timer);
13553 hdd_set_delack_value(pHddCtx, TP_IND_LOW);
13554}
13555
13556/**
13557 * hdd_start_delack_timer() - Start delack timer
13558 * @pHddCtx: Valid Global HDD context pointer
13559 *
13560 * This function starts the delack timer for tcpDelAckComputeInterval time
13561 * interval.The default timer value is 2 second.
13562 *
13563 * Return: void.
13564 */
13565void hdd_start_delack_timer(hdd_context_t *pHddCtx)
13566{
13567 if (VOS_TIMER_STATE_RUNNING ==
13568 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
13569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13570 "%s: Timer is already running", __func__);
13571 return;
13572 }
13573
13574 vos_timer_start(&pHddCtx->delack_timer,
13575 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
13576}
13577
13578/**
13579 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
13580 * @pHddCtx: Valid Global HDD context pointer
13581 *
13582 * This function updates the prev_rx_packets count from the corresponding
13583 * pAdapter states. This prev_rx_packets will diffed with the packet count
13584 * at the end of delack timer. That can give number of RX packet is spacific
13585 * time.
13586 *
13587 * Return: void.
13588 */
13589void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
13590{
13591 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13592 hdd_adapter_t *pAdapter;
13593 VOS_STATUS status;
13594
13595 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13596 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
13597 pAdapter = pAdapterNode->pAdapter;
13598 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
13599 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13600 pAdapterNode = pNext;
13601 }
13602}
13603
13604/**
13605 * hdd_manage_delack_timer() - start\stop delack timer
13606 * @pHddCtx: Valid Global HDD context pointer
13607 *
13608 * This function check the number of concerent session present, it starts the
13609 * delack timer if only one session is present.
13610 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
13611 *
13612 * Return: void.
13613 */
13614void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
13615{
13616 uint8_t sessions;
13617
13618 if (!pHddCtx->cfg_ini->enable_delack) {
13619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13620 "%s: TCP DELACK is not enabled", __func__);
13621 return;
13622 }
13623
13624 /* Blindly stop timer of BTCOEX and TDLS Session is up */
13625 if (pHddCtx->mode != 0) {
13626 hdd_set_default_stop_delack_timer(pHddCtx);
13627 return;
13628 }
13629
13630 sessions = hdd_get_total_sessions(pHddCtx);
13631 if (sessions == 1) {
13632 hdd_update_prev_rx_packet_count(pHddCtx);
13633 hdd_start_delack_timer(pHddCtx);
13634 } else {
13635 hdd_set_default_stop_delack_timer(pHddCtx);
13636 }
13637}
13638
Mihir Shetee1093ba2014-01-21 20:13:32 +053013639/**---------------------------------------------------------------------------
13640 *
13641 * \brief wlan_hdd_init_channels
13642 *
13643 * This function is used to initialize the channel list in CSR
13644 *
13645 * This function is called from hdd_wlan_startup
13646 *
13647 * \param - pHddCtx: HDD context
13648 *
13649 * \return - VOS_STATUS_SUCCESS: Success
13650 * VOS_STATUS_E_FAULT: Failure reported by SME
13651
13652 * --------------------------------------------------------------------------*/
13653static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
13654{
13655 eHalStatus status;
13656
13657 status = sme_InitChannels(pHddCtx->hHal);
13658 if (HAL_STATUS_SUCCESS(status))
13659 {
13660 return VOS_STATUS_SUCCESS;
13661 }
13662 else
13663 {
13664 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
13665 __func__, status);
13666 return VOS_STATUS_E_FAULT;
13667 }
13668}
13669
Mihir Shete04206452014-11-20 17:50:58 +053013670#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013671VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013672{
13673 eHalStatus status;
13674
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013675 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013676 if (HAL_STATUS_SUCCESS(status))
13677 {
13678 return VOS_STATUS_SUCCESS;
13679 }
13680 else
13681 {
13682 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
13683 __func__, status);
13684 return VOS_STATUS_E_FAULT;
13685 }
13686}
Mihir Shete04206452014-11-20 17:50:58 +053013687#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070013688/*
13689 * API to find if there is any STA or P2P-Client is connected
13690 */
13691VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
13692{
13693 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
13694}
Jeff Johnsone7245742012-09-05 17:12:55 -070013695
Mihir Shetee2ae82a2015-03-16 14:08:49 +053013696
13697/*
13698 * API to find if the firmware will send logs using DXE channel
13699 */
13700v_U8_t hdd_is_fw_logging_enabled(void)
13701{
13702 hdd_context_t *pHddCtx;
13703
13704 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
13705 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
13706
Sachin Ahuja084313e2015-05-21 17:57:10 +053013707 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053013708}
13709
Agarwal Ashish57e84372014-12-05 18:26:53 +053013710/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053013711 * API to find if the firmware will send trace logs using DXE channel
13712 */
13713v_U8_t hdd_is_fw_ev_logging_enabled(void)
13714{
13715 hdd_context_t *pHddCtx;
13716
13717 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
13718 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
13719
13720 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
13721}
13722/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053013723 * API to find if there is any session connected
13724 */
13725VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
13726{
13727 return sme_is_any_session_connected(pHddCtx->hHal);
13728}
13729
13730
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013731int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
13732{
13733 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13734 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053013735 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053013736 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013737
13738 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053013739 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013740 if (pScanInfo->mScanPending)
13741 {
c_hpothua3d45d52015-01-05 14:11:17 +053013742 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
13743 eCSR_SCAN_ABORT_DEFAULT);
13744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13745 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013746
c_hpothua3d45d52015-01-05 14:11:17 +053013747 /* If there is active scan command lets wait for the completion else
13748 * there is no need to wait as scan command might be in the SME pending
13749 * command list.
13750 */
13751 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
13752 {
c_hpothua3d45d52015-01-05 14:11:17 +053013753 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013754 &pScanInfo->abortscan_event_var,
13755 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053013756 if (0 >= status)
13757 {
13758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053013759 "%s: Timeout or Interrupt occurred while waiting for abort"
13760 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053013761 return -ETIMEDOUT;
13762 }
13763 }
13764 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
13765 {
13766 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13767 FL("hdd_abort_mac_scan failed"));
13768 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013769 }
13770 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053013771 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013772}
13773
Abhishek Singh7d624e12015-11-30 14:29:27 +053013774/**
13775 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
13776 * user space
13777 * @frame_ind: Management frame data to be informed.
13778 *
13779 * This function is used to indicate management frame to
13780 * user space
13781 *
13782 * Return: None
13783 *
13784 */
13785void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
13786{
13787 hdd_context_t *hdd_ctx = NULL;
13788 hdd_adapter_t *adapter = NULL;
13789 v_CONTEXT_t vos_context = NULL;
13790
13791 /* Get the global VOSS context.*/
13792 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13793 if (!vos_context) {
13794 hddLog(LOGE, FL("Global VOS context is Null"));
13795 return;
13796 }
13797 /* Get the HDD context.*/
13798 hdd_ctx =
13799 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
13800
13801 if (0 != wlan_hdd_validate_context(hdd_ctx))
13802 {
13803 return;
13804 }
13805 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
13806 frame_ind->sessionId);
13807
13808 if ((NULL != adapter) &&
13809 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
13810 __hdd_indicate_mgmt_frame(adapter,
13811 frame_ind->frameLen,
13812 frame_ind->frameBuf,
13813 frame_ind->frameType,
13814 frame_ind->rxChan,
13815 frame_ind->rxRssi);
13816 return;
13817
13818}
13819
c_hpothu225aa7c2014-10-22 17:45:13 +053013820VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
13821{
13822 hdd_adapter_t *pAdapter;
13823 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13824 VOS_STATUS vosStatus;
13825
13826 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13827 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
13828 {
13829 pAdapter = pAdapterNode->pAdapter;
13830 if (NULL != pAdapter)
13831 {
13832 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
13833 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
13834 WLAN_HDD_P2P_GO == pAdapter->device_mode)
13835 {
13836 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
13837 pAdapter->device_mode);
13838 if (VOS_STATUS_SUCCESS !=
13839 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
13840 {
13841 hddLog(LOGE, FL("failed to abort ROC"));
13842 return VOS_STATUS_E_FAILURE;
13843 }
13844 }
13845 }
13846 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13847 pAdapterNode = pNext;
13848 }
13849 return VOS_STATUS_SUCCESS;
13850}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053013851
Mihir Shete0be28772015-02-17 18:42:14 +053013852hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
13853{
13854 hdd_adapter_t *pAdapter;
13855 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13856 hdd_cfg80211_state_t *cfgState;
13857 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
13858 VOS_STATUS vosStatus;
13859
13860 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
13861 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
13862 {
13863 pAdapter = pAdapterNode->pAdapter;
13864 if (NULL != pAdapter)
13865 {
13866 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
13867 pRemainChanCtx = cfgState->remain_on_chan_ctx;
13868 if (pRemainChanCtx)
13869 break;
13870 }
13871 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
13872 pAdapterNode = pNext;
13873 }
13874 return pRemainChanCtx;
13875}
13876
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053013877/**
13878 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
13879 *
13880 * @pHddCtx: HDD context within host driver
13881 * @dfsScanMode: dfsScanMode passed from ioctl
13882 *
13883 */
13884
13885VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
13886 tANI_U8 dfsScanMode)
13887{
13888 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13889 hdd_adapter_t *pAdapter;
13890 VOS_STATUS vosStatus;
13891 hdd_station_ctx_t *pHddStaCtx;
13892 eHalStatus status = eHAL_STATUS_SUCCESS;
13893
13894 if(!pHddCtx)
13895 {
13896 hddLog(LOGE, FL("HDD context is Null"));
13897 return eHAL_STATUS_FAILURE;
13898 }
13899
13900 if (pHddCtx->scan_info.mScanPending)
13901 {
13902 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
13903 pHddCtx->scan_info.sessionId);
13904 hdd_abort_mac_scan(pHddCtx,
13905 pHddCtx->scan_info.sessionId,
13906 eCSR_SCAN_ABORT_DEFAULT);
13907 }
13908
13909 if (!dfsScanMode)
13910 {
13911 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
13912 while ((NULL != pAdapterNode) &&
13913 (VOS_STATUS_SUCCESS == vosStatus))
13914 {
13915 pAdapter = pAdapterNode->pAdapter;
13916
13917 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
13918 {
13919 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13920
13921 if(!pHddStaCtx)
13922 {
13923 hddLog(LOGE, FL("HDD STA context is Null"));
13924 return eHAL_STATUS_FAILURE;
13925 }
13926
13927 /* if STA is already connected on DFS channel,
13928 disconnect immediately*/
13929 if (hdd_connIsConnected(pHddStaCtx) &&
13930 (NV_CHANNEL_DFS ==
13931 vos_nv_getChannelEnabledState(
13932 pHddStaCtx->conn_info.operationChannel)))
13933 {
13934 status = sme_RoamDisconnect(pHddCtx->hHal,
13935 pAdapter->sessionId,
13936 eCSR_DISCONNECT_REASON_UNSPECIFIED);
13937 hddLog(LOG1, FL("Client connected on DFS channel %d,"
13938 "sme_RoamDisconnect returned with status: %d"
13939 "for sessionid: %d"), pHddStaCtx->conn_info.
13940 operationChannel, status, pAdapter->sessionId);
13941 }
13942 }
13943
13944 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
13945 &pNext);
13946 pAdapterNode = pNext;
13947 }
13948 }
13949
13950 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
13951 sme_UpdateDFSRoamMode(pHddCtx->hHal,
13952 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
13953
13954 status = sme_HandleDFSChanScan(pHddCtx->hHal);
13955 if (!HAL_STATUS_SUCCESS(status))
13956 {
13957 hddLog(LOGE,
13958 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
13959 return status;
13960 }
13961
13962 return status;
13963}
13964
Nirav Shah7e3c8132015-06-22 23:51:42 +053013965static int hdd_log2_ceil(unsigned value)
13966{
13967 /* need to switch to unsigned math so that negative values
13968 * will right-shift towards 0 instead of -1
13969 */
13970 unsigned tmp = value;
13971 int log2 = -1;
13972
13973 if (value == 0)
13974 return 0;
13975
13976 while (tmp) {
13977 log2++;
13978 tmp >>= 1;
13979 }
13980 if (1U << log2 != value)
13981 log2++;
13982
13983 return log2;
13984}
13985
13986/**
13987 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
13988 * @pAdapter: adapter handle
13989 *
13990 * Return: vos status
13991 */
13992VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
13993{
13994 int hash_elem, log2, i;
13995
13996 spin_lock_bh( &pAdapter->sta_hash_lock);
13997 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
13998 spin_unlock_bh( &pAdapter->sta_hash_lock);
13999 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14000 "%s: hash already attached for session id %d",
14001 __func__, pAdapter->sessionId);
14002 return VOS_STATUS_SUCCESS;
14003 }
14004 spin_unlock_bh( &pAdapter->sta_hash_lock);
14005
14006 hash_elem = WLAN_MAX_STA_COUNT;
14007 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
14008 log2 = hdd_log2_ceil(hash_elem);
14009 hash_elem = 1 << log2;
14010
14011 pAdapter->sta_id_hash.mask = hash_elem - 1;
14012 pAdapter->sta_id_hash.idx_bits = log2;
14013 pAdapter->sta_id_hash.bins =
14014 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
14015 if (!pAdapter->sta_id_hash.bins) {
14016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14017 "%s: malloc failed for session %d",
14018 __func__, pAdapter->sessionId);
14019 return VOS_STATUS_E_NOMEM;
14020 }
14021
14022 for (i = 0; i < hash_elem; i++)
14023 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
14024
14025 spin_lock_bh( &pAdapter->sta_hash_lock);
14026 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
14027 spin_unlock_bh( &pAdapter->sta_hash_lock);
14028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14029 "%s: Station ID Hash attached for session id %d",
14030 __func__, pAdapter->sessionId);
14031
14032 return VOS_STATUS_SUCCESS;
14033}
14034
14035/**
14036 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
14037 * @pAdapter: adapter handle
14038 *
14039 * Return: vos status
14040 */
14041VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
14042{
14043 int hash_elem, i;
14044 v_SIZE_t size;
14045
14046 spin_lock_bh( &pAdapter->sta_hash_lock);
14047 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14048 spin_unlock_bh( &pAdapter->sta_hash_lock);
14049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14050 "%s: hash not initialized for session id %d",
14051 __func__, pAdapter->sessionId);
14052 return VOS_STATUS_SUCCESS;
14053 }
14054
14055 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
14056 spin_unlock_bh( &pAdapter->sta_hash_lock);
14057
14058 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
14059
14060 /* free all station info*/
14061 for (i = 0; i < hash_elem; i++) {
14062 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
14063 if (size != 0) {
14064 VOS_STATUS status;
14065 hdd_staid_hash_node_t *sta_info_node = NULL;
14066 hdd_staid_hash_node_t *next_node = NULL;
14067 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
14068 (hdd_list_node_t**) &sta_info_node );
14069
14070 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14071 {
14072 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
14073 &sta_info_node->node);
14074 vos_mem_free(sta_info_node);
14075
14076 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
14077 (hdd_list_node_t*)sta_info_node,
14078 (hdd_list_node_t**)&next_node);
14079 sta_info_node = next_node;
14080 }
14081 }
14082 }
14083
14084 vos_mem_free(pAdapter->sta_id_hash.bins);
14085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14086 "%s: Station ID Hash detached for session id %d",
14087 __func__, pAdapter->sessionId);
14088 return VOS_STATUS_SUCCESS;
14089}
14090
14091/**
14092 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
14093 * @pAdapter: adapter handle
14094 * @mac_addr_in: input mac address
14095 *
14096 * Return: index derived from mac address
14097 */
14098int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
14099 v_MACADDR_t *mac_addr_in)
14100{
14101 uint16 index;
14102 struct hdd_align_mac_addr_t * mac_addr =
14103 (struct hdd_align_mac_addr_t *)mac_addr_in;
14104
14105 index = mac_addr->bytes_ab ^
14106 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
14107 index ^= index >> pAdapter->sta_id_hash.idx_bits;
14108 index &= pAdapter->sta_id_hash.mask;
14109 return index;
14110}
14111
14112/**
14113 * hdd_sta_id_hash_add_entry() - add entry in hash
14114 * @pAdapter: adapter handle
14115 * @sta_id: station id
14116 * @mac_addr: mac address
14117 *
14118 * Return: vos status
14119 */
14120VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
14121 v_U8_t sta_id, v_MACADDR_t *mac_addr)
14122{
14123 uint16 index;
14124 hdd_staid_hash_node_t *sta_info_node = NULL;
14125
Nirav Shah7e3c8132015-06-22 23:51:42 +053014126 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
14127 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
14128 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053014129 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14130 "%s: malloc failed", __func__);
14131 return VOS_STATUS_E_NOMEM;
14132 }
14133
14134 sta_info_node->sta_id = sta_id;
14135 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
14136
Nirav Shah303ed5c2015-08-24 10:29:25 +053014137 spin_lock_bh( &pAdapter->sta_hash_lock);
14138 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14139 spin_unlock_bh( &pAdapter->sta_hash_lock);
14140 vos_mem_free(sta_info_node);
14141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14142 "%s: hash is not initialized for session id %d",
14143 __func__, pAdapter->sessionId);
14144 return VOS_STATUS_E_FAILURE;
14145 }
14146
Nirav Shah7e3c8132015-06-22 23:51:42 +053014147 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
14148 (hdd_list_node_t*) sta_info_node );
14149 spin_unlock_bh( &pAdapter->sta_hash_lock);
14150 return VOS_STATUS_SUCCESS;
14151}
14152
14153/**
14154 * hdd_sta_id_hash_remove_entry() - remove entry from hash
14155 * @pAdapter: adapter handle
14156 * @sta_id: station id
14157 * @mac_addr: mac address
14158 *
14159 * Return: vos status
14160 */
14161VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
14162 v_U8_t sta_id, v_MACADDR_t *mac_addr)
14163{
14164 uint16 index;
14165 VOS_STATUS status;
14166 hdd_staid_hash_node_t *sta_info_node = NULL;
14167 hdd_staid_hash_node_t *next_node = NULL;
14168
14169 spin_lock_bh( &pAdapter->sta_hash_lock);
14170 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14171 spin_unlock_bh( &pAdapter->sta_hash_lock);
14172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14173 "%s: hash is not initialized for session id %d",
14174 __func__, pAdapter->sessionId);
14175 return VOS_STATUS_E_FAILURE;
14176 }
14177
14178 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
14179 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
14180 (hdd_list_node_t**) &sta_info_node );
14181
14182 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14183 {
14184 if (sta_info_node->sta_id == sta_id) {
14185 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
14186 &sta_info_node->node);
14187 vos_mem_free(sta_info_node);
14188 break;
14189 }
14190 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
14191 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
14192 sta_info_node = next_node;
14193 }
14194 spin_unlock_bh( &pAdapter->sta_hash_lock);
14195 return status;
14196}
14197
14198/**
14199 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
14200 * @pAdapter: adapter handle
14201 * @mac_addr_in: mac address
14202 *
14203 * Return: station id
14204 */
14205int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
14206 v_MACADDR_t *mac_addr_in)
14207{
14208 uint8 is_found = 0;
14209 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
14210 uint16 index;
14211 VOS_STATUS status;
14212 hdd_staid_hash_node_t *sta_info_node = NULL;
14213 hdd_staid_hash_node_t *next_node = NULL;
14214
14215 spin_lock_bh( &pAdapter->sta_hash_lock);
14216 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14217 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053014218 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053014219 FL("hash is not initialized for session id %d"),
14220 pAdapter->sessionId);
14221 return HDD_WLAN_INVALID_STA_ID;
14222 }
14223
14224 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
14225 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
14226 (hdd_list_node_t**) &sta_info_node );
14227
14228 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14229 {
14230 if (vos_mem_compare(&sta_info_node->mac_addr,
14231 mac_addr_in, sizeof(v_MACADDR_t))) {
14232 is_found = 1;
14233 sta_id = sta_info_node->sta_id;
14234 break;
14235 }
14236 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
14237 (hdd_list_node_t*)sta_info_node,
14238 (hdd_list_node_t**)&next_node);
14239 sta_info_node = next_node;
14240 }
14241 spin_unlock_bh( &pAdapter->sta_hash_lock);
14242 return sta_id;
14243}
14244
c_manjeecfd1efb2015-09-25 19:32:34 +053014245/*FW memory dump feature*/
14246/**
14247 * This structure hold information about the /proc file
14248 *
14249 */
14250static struct proc_dir_entry *proc_file, *proc_dir;
14251
14252/**
14253 * memdump_read() - perform read operation in memory dump proc file
14254 *
14255 * @file - handle for the proc file.
14256 * @buf - pointer to user space buffer.
14257 * @count - number of bytes to be read.
14258 * @pos - offset in the from buffer.
14259 *
14260 * This function performs read operation for the memory dump proc file.
14261 *
14262 * Return: number of bytes read on success, error code otherwise.
14263 */
14264static ssize_t memdump_read(struct file *file, char __user *buf,
14265 size_t count, loff_t *pos)
14266{
14267 int status;
14268 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
14269 size_t ret_count;
c_manjeef1495642015-10-13 18:35:01 +053014270 loff_t bytes_left;
c_manjeecfd1efb2015-09-25 19:32:34 +053014271 ENTER();
14272
14273 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
14274 status = wlan_hdd_validate_context(hdd_ctx);
14275 if (0 != status) {
14276 return -EINVAL;
14277 }
14278
14279 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
14280 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
14281 return -EINVAL;
14282 }
14283
14284 /* run fs_read_handler in an atomic context*/
14285 vos_ssr_protect(__func__);
c_manjeef1495642015-10-13 18:35:01 +053014286 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left);
14287 if(bytes_left == 0)
c_manjeecfd1efb2015-09-25 19:32:34 +053014288 {
14289 /*Free the fwr mem dump buffer */
14290 wlan_free_fwr_mem_dump_buffer();
14291 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeef1495642015-10-13 18:35:01 +053014292 ret_count=0;
c_manjeecfd1efb2015-09-25 19:32:34 +053014293 }
14294 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
14295 vos_ssr_unprotect(__func__);
14296 EXIT();
14297 return ret_count;
14298}
14299
14300/**
14301 * struct memdump_fops - file operations for memory dump feature
14302 * @read - read function for memory dump operation.
14303 *
14304 * This structure initialize the file operation handle for memory
14305 * dump feature
14306 */
14307static const struct file_operations memdump_fops = {
14308 read: memdump_read
14309};
14310
14311/*
14312* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
14313* To be passed by HDD to WDA and called upon receiving of response
14314* from firmware
14315* @fwMemDumpReqContext : memory dump request context
14316* @dump_rsp : dump response from HAL
14317* Returns none
14318*/
14319void wlan_hdd_fw_mem_dump_cb(void *fwMemDumpReqContext,
14320 tAniFwrDumpRsp *dump_rsp)
14321{
c_manjeef1495642015-10-13 18:35:01 +053014322 struct hdd_fw_mem_dump_req_ctx *pHddFwMemDumpCtx = (struct hdd_fw_mem_dump_req_ctx *)fwMemDumpReqContext;
c_manjeecfd1efb2015-09-25 19:32:34 +053014323
c_manjeef1495642015-10-13 18:35:01 +053014324 ENTER();
14325 spin_lock(&hdd_context_lock);
14326 if(!pHddFwMemDumpCtx || (FW_MEM_DUMP_MAGIC != pHddFwMemDumpCtx->magic)) {
14327 spin_unlock(&hdd_context_lock);
14328 return;
14329 }
14330 /* report the status to requesting function and free mem.*/
c_manjeecfd1efb2015-09-25 19:32:34 +053014331 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
c_manjeef1495642015-10-13 18:35:01 +053014332 hddLog(LOGE, FL("fw dump request declined by fwr"));
14333 //set the request completion variable
14334 complete(&(pHddFwMemDumpCtx->req_completion));
c_manjeecfd1efb2015-09-25 19:32:34 +053014335 //Free the allocated fwr dump
14336 wlan_free_fwr_mem_dump_buffer();
14337 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeecfd1efb2015-09-25 19:32:34 +053014338 }
c_manjeef1495642015-10-13 18:35:01 +053014339 else {
14340 hddLog(LOG1, FL("fw dump request accepted by fwr"));
14341 /* register the HDD callback which will be called by SVC */
14342 wlan_set_svc_fw_mem_dump_req_cb((void*)wlan_hdd_fw_mem_dump_req_cb,(void*)pHddFwMemDumpCtx);
14343 }
14344 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014345 EXIT();
14346
14347}
14348
14349/**
14350 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
14351 *
14352 * This function removes file/dir under proc file system that was
14353 * processing firmware memory dump
14354 *
14355 * Return: None
14356 */
14357static void memdump_procfs_remove(void)
14358{
14359 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
14360 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
14361 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
14362 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
14363 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
14364}
14365
14366/**
14367 * memdump_procfs_init() - Initialize procfs for memory dump
14368 *
14369 * @vos_ctx - Global vos context.
14370 *
14371 * This function create file under proc file system to be used later for
14372 * processing firmware memory dump
14373 *
14374 * Return: 0 on success, error code otherwise.
14375 */
14376static int memdump_procfs_init(void *vos_ctx)
14377{
14378 hdd_context_t *hdd_ctx;
14379
14380 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14381 if (!hdd_ctx) {
14382 hddLog(LOGE , FL("Invalid HDD context"));
14383 return -EINVAL;
14384 }
14385
14386 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
14387 if (proc_dir == NULL) {
14388 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
14389 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
14390 PROCFS_MEMDUMP_DIR);
14391 return -ENOMEM;
14392 }
14393
14394 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
14395 S_IRUSR | S_IWUSR, proc_dir,
14396 &memdump_fops, hdd_ctx);
14397 if (proc_file == NULL) {
14398 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
14399 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
14400 PROCFS_MEMDUMP_NAME);
14401 return -ENOMEM;
14402 }
14403
14404 hddLog(LOG1 , FL("/proc/%s/%s created"),
14405 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
14406
14407 return 0;
14408}
14409
14410/**
14411 * memdump_init() - Initialization function for memory dump feature
14412 *
14413 * This function creates proc file for memdump feature and registers
14414 * HDD callback function with SME.
14415 *
14416 * Return - 0 on success, error otherwise
14417 */
14418int memdump_init(void)
14419{
14420 hdd_context_t *hdd_ctx;
14421 void *vos_ctx;
14422 int status = 0;
14423
14424 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14425 if (!vos_ctx) {
14426 hddLog(LOGE, FL("Invalid VOS context"));
14427 return -EINVAL;
14428 }
14429
14430 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14431 if (!hdd_ctx) {
14432 hddLog(LOGE , FL("Invalid HDD context"));
14433 return -EINVAL;
14434 }
14435
14436 status = memdump_procfs_init(vos_ctx);
14437 if (status) {
14438 hddLog(LOGE , FL("Failed to create proc file"));
14439 return status;
14440 }
14441
14442 return 0;
14443}
14444
14445/**
14446 * memdump_deinit() - De initialize memdump feature
14447 *
14448 * This function removes proc file created for memdump feature.
14449 *
14450 * Return: None
14451 */
14452int memdump_deinit(void)
14453{
14454 hdd_context_t *hdd_ctx;
14455 void *vos_ctx;
14456
14457 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14458 if (!vos_ctx) {
14459 hddLog(LOGE, FL("Invalid VOS context"));
14460 return -EINVAL;
14461 }
14462
14463 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14464 if(!hdd_ctx) {
14465 hddLog(LOGE , FL("Invalid HDD context"));
14466 return -EINVAL;
14467 }
14468
14469 memdump_procfs_remove();
14470 return 0;
14471}
14472
14473/**
14474 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
14475 * Return: HAL status
14476 */
14477
14478int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
14479{
14480 tAniFwrDumpReq fw_mem_dump_req={0};
c_manjeef1495642015-10-13 18:35:01 +053014481 struct hdd_fw_mem_dump_req_ctx fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053014482 eHalStatus status = eHAL_STATUS_FAILURE;
Abhishek Singh4eca9822015-12-09 18:07:34 +053014483 int ret=0, result;
c_manjeecfd1efb2015-09-25 19:32:34 +053014484 ENTER();
c_manjeef1495642015-10-13 18:35:01 +053014485
c_manjeecfd1efb2015-09-25 19:32:34 +053014486 /*Check whether a dump request is already going on
14487 *Caution this function will free previously held memory if new dump request is allowed*/
14488 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
14489 hddLog(LOGE, FL("Fw memdump already in progress"));
14490 return -EBUSY;
14491 }
14492 //Allocate memory for fw mem dump buffer
14493 ret = wlan_fwr_mem_dump_buffer_allocation();
14494 if(ret == -EFAULT)
14495 {
14496 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
14497 return ret;
14498 }
14499 if (0 != ret) {
14500 hddLog(LOGE, FL("Fwr mem Allocation failed"));
14501 return -ENOMEM;
14502 }
c_manjeef1495642015-10-13 18:35:01 +053014503 init_completion(&fw_mem_dump_ctx.req_completion);
14504 fw_mem_dump_ctx.magic = FW_MEM_DUMP_MAGIC;
14505 fw_mem_dump_ctx.status = false;
14506
c_manjeecfd1efb2015-09-25 19:32:34 +053014507 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
c_manjeef1495642015-10-13 18:35:01 +053014508 fw_mem_dump_req.fwMemDumpReqContext = &fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053014509 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
14510 if(eHAL_STATUS_SUCCESS != status)
14511 {
14512 hddLog(VOS_TRACE_LEVEL_ERROR,
14513 "%s: fw_mem_dump_req failed ", __func__);
14514 wlan_free_fwr_mem_dump_buffer();
c_manjeef1495642015-10-13 18:35:01 +053014515 ret = -EFAULT;
14516 goto cleanup;
c_manjeecfd1efb2015-09-25 19:32:34 +053014517 }
c_manjeef1495642015-10-13 18:35:01 +053014518 /*wait for fw mem dump completion to send event to userspace*/
Abhishek Singh4eca9822015-12-09 18:07:34 +053014519 result =
14520 wait_for_completion_timeout(&fw_mem_dump_ctx.req_completion,
14521 msecs_to_jiffies(FW_MEM_DUMP_TIMEOUT_MS));
14522 if (0 >= result )
c_manjeef1495642015-10-13 18:35:01 +053014523 {
14524 hddLog(VOS_TRACE_LEVEL_ERROR,
Abhishek Singh4eca9822015-12-09 18:07:34 +053014525 "%s: fw_mem_dump_req timeout %d ", __func__,result);
14526 ret = -ETIMEDOUT;
c_manjeef1495642015-10-13 18:35:01 +053014527 }
14528cleanup:
14529 spin_lock(&hdd_context_lock);
14530 fw_mem_dump_ctx.magic = 0;
Abhishek Singh4eca9822015-12-09 18:07:34 +053014531 if(!ret && !fw_mem_dump_ctx.status)
14532 ret = -EFAULT;
c_manjeef1495642015-10-13 18:35:01 +053014533 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014534
c_manjeef1495642015-10-13 18:35:01 +053014535 EXIT();
Abhishek Singh4eca9822015-12-09 18:07:34 +053014536 return ret;
c_manjeef1495642015-10-13 18:35:01 +053014537}
14538
14539/**
14540 * HDD callback which will be called by SVC to indicate mem dump completion.
14541 */
14542void wlan_hdd_fw_mem_dump_req_cb(struct hdd_fw_mem_dump_req_ctx* pHddFwMemDumpCtx)
14543{
14544 if (!pHddFwMemDumpCtx) {
14545 hddLog(VOS_TRACE_LEVEL_ERROR,
14546 "%s: HDD context not valid ", __func__);
14547 return;
14548 }
14549 spin_lock(&hdd_context_lock);
14550 /* check the req magic and set status */
14551 if (pHddFwMemDumpCtx->magic == FW_MEM_DUMP_MAGIC)
14552 {
14553 pHddFwMemDumpCtx->status = true;
14554 //signal the completion
14555 complete(&(pHddFwMemDumpCtx->req_completion));
14556 }
14557 else
14558 {
14559 hddLog(VOS_TRACE_LEVEL_ERROR,
14560 "%s: fw mem dump request possible timeout ", __func__);
14561 }
14562 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014563}
14564
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053014565void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
14566{
14567 if (NULL == pAdapter)
14568 {
14569 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
14570 return;
14571 }
14572 init_completion(&pAdapter->session_open_comp_var);
14573 init_completion(&pAdapter->session_close_comp_var);
14574 init_completion(&pAdapter->disconnect_comp_var);
14575 init_completion(&pAdapter->linkup_event_var);
14576 init_completion(&pAdapter->cancel_rem_on_chan_var);
14577 init_completion(&pAdapter->rem_on_chan_ready_event);
14578 init_completion(&pAdapter->pno_comp_var);
14579#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14580 init_completion(&pAdapter->offchannel_tx_event);
14581#endif
14582 init_completion(&pAdapter->tx_action_cnf_event);
14583#ifdef FEATURE_WLAN_TDLS
14584 init_completion(&pAdapter->tdls_add_station_comp);
14585 init_completion(&pAdapter->tdls_del_station_comp);
14586 init_completion(&pAdapter->tdls_mgmt_comp);
14587 init_completion(&pAdapter->tdls_link_establish_req_comp);
14588#endif
14589
14590#ifdef WLAN_FEATURE_RMC
14591 init_completion(&pAdapter->ibss_peer_info_comp);
14592#endif /* WLAN_FEATURE_RMC */
14593 init_completion(&pAdapter->ula_complete);
14594 init_completion(&pAdapter->change_country_code);
14595
14596#ifdef FEATURE_WLAN_BATCH_SCAN
14597 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
14598 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
14599#endif
14600
14601 return;
14602}
c_manjeecfd1efb2015-09-25 19:32:34 +053014603
14604
Jeff Johnson295189b2012-06-20 16:38:30 -070014605//Register the module init/exit functions
14606module_init(hdd_module_init);
14607module_exit(hdd_module_exit);
14608
14609MODULE_LICENSE("Dual BSD/GPL");
14610MODULE_AUTHOR("Qualcomm Atheros, Inc.");
14611MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
14612
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014613module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
14614 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070014615
Jeff Johnson76052702013-04-16 13:55:05 -070014616module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070014617 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080014618
14619module_param(enable_dfs_chan_scan, int,
14620 S_IRUSR | S_IRGRP | S_IROTH);
14621
14622module_param(enable_11d, int,
14623 S_IRUSR | S_IRGRP | S_IROTH);
14624
14625module_param(country_code, charp,
14626 S_IRUSR | S_IRGRP | S_IROTH);