blob: 92c71558d69acf5f40bec89e7dae2e4904b47fb0 [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);
Jeff Johnson295189b2012-06-20 16:38:30 -07008225 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07008226 break;
8227 }
8228
8229 case WLAN_HDD_MONITOR:
8230 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008231 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8232 {
8233 hdd_deinit_tx_rx( pAdapter );
8234 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8235 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008236 break;
8237 }
8238
8239
8240 default:
8241 break;
8242 }
8243
8244 EXIT();
8245}
8246
8247void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
8248{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008249 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308250
8251 ENTER();
8252 if (NULL == pAdapter)
8253 {
8254 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8255 "%s: HDD adapter is Null", __func__);
8256 return;
8257 }
8258
8259 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07008260
Rajeev79dbe4c2013-10-05 11:03:42 +05308261#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308262 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8263 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08008264 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308265 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
8266 )
8267 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08008268 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05308269 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08008270 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
8271 {
8272 hdd_deinit_batch_scan(pAdapter);
8273 }
Rajeev79dbe4c2013-10-05 11:03:42 +05308274 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08008275 }
Rajeev79dbe4c2013-10-05 11:03:42 +05308276#endif
8277
Jeff Johnson295189b2012-06-20 16:38:30 -07008278 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
8279 if( rtnl_held )
8280 {
8281 unregister_netdevice(pWlanDev);
8282 }
8283 else
8284 {
8285 unregister_netdev(pWlanDev);
8286 }
8287 // note that the pAdapter is no longer valid at this point
8288 // since the memory has been reclaimed
8289 }
8290
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308291 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008292}
8293
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008294void hdd_set_pwrparams(hdd_context_t *pHddCtx)
8295{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308296 VOS_STATUS status;
8297 hdd_adapter_t *pAdapter = NULL;
8298 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008299
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308300 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008301
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308302 /*loop through all adapters.*/
8303 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008304 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308305 pAdapter = pAdapterNode->pAdapter;
8306 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
8307 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008308
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308309 { // we skip this registration for modes other than STA and P2P client modes.
8310 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8311 pAdapterNode = pNext;
8312 continue;
8313 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008314
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308315 //Apply Dynamic DTIM For P2P
8316 //Only if ignoreDynamicDtimInP2pMode is not set in ini
8317 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
8318 pHddCtx->cfg_ini->enableModulatedDTIM) &&
8319 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8320 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
8321 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
8322 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
8323 (eConnectionState_Associated ==
8324 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
8325 (pHddCtx->cfg_ini->fIsBmpsEnabled))
8326 {
8327 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008328
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308329 powerRequest.uIgnoreDTIM = 1;
8330 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
8331
8332 if (pHddCtx->cfg_ini->enableModulatedDTIM)
8333 {
8334 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
8335 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
8336 }
8337 else
8338 {
8339 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
8340 }
8341
8342 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
8343 * specified during Enter/Exit BMPS when LCD off*/
8344 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
8345 NULL, eANI_BOOLEAN_FALSE);
8346 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
8347 NULL, eANI_BOOLEAN_FALSE);
8348
8349 /* switch to the DTIM specified in cfg.ini */
8350 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05308351 "Switch to DTIM %d Listen interval %d",
8352 powerRequest.uDTIMPeriod,
8353 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308354 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
8355 break;
8356
8357 }
8358
8359 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8360 pAdapterNode = pNext;
8361 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008362}
8363
8364void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
8365{
8366 /*Switch back to DTIM 1*/
8367 tSirSetPowerParamsReq powerRequest = { 0 };
8368
8369 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
8370 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07008371 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008372
8373 /* Update ignoreDTIM and ListedInterval in CFG with default values */
8374 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
8375 NULL, eANI_BOOLEAN_FALSE);
8376 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
8377 NULL, eANI_BOOLEAN_FALSE);
8378
8379 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8380 "Switch to DTIM%d",powerRequest.uListenInterval);
8381 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
8382
8383}
8384
Jeff Johnson295189b2012-06-20 16:38:30 -07008385VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
8386{
8387 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05308388 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
8389 {
8390 hddLog( LOGE, FL("Wlan Unload in progress"));
8391 return VOS_STATUS_E_PERM;
8392 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008393 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
8394 {
8395 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8396 }
8397
8398 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
8399 {
8400 sme_StartAutoBmpsTimer(pHddCtx->hHal);
8401 }
8402
8403 if (pHddCtx->cfg_ini->fIsImpsEnabled)
8404 {
8405 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8406 }
8407
8408 return status;
8409}
8410
8411VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
8412{
8413 hdd_adapter_t *pAdapter = NULL;
8414 eHalStatus halStatus;
8415 VOS_STATUS status = VOS_STATUS_E_INVAL;
8416 v_BOOL_t disableBmps = FALSE;
8417 v_BOOL_t disableImps = FALSE;
8418
8419 switch(session_type)
8420 {
8421 case WLAN_HDD_INFRA_STATION:
8422 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008423 case WLAN_HDD_P2P_CLIENT:
8424 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008425 //Exit BMPS -> Is Sta/P2P Client is already connected
8426 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
8427 if((NULL != pAdapter)&&
8428 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8429 {
8430 disableBmps = TRUE;
8431 }
8432
8433 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
8434 if((NULL != pAdapter)&&
8435 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8436 {
8437 disableBmps = TRUE;
8438 }
8439
8440 //Exit both Bmps and Imps incase of Go/SAP Mode
8441 if((WLAN_HDD_SOFTAP == session_type) ||
8442 (WLAN_HDD_P2P_GO == session_type))
8443 {
8444 disableBmps = TRUE;
8445 disableImps = TRUE;
8446 }
8447
8448 if(TRUE == disableImps)
8449 {
8450 if (pHddCtx->cfg_ini->fIsImpsEnabled)
8451 {
8452 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8453 }
8454 }
8455
8456 if(TRUE == disableBmps)
8457 {
8458 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
8459 {
8460 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8461
8462 if(eHAL_STATUS_SUCCESS != halStatus)
8463 {
8464 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008465 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008466 VOS_ASSERT(0);
8467 return status;
8468 }
8469 }
8470
8471 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
8472 {
8473 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
8474
8475 if(eHAL_STATUS_SUCCESS != halStatus)
8476 {
8477 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008478 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008479 VOS_ASSERT(0);
8480 return status;
8481 }
8482 }
8483 }
8484
8485 if((TRUE == disableBmps) ||
8486 (TRUE == disableImps))
8487 {
8488 /* Now, get the chip into Full Power now */
8489 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
8490 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
8491 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
8492
8493 if(halStatus != eHAL_STATUS_SUCCESS)
8494 {
8495 if(halStatus == eHAL_STATUS_PMC_PENDING)
8496 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308497 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008498 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308499 ret = wait_for_completion_interruptible_timeout(
8500 &pHddCtx->full_pwr_comp_var,
8501 msecs_to_jiffies(1000));
8502 if (ret <= 0)
8503 {
8504 hddLog(VOS_TRACE_LEVEL_ERROR,
8505 "%s: wait on full_pwr_comp_var failed %ld",
8506 __func__, ret);
8507 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008508 }
8509 else
8510 {
8511 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008512 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008513 VOS_ASSERT(0);
8514 return status;
8515 }
8516 }
8517
8518 status = VOS_STATUS_SUCCESS;
8519 }
8520
8521 break;
8522 }
8523 return status;
8524}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308525
8526void hdd_monPostMsgCb(tANI_U32 *magic, struct completion *cmpVar)
8527{
8528 if (magic == NULL || cmpVar == NULL) {
8529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8530 FL("invalid arguments %p %p"), magic, cmpVar);
8531 return;
8532 }
8533 if (*magic != MON_MODE_MSG_MAGIC) {
8534 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8535 FL("maic: %x"), *magic);
8536 return;
8537 }
8538
8539 complete(cmpVar);
8540 return;
8541}
8542
Katya Nigame7b69a82015-04-28 15:24:06 +05308543void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
8544 {
8545 hdd_mon_ctx_t *pMonCtx = NULL;
8546 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
8547
8548 pMonCtx->state = 0;
8549 pMonCtx->ChannelNo = 1;
8550 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05308551 pMonCtx->crcCheckEnabled = 1;
8552 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
8553 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05308554 pMonCtx->numOfMacFilters = 0;
8555 }
8556
Jeff Johnson295189b2012-06-20 16:38:30 -07008557
8558hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08008559 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07008560 tANI_U8 rtnl_held )
8561{
8562 hdd_adapter_t *pAdapter = NULL;
8563 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
8564 VOS_STATUS status = VOS_STATUS_E_FAILURE;
8565 VOS_STATUS exitbmpsStatus;
8566
Arif Hussain6d2a3322013-11-17 19:50:10 -08008567 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008568
Nirav Shah436658f2014-02-28 17:05:45 +05308569 if(macAddr == NULL)
8570 {
8571 /* Not received valid macAddr */
8572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8573 "%s:Unable to add virtual intf: Not able to get"
8574 "valid mac address",__func__);
8575 return NULL;
8576 }
8577
Jeff Johnson295189b2012-06-20 16:38:30 -07008578 //Disable BMPS incase of Concurrency
8579 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
8580
8581 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
8582 {
8583 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308584 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008585 VOS_ASSERT(0);
8586 return NULL;
8587 }
8588
8589 switch(session_type)
8590 {
8591 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008592 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07008593 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07008594 {
8595 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8596
8597 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308598 {
8599 hddLog(VOS_TRACE_LEVEL_FATAL,
8600 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008601 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308602 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008603
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308604#ifdef FEATURE_WLAN_TDLS
8605 /* A Mutex Lock is introduced while changing/initializing the mode to
8606 * protect the concurrent access for the Adapters by TDLS module.
8607 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308608 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308609#endif
8610
Jeff Johnsone7245742012-09-05 17:12:55 -07008611 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
8612 NL80211_IFTYPE_P2P_CLIENT:
8613 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07008614
Jeff Johnson295189b2012-06-20 16:38:30 -07008615 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308616#ifdef FEATURE_WLAN_TDLS
8617 mutex_unlock(&pHddCtx->tdls_lock);
8618#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308619
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308620 hdd_initialize_adapter_common(pAdapter);
Sunil Dutt66485cb2013-12-19 19:05:03 +05308621 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008622 if( VOS_STATUS_SUCCESS != status )
8623 goto err_free_netdev;
8624
8625 status = hdd_register_interface( pAdapter, rtnl_held );
8626 if( VOS_STATUS_SUCCESS != status )
8627 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308628#ifdef FEATURE_WLAN_TDLS
8629 mutex_lock(&pHddCtx->tdls_lock);
8630#endif
c_hpothu002231a2015-02-05 14:58:51 +05308631 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308632#ifdef FEATURE_WLAN_TDLS
8633 mutex_unlock(&pHddCtx->tdls_lock);
8634#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008635 goto err_free_netdev;
8636 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308637
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05308638 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308639 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05308640
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308641#ifdef WLAN_NS_OFFLOAD
8642 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308643 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308644#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008645 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308646 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008647 netif_tx_disable(pAdapter->dev);
8648 //netif_tx_disable(pWlanDev);
8649 netif_carrier_off(pAdapter->dev);
8650
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308651 if (WLAN_HDD_P2P_CLIENT == session_type ||
8652 WLAN_HDD_P2P_DEVICE == session_type)
8653 {
8654 /* Initialize the work queue to defer the
8655 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308656 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308657 hdd_p2p_roc_work_queue);
8658 }
8659
Jeff Johnson295189b2012-06-20 16:38:30 -07008660 break;
8661 }
8662
Jeff Johnson295189b2012-06-20 16:38:30 -07008663 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008664 case WLAN_HDD_SOFTAP:
8665 {
8666 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
8667 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308668 {
8669 hddLog(VOS_TRACE_LEVEL_FATAL,
8670 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008671 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308672 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008673
Jeff Johnson295189b2012-06-20 16:38:30 -07008674 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
8675 NL80211_IFTYPE_AP:
8676 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008677 pAdapter->device_mode = session_type;
8678
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308679 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008680 status = hdd_init_ap_mode(pAdapter);
8681 if( VOS_STATUS_SUCCESS != status )
8682 goto err_free_netdev;
8683
Nirav Shah7e3c8132015-06-22 23:51:42 +05308684 status = hdd_sta_id_hash_attach(pAdapter);
8685 if (VOS_STATUS_SUCCESS != status)
8686 {
8687 hddLog(VOS_TRACE_LEVEL_FATAL,
8688 FL("failed to attach hash for session %d"), session_type);
8689 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
8690 goto err_free_netdev;
8691 }
8692
Jeff Johnson295189b2012-06-20 16:38:30 -07008693 status = hdd_register_hostapd( pAdapter, rtnl_held );
8694 if( VOS_STATUS_SUCCESS != status )
8695 {
c_hpothu002231a2015-02-05 14:58:51 +05308696 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07008697 goto err_free_netdev;
8698 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308699 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008700 netif_tx_disable(pAdapter->dev);
8701 netif_carrier_off(pAdapter->dev);
8702
8703 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308704
8705 if (WLAN_HDD_P2P_GO == session_type)
8706 {
8707 /* Initialize the work queue to
8708 * defer the back to back RoC request */
8709 INIT_DELAYED_WORK(&pAdapter->roc_work,
8710 hdd_p2p_roc_work_queue);
8711 }
Bhargav Shahd0715912015-10-01 18:17:37 +05308712
Jeff Johnson295189b2012-06-20 16:38:30 -07008713 break;
8714 }
8715 case WLAN_HDD_MONITOR:
8716 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008717 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8718 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308719 {
8720 hddLog(VOS_TRACE_LEVEL_FATAL,
8721 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008722 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308723 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008724
Katya Nigame7b69a82015-04-28 15:24:06 +05308725 // Register wireless extensions
8726 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
8727 {
8728 hddLog(VOS_TRACE_LEVEL_FATAL,
8729 "hdd_register_wext() failed with status code %08d [x%08x]",
8730 status, status );
8731 status = VOS_STATUS_E_FAILURE;
8732 }
8733
Jeff Johnson295189b2012-06-20 16:38:30 -07008734 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
8735 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008736#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
8737 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
8738#else
8739 pAdapter->dev->open = hdd_mon_open;
8740 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05308741 pAdapter->dev->stop = hdd_mon_stop;
8742 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07008743#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05308744 status = hdd_register_interface( pAdapter, rtnl_held );
8745 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308746 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008747 hdd_init_tx_rx( pAdapter );
8748 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05308749 //Stop the Interface TX queue.
8750 netif_tx_disable(pAdapter->dev);
8751 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008752 }
8753 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07008754 case WLAN_HDD_FTM:
8755 {
8756 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8757
8758 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308759 {
8760 hddLog(VOS_TRACE_LEVEL_FATAL,
8761 FL("failed to allocate adapter for session %d"), session_type);
8762 return NULL;
8763 }
8764
Jeff Johnson295189b2012-06-20 16:38:30 -07008765 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
8766 * message while loading driver in FTM mode. */
8767 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
8768 pAdapter->device_mode = session_type;
8769 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05308770
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308771 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05308772 hdd_init_tx_rx( pAdapter );
8773
8774 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308775 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05308776 netif_tx_disable(pAdapter->dev);
8777 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008778 }
8779 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07008780 default:
8781 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308782 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
8783 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008784 VOS_ASSERT(0);
8785 return NULL;
8786 }
8787 }
8788
Jeff Johnson295189b2012-06-20 16:38:30 -07008789 if( VOS_STATUS_SUCCESS == status )
8790 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308791 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -07008792 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
8793 if( NULL == pHddAdapterNode )
8794 {
8795 status = VOS_STATUS_E_NOMEM;
8796 }
8797 else
8798 {
8799 pHddAdapterNode->pAdapter = pAdapter;
8800 status = hdd_add_adapter_back ( pHddCtx,
8801 pHddAdapterNode );
8802 }
8803 }
8804
8805 if( VOS_STATUS_SUCCESS != status )
8806 {
8807 if( NULL != pAdapter )
8808 {
8809 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
8810 pAdapter = NULL;
8811 }
8812 if( NULL != pHddAdapterNode )
8813 {
8814 vos_mem_free( pHddAdapterNode );
8815 }
8816
8817 goto resume_bmps;
8818 }
8819
8820 if(VOS_STATUS_SUCCESS == status)
8821 {
8822 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
8823
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07008824 //Initialize the WoWL service
8825 if(!hdd_init_wowl(pAdapter))
8826 {
8827 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
8828 goto err_free_netdev;
8829 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008830 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008831 return pAdapter;
8832
8833err_free_netdev:
8834 free_netdev(pAdapter->dev);
8835 wlan_hdd_release_intf_addr( pHddCtx,
8836 pAdapter->macAddressCurrent.bytes );
8837
8838resume_bmps:
8839 //If bmps disabled enable it
8840 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
8841 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308842 if (pHddCtx->hdd_wlan_suspended)
8843 {
8844 hdd_set_pwrparams(pHddCtx);
8845 }
8846 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008847 }
8848 return NULL;
8849}
8850
8851VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
8852 tANI_U8 rtnl_held )
8853{
8854 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
8855 VOS_STATUS status;
8856
8857 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
8858 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308859 {
8860 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
8861 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008862 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308863 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008864
8865 while ( pCurrent->pAdapter != pAdapter )
8866 {
8867 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
8868 if( VOS_STATUS_SUCCESS != status )
8869 break;
8870
8871 pCurrent = pNext;
8872 }
8873 pAdapterNode = pCurrent;
8874 if( VOS_STATUS_SUCCESS == status )
8875 {
8876 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8877 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308878
8879#ifdef FEATURE_WLAN_TDLS
8880
8881 /* A Mutex Lock is introduced while changing/initializing the mode to
8882 * protect the concurrent access for the Adapters by TDLS module.
8883 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308884 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308885#endif
8886
Jeff Johnson295189b2012-06-20 16:38:30 -07008887 hdd_remove_adapter( pHddCtx, pAdapterNode );
8888 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008889 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008890
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308891#ifdef FEATURE_WLAN_TDLS
8892 mutex_unlock(&pHddCtx->tdls_lock);
8893#endif
8894
Jeff Johnson295189b2012-06-20 16:38:30 -07008895
8896 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05308897 if ((!vos_concurrent_open_sessions_running()) &&
8898 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
8899 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008900 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308901 if (pHddCtx->hdd_wlan_suspended)
8902 {
8903 hdd_set_pwrparams(pHddCtx);
8904 }
8905 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008906 }
8907
8908 return VOS_STATUS_SUCCESS;
8909 }
8910
8911 return VOS_STATUS_E_FAILURE;
8912}
8913
8914VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
8915{
8916 hdd_adapter_list_node_t *pHddAdapterNode;
8917 VOS_STATUS status;
8918
8919 ENTER();
8920
8921 do
8922 {
8923 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
8924 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
8925 {
8926 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
8927 vos_mem_free( pHddAdapterNode );
8928 }
8929 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
8930
8931 EXIT();
8932
8933 return VOS_STATUS_SUCCESS;
8934}
8935
8936void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
8937{
8938 v_U8_t addIE[1] = {0};
8939
8940 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8941 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
8942 eANI_BOOLEAN_FALSE) )
8943 {
8944 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008945 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008946 }
8947
8948 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8949 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8950 eANI_BOOLEAN_FALSE) )
8951 {
8952 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008953 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008954 }
8955
8956 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8957 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8958 eANI_BOOLEAN_FALSE) )
8959 {
8960 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008961 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008962 }
8963}
8964
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308965VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
8966 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07008967{
8968 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
8969 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308970 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008971 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05308972 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308973 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05308974 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008975
Anand N Sunkad26d71b92014-12-24 18:08:22 +05308976 if (pHddCtx->isLogpInProgress) {
8977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8978 "%s:LOGP in Progress. Ignore!!!",__func__);
8979 return VOS_STATUS_E_FAILURE;
8980 }
8981
Jeff Johnson295189b2012-06-20 16:38:30 -07008982 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308983
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308984 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07008985 switch(pAdapter->device_mode)
8986 {
Nirav Shah0cf4d892015-11-05 16:27:27 +05308987 case WLAN_HDD_IBSS:
8988 if ( VOS_TRUE == bCloseSession )
8989 {
8990 status = hdd_sta_id_hash_detach(pAdapter);
8991 if (status != VOS_STATUS_SUCCESS)
8992 hddLog(VOS_TRACE_LEVEL_ERROR,
8993 FL("sta id hash detach failed"));
8994 }
8995
Jeff Johnson295189b2012-06-20 16:38:30 -07008996 case WLAN_HDD_INFRA_STATION:
8997 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07008998 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05308999 {
9000 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05309001#ifdef FEATURE_WLAN_TDLS
9002 mutex_lock(&pHddCtx->tdls_lock);
9003 wlan_hdd_tdls_exit(pAdapter, TRUE);
9004 mutex_unlock(&pHddCtx->tdls_lock);
9005#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309006 if( hdd_connIsConnected(pstation) ||
9007 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009008 {
9009 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
9010 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
9011 pAdapter->sessionId,
9012 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
9013 else
9014 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
9015 pAdapter->sessionId,
9016 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Abhishek Singh7b52ed52016-02-11 17:45:54 +05309017 /* Success implies disconnect command got queued up successfully
9018 * Or cmd not queued as scan for SSID is in progress
9019 */
9020 if((eHAL_STATUS_SUCCESS == halStatus) ||
9021 (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07009022 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309023 ret = wait_for_completion_interruptible_timeout(
9024 &pAdapter->disconnect_comp_var,
9025 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singh7b52ed52016-02-11 17:45:54 +05309026 if (ret <= 0 &&
9027 (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309028 {
9029 hddLog(VOS_TRACE_LEVEL_ERROR,
9030 "%s: wait on disconnect_comp_var failed %ld",
9031 __func__, ret);
9032 }
9033 }
9034 else
9035 {
9036 hddLog(LOGE, "%s: failed to post disconnect event to SME",
9037 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009038 }
9039 memset(&wrqu, '\0', sizeof(wrqu));
9040 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
9041 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
9042 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
9043 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309044 else if(pstation->conn_info.connState ==
9045 eConnectionState_Disconnecting)
9046 {
9047 ret = wait_for_completion_interruptible_timeout(
9048 &pAdapter->disconnect_comp_var,
9049 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
9050 if (ret <= 0)
9051 {
9052 hddLog(VOS_TRACE_LEVEL_ERROR,
9053 FL("wait on disconnect_comp_var failed %ld"), ret);
9054 }
9055 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05309056 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07009057 {
Mahesh A Saptasagar0b61dcc2016-02-15 14:23:38 +05309058 wlan_hdd_scan_abort(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009059 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +05309060 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
9061 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309062 {
9063 while (pAdapter->is_roc_inprogress)
9064 {
9065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9066 "%s: ROC in progress for session %d!!!",
9067 __func__, pAdapter->sessionId);
9068 // waiting for ROC to expire
9069 msleep(500);
9070 /* In GO present case , if retry exceeds 3,
9071 it means something went wrong. */
9072 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
9073 {
9074 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9075 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05309076 if (eHAL_STATUS_SUCCESS !=
9077 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
9078 pAdapter->sessionId ))
9079 {
9080 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9081 FL("Failed to Cancel Remain on Channel"));
9082 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309083 wait_for_completion_interruptible_timeout(
9084 &pAdapter->cancel_rem_on_chan_var,
9085 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
9086 break;
9087 }
9088 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309089 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309090 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309091#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309092 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309093#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309094
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309095 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309096
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309097 /* It is possible that the caller of this function does not
9098 * wish to close the session
9099 */
9100 if (VOS_TRUE == bCloseSession &&
9101 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009102 {
9103 INIT_COMPLETION(pAdapter->session_close_comp_var);
9104 if (eHAL_STATUS_SUCCESS ==
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05309105 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, FALSE,
9106 VOS_FALSE, hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07009107 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309108 unsigned long ret;
9109
Jeff Johnson295189b2012-06-20 16:38:30 -07009110 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309111 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309112 &pAdapter->session_close_comp_var,
9113 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309114 if ( 0 >= ret)
9115 {
9116 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309117 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309118 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009119 }
9120 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309121 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009122 break;
9123
9124 case WLAN_HDD_SOFTAP:
9125 case WLAN_HDD_P2P_GO:
Nirav Shah0cf4d892015-11-05 16:27:27 +05309126 if ( VOS_TRUE == bCloseSession )
9127 {
9128 status = hdd_sta_id_hash_detach(pAdapter);
9129 if (status != VOS_STATUS_SUCCESS)
9130 hddLog(VOS_TRACE_LEVEL_ERROR,
9131 FL("sta id hash detach failed"));
9132 }
9133
Jeff Johnson295189b2012-06-20 16:38:30 -07009134 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309135 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
9136 while (pAdapter->is_roc_inprogress) {
9137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9138 "%s: ROC in progress for session %d!!!",
9139 __func__, pAdapter->sessionId);
9140 msleep(500);
9141 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
9142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9143 "%s: ROC completion is not received.!!!", __func__);
9144 WLANSAP_CancelRemainOnChannel(
9145 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
9146 wait_for_completion_interruptible_timeout(
9147 &pAdapter->cancel_rem_on_chan_var,
9148 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
9149 break;
9150 }
9151 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309152
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309153 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309154 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009155 mutex_lock(&pHddCtx->sap_lock);
9156 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9157 {
9158 VOS_STATUS status;
9159 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9160
9161 //Stop Bss.
9162 status = WLANSAP_StopBss(pHddCtx->pvosContext);
9163 if (VOS_IS_STATUS_SUCCESS(status))
9164 {
9165 hdd_hostapd_state_t *pHostapdState =
9166 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9167
9168 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9169
9170 if (!VOS_IS_STATUS_SUCCESS(status))
9171 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309172 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
9173 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009174 }
9175 }
9176 else
9177 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009178 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009179 }
9180 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309181 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009182
9183 if (eHAL_STATUS_FAILURE ==
9184 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
9185 0, NULL, eANI_BOOLEAN_FALSE))
9186 {
9187 hddLog(LOGE,
9188 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009189 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009190 }
9191
9192 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
9193 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9194 eANI_BOOLEAN_FALSE) )
9195 {
9196 hddLog(LOGE,
9197 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
9198 }
9199
9200 // Reset WNI_CFG_PROBE_RSP Flags
9201 wlan_hdd_reset_prob_rspies(pAdapter);
9202 kfree(pAdapter->sessionCtx.ap.beacon);
9203 pAdapter->sessionCtx.ap.beacon = NULL;
9204 }
9205 mutex_unlock(&pHddCtx->sap_lock);
9206 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009207
Jeff Johnson295189b2012-06-20 16:38:30 -07009208 case WLAN_HDD_MONITOR:
9209 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009210
Jeff Johnson295189b2012-06-20 16:38:30 -07009211 default:
9212 break;
9213 }
9214
9215 EXIT();
9216 return VOS_STATUS_SUCCESS;
9217}
9218
9219VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
9220{
9221 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9222 VOS_STATUS status;
9223 hdd_adapter_t *pAdapter;
9224
9225 ENTER();
9226
9227 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9228
9229 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9230 {
9231 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009232
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309233 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009234
9235 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9236 pAdapterNode = pNext;
9237 }
9238
9239 EXIT();
9240
9241 return VOS_STATUS_SUCCESS;
9242}
9243
Rajeev Kumarf999e582014-01-09 17:33:29 -08009244
9245#ifdef FEATURE_WLAN_BATCH_SCAN
9246/**---------------------------------------------------------------------------
9247
9248 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
9249 structures
9250
9251 \param - pAdapter Pointer to HDD adapter
9252
9253 \return - None
9254
9255 --------------------------------------------------------------------------*/
9256void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
9257{
9258 tHddBatchScanRsp *pNode;
9259 tHddBatchScanRsp *pPrev;
9260
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05309261 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08009262 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05309263 hddLog(VOS_TRACE_LEVEL_ERROR,
9264 "%s: Adapter context is Null", __func__);
9265 return;
9266 }
9267
9268 pNode = pAdapter->pBatchScanRsp;
9269 while (pNode)
9270 {
9271 pPrev = pNode;
9272 pNode = pNode->pNext;
9273 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08009274 }
9275
9276 pAdapter->pBatchScanRsp = NULL;
9277 pAdapter->numScanList = 0;
9278 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
9279 pAdapter->prev_batch_id = 0;
9280
9281 return;
9282}
9283#endif
9284
9285
Jeff Johnson295189b2012-06-20 16:38:30 -07009286VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
9287{
9288 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9289 VOS_STATUS status;
9290 hdd_adapter_t *pAdapter;
9291
9292 ENTER();
9293
9294 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9295
9296 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9297 {
9298 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309299 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009300 netif_tx_disable(pAdapter->dev);
9301 netif_carrier_off(pAdapter->dev);
9302
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07009303 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
9304
Jeff Johnson295189b2012-06-20 16:38:30 -07009305 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05309306
Katya Nigam1fd24402015-02-16 14:52:19 +05309307 if(pAdapter->device_mode == WLAN_HDD_IBSS )
9308 hdd_ibss_deinit_tx_rx(pAdapter);
9309
Nirav Shah7e3c8132015-06-22 23:51:42 +05309310 status = hdd_sta_id_hash_detach(pAdapter);
9311 if (status != VOS_STATUS_SUCCESS)
9312 hddLog(VOS_TRACE_LEVEL_ERROR,
9313 FL("sta id hash detach failed for session id %d"),
9314 pAdapter->sessionId);
9315
Agarwal Ashish6267caa2014-08-06 19:16:21 +05309316 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
9317
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05309318 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9319 {
9320 hdd_wmm_adapter_close( pAdapter );
9321 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9322 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009323
Siddharth Bhal2db319d2014-12-03 12:37:18 +05309324 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9325 {
9326 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
9327 }
9328
Rajeev Kumarf999e582014-01-09 17:33:29 -08009329#ifdef FEATURE_WLAN_BATCH_SCAN
9330 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
9331 {
9332 hdd_deinit_batch_scan(pAdapter);
9333 }
9334#endif
9335
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05309336#ifdef FEATURE_WLAN_TDLS
9337 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05309338 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05309339 mutex_unlock(&pHddCtx->tdls_lock);
9340#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009341 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9342 pAdapterNode = pNext;
9343 }
9344
9345 EXIT();
9346
9347 return VOS_STATUS_SUCCESS;
9348}
9349
9350VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
9351{
9352 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9353 VOS_STATUS status;
9354 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309355 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07009356
9357 ENTER();
9358
9359 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9360
9361 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9362 {
9363 pAdapter = pAdapterNode->pAdapter;
9364
Kumar Anand82c009f2014-05-29 00:29:42 -07009365 hdd_wmm_init( pAdapter );
9366
Jeff Johnson295189b2012-06-20 16:38:30 -07009367 switch(pAdapter->device_mode)
9368 {
9369 case WLAN_HDD_INFRA_STATION:
9370 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009371 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309372
9373 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
9374
Jeff Johnson295189b2012-06-20 16:38:30 -07009375 hdd_init_station_mode(pAdapter);
9376 /* Open the gates for HDD to receive Wext commands */
9377 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009378 pHddCtx->scan_info.mScanPending = FALSE;
9379 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009380
9381 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +05309382 if (!pHddCtx->isLogpInProgress)
9383 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009384
9385 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309386 if (eConnectionState_Associated == connState ||
9387 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07009388 {
9389 union iwreq_data wrqu;
9390 memset(&wrqu, '\0', sizeof(wrqu));
9391 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
9392 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
9393 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07009394 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009395
Jeff Johnson295189b2012-06-20 16:38:30 -07009396 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagar9ff4bcc2016-06-01 17:17:50 +05309397 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, false,
Mahesh A Saptasagarb5a15142016-05-25 11:27:43 +05309398 WLAN_REASON_UNSPECIFIED);
Jeff Johnson295189b2012-06-20 16:38:30 -07009399 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309400 else if (eConnectionState_Connecting == connState)
9401 {
9402 /*
9403 * Indicate connect failure to supplicant if we were in the
9404 * process of connecting
9405 */
9406 cfg80211_connect_result(pAdapter->dev, NULL,
9407 NULL, 0, NULL, 0,
9408 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
9409 GFP_KERNEL);
9410 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009411 break;
9412
9413 case WLAN_HDD_SOFTAP:
9414 /* softAP can handle SSR */
9415 break;
9416
9417 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07009418 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07009419 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07009420 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009421 break;
9422
9423 case WLAN_HDD_MONITOR:
9424 /* monitor interface start */
9425 break;
9426 default:
9427 break;
9428 }
9429
9430 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9431 pAdapterNode = pNext;
9432 }
9433
9434 EXIT();
9435
9436 return VOS_STATUS_SUCCESS;
9437}
9438
9439VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
9440{
9441 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9442 hdd_adapter_t *pAdapter;
9443 VOS_STATUS status;
9444 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309445 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009446
9447 ENTER();
9448
9449 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9450
9451 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9452 {
9453 pAdapter = pAdapterNode->pAdapter;
9454
9455 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9456 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9457 {
9458 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9459 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9460
Abhishek Singhf4669da2014-05-26 15:07:49 +05309461 hddLog(VOS_TRACE_LEVEL_INFO,
9462 "%s: Set HDD connState to eConnectionState_NotConnected",
9463 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +05309464 spin_lock_bh(&pAdapter->lock_for_active_session);
9465 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
9466 {
9467 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
9468 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009469 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +05309470 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07009471 init_completion(&pAdapter->disconnect_comp_var);
9472 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
9473 eCSR_DISCONNECT_REASON_UNSPECIFIED);
9474
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309475 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009476 &pAdapter->disconnect_comp_var,
9477 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309478 if (0 >= ret)
9479 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
9480 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07009481
9482 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
9483 pHddCtx->isAmpAllowed = VOS_FALSE;
9484 sme_RoamConnect(pHddCtx->hHal,
9485 pAdapter->sessionId, &(pWextState->roamProfile),
9486 &roamId);
9487 }
9488
9489 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9490 pAdapterNode = pNext;
9491 }
9492
9493 EXIT();
9494
9495 return VOS_STATUS_SUCCESS;
9496}
9497
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009498void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
9499{
9500 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9501 VOS_STATUS status;
9502 hdd_adapter_t *pAdapter;
9503 hdd_station_ctx_t *pHddStaCtx;
9504 hdd_ap_ctx_t *pHddApCtx;
9505 hdd_hostapd_state_t * pHostapdState;
9506 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
9507 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
9508 const char *p2pMode = "DEV";
9509 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009510
9511 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9512 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9513 {
9514 pAdapter = pAdapterNode->pAdapter;
9515 switch (pAdapter->device_mode) {
9516 case WLAN_HDD_INFRA_STATION:
9517 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9518 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
9519 staChannel = pHddStaCtx->conn_info.operationChannel;
9520 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
9521 }
9522 break;
9523 case WLAN_HDD_P2P_CLIENT:
9524 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9525 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
9526 p2pChannel = pHddStaCtx->conn_info.operationChannel;
9527 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
9528 p2pMode = "CLI";
9529 }
9530 break;
9531 case WLAN_HDD_P2P_GO:
9532 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9533 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9534 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
9535 p2pChannel = pHddApCtx->operatingChannel;
9536 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
9537 }
9538 p2pMode = "GO";
9539 break;
9540 case WLAN_HDD_SOFTAP:
9541 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9542 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9543 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
9544 apChannel = pHddApCtx->operatingChannel;
9545 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
9546 }
9547 break;
9548 default:
9549 break;
9550 }
9551 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9552 pAdapterNode = pNext;
9553 }
9554 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
9555 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
9556 }
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05309557 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s",
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009558 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
9559 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05309560 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009561 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
9562 }
9563 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05309564 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009565 apChannel, MAC_ADDR_ARRAY(apBssid));
9566 }
9567
9568 if (p2pChannel > 0 && apChannel > 0) {
9569 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
9570 }
9571}
9572
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009573bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009574{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009575 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07009576}
9577
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009578/* Once SSR is disabled then it cannot be set. */
9579void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07009580{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009581 if (HDD_SSR_DISABLED == isSsrRequired)
9582 return;
9583
Jeff Johnson295189b2012-06-20 16:38:30 -07009584 isSsrRequired = value;
9585}
9586
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05309587void hdd_set_pre_close( hdd_context_t *pHddCtx)
9588{
9589 sme_PreClose(pHddCtx->hHal);
9590}
9591
Jeff Johnson295189b2012-06-20 16:38:30 -07009592VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
9593 hdd_adapter_list_node_t** ppAdapterNode)
9594{
9595 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309596 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009597 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
9598 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309599 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009600 return status;
9601}
9602
9603VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
9604 hdd_adapter_list_node_t* pAdapterNode,
9605 hdd_adapter_list_node_t** pNextAdapterNode)
9606{
9607 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309608 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009609 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
9610 (hdd_list_node_t*) pAdapterNode,
9611 (hdd_list_node_t**)pNextAdapterNode );
9612
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309613 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009614 return status;
9615}
9616
9617VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
9618 hdd_adapter_list_node_t* pAdapterNode)
9619{
9620 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309621 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009622 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
9623 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309624 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009625 return status;
9626}
9627
9628VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
9629 hdd_adapter_list_node_t** ppAdapterNode)
9630{
9631 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309632 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009633 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
9634 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309635 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009636 return status;
9637}
9638
9639VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
9640 hdd_adapter_list_node_t* pAdapterNode)
9641{
9642 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309643 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009644 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
9645 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309646 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009647 return status;
9648}
9649
9650VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
9651 hdd_adapter_list_node_t* pAdapterNode)
9652{
9653 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309654 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009655 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
9656 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309657 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009658 return status;
9659}
9660
9661hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
9662 tSirMacAddr macAddr )
9663{
9664 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9665 hdd_adapter_t *pAdapter;
9666 VOS_STATUS status;
9667
9668 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9669
9670 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9671 {
9672 pAdapter = pAdapterNode->pAdapter;
9673
9674 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
9675 macAddr, sizeof(tSirMacAddr) ) )
9676 {
9677 return pAdapter;
9678 }
9679 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9680 pAdapterNode = pNext;
9681 }
9682
9683 return NULL;
9684
9685}
9686
9687hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
9688{
9689 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9690 hdd_adapter_t *pAdapter;
9691 VOS_STATUS status;
9692
9693 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9694
9695 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9696 {
9697 pAdapter = pAdapterNode->pAdapter;
9698
9699 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
9700 IFNAMSIZ ) )
9701 {
9702 return pAdapter;
9703 }
9704 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9705 pAdapterNode = pNext;
9706 }
9707
9708 return NULL;
9709
9710}
9711
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +05309712hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
9713 tANI_U32 sme_session_id )
9714{
9715 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9716 hdd_adapter_t *pAdapter;
9717 VOS_STATUS vos_status;
9718
9719
9720 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
9721
9722 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
9723 {
9724 pAdapter = pAdapterNode->pAdapter;
9725
9726 if (pAdapter->sessionId == sme_session_id)
9727 return pAdapter;
9728
9729 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
9730 pAdapterNode = pNext;
9731 }
9732
9733 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9734 "%s: sme_session_id %d does not exist with host",
9735 __func__, sme_session_id);
9736
9737 return NULL;
9738}
9739
Jeff Johnson295189b2012-06-20 16:38:30 -07009740hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
9741{
9742 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9743 hdd_adapter_t *pAdapter;
9744 VOS_STATUS status;
9745
9746 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9747
9748 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9749 {
9750 pAdapter = pAdapterNode->pAdapter;
9751
9752 if( pAdapter && (mode == pAdapter->device_mode) )
9753 {
9754 return pAdapter;
9755 }
9756 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9757 pAdapterNode = pNext;
9758 }
9759
9760 return NULL;
9761
9762}
9763
9764//Remove this function later
9765hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
9766{
9767 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9768 hdd_adapter_t *pAdapter;
9769 VOS_STATUS status;
9770
9771 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9772
9773 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9774 {
9775 pAdapter = pAdapterNode->pAdapter;
9776
9777 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
9778 {
9779 return pAdapter;
9780 }
9781
9782 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9783 pAdapterNode = pNext;
9784 }
9785
9786 return NULL;
9787
9788}
9789
Jeff Johnson295189b2012-06-20 16:38:30 -07009790/**---------------------------------------------------------------------------
9791
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05309792 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07009793
9794 This API returns the operating channel of the requested device mode
9795
9796 \param - pHddCtx - Pointer to the HDD context.
9797 - mode - Device mode for which operating channel is required
9798 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
9799 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
9800 \return - channel number. "0" id the requested device is not found OR it is not connected.
9801 --------------------------------------------------------------------------*/
9802v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
9803{
9804 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9805 VOS_STATUS status;
9806 hdd_adapter_t *pAdapter;
9807 v_U8_t operatingChannel = 0;
9808
9809 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9810
9811 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9812 {
9813 pAdapter = pAdapterNode->pAdapter;
9814
9815 if( mode == pAdapter->device_mode )
9816 {
9817 switch(pAdapter->device_mode)
9818 {
9819 case WLAN_HDD_INFRA_STATION:
9820 case WLAN_HDD_P2P_CLIENT:
9821 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
9822 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
9823 break;
9824 case WLAN_HDD_SOFTAP:
9825 case WLAN_HDD_P2P_GO:
9826 /*softap connection info */
9827 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9828 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
9829 break;
9830 default:
9831 break;
9832 }
9833
9834 break; //Found the device of interest. break the loop
9835 }
9836
9837 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9838 pAdapterNode = pNext;
9839 }
9840 return operatingChannel;
9841}
9842
9843#ifdef WLAN_FEATURE_PACKET_FILTERING
9844/**---------------------------------------------------------------------------
9845
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309846 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07009847
9848 This used to set the multicast address list.
9849
9850 \param - dev - Pointer to the WLAN device.
9851 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309852 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07009853
9854 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309855static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07009856{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309857 hdd_adapter_t *pAdapter;
9858 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009859 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309860 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009861 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309862
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309863 ENTER();
9864
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309865 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309866 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009867 {
9868 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309869 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009870 return;
9871 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309872 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9873 ret = wlan_hdd_validate_context(pHddCtx);
9874 if (0 != ret)
9875 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309876 return;
9877 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009878 if (dev->flags & IFF_ALLMULTI)
9879 {
9880 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009881 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309882 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009883 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309884 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009885 {
9886 mc_count = netdev_mc_count(dev);
9887 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009888 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07009889 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
9890 {
9891 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009892 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309893 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009894 return;
9895 }
9896
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309897 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07009898
9899 netdev_for_each_mc_addr(ha, dev) {
9900 if (i == mc_count)
9901 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309902 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
9903 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08009904 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309905 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309906 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07009907 i++;
9908 }
9909 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309910
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +05309911 if (pHddCtx->hdd_wlan_suspended)
9912 {
9913 /*
9914 * Configure the Mcast address list to FW
9915 * If wlan is already in suspend mode
9916 */
9917 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
9918 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309919 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009920 return;
9921}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309922
9923static void hdd_set_multicast_list(struct net_device *dev)
9924{
9925 vos_ssr_protect(__func__);
9926 __hdd_set_multicast_list(dev);
9927 vos_ssr_unprotect(__func__);
9928}
Jeff Johnson295189b2012-06-20 16:38:30 -07009929#endif
9930
9931/**---------------------------------------------------------------------------
9932
9933 \brief hdd_select_queue() -
9934
9935 This function is registered with the Linux OS for network
9936 core to decide which queue to use first.
9937
9938 \param - dev - Pointer to the WLAN device.
9939 - skb - Pointer to OS packet (sk_buff).
9940 \return - ac, Queue Index/access category corresponding to UP in IP header
9941
9942 --------------------------------------------------------------------------*/
9943v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309944 struct sk_buff *skb
9945#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
9946 , void *accel_priv
9947#endif
9948#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9949 , select_queue_fallback_t fallback
9950#endif
9951)
Jeff Johnson295189b2012-06-20 16:38:30 -07009952{
9953 return hdd_wmm_select_queue(dev, skb);
9954}
9955
9956
9957/**---------------------------------------------------------------------------
9958
9959 \brief hdd_wlan_initial_scan() -
9960
9961 This function triggers the initial scan
9962
9963 \param - pAdapter - Pointer to the HDD adapter.
9964
9965 --------------------------------------------------------------------------*/
9966void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
9967{
9968 tCsrScanRequest scanReq;
9969 tCsrChannelInfo channelInfo;
9970 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07009971 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07009972 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9973
9974 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
9975 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
9976 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
9977
9978 if(sme_Is11dSupported(pHddCtx->hHal))
9979 {
9980 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
9981 if ( HAL_STATUS_SUCCESS( halStatus ) )
9982 {
9983 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
9984 if( !scanReq.ChannelInfo.ChannelList )
9985 {
9986 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
9987 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08009988 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009989 return;
9990 }
9991 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
9992 channelInfo.numOfChannels);
9993 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
9994 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08009995 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009996 }
9997
9998 scanReq.scanType = eSIR_PASSIVE_SCAN;
9999 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
10000 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
10001 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
10002 }
10003 else
10004 {
10005 scanReq.scanType = eSIR_ACTIVE_SCAN;
10006 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10007 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
10008 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
10009 }
10010
10011 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
10012 if ( !HAL_STATUS_SUCCESS( halStatus ) )
10013 {
10014 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
10015 __func__, halStatus );
10016 }
10017
10018 if(sme_Is11dSupported(pHddCtx->hHal))
10019 vos_mem_free(scanReq.ChannelInfo.ChannelList);
10020}
10021
Jeff Johnson295189b2012-06-20 16:38:30 -070010022/**---------------------------------------------------------------------------
10023
10024 \brief hdd_full_power_callback() - HDD full power callback function
10025
10026 This is the function invoked by SME to inform the result of a full power
10027 request issued by HDD
10028
10029 \param - callbackcontext - Pointer to cookie
10030 \param - status - result of request
10031
10032 \return - None
10033
10034 --------------------------------------------------------------------------*/
10035static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
10036{
Jeff Johnson72a40512013-12-19 10:14:15 -080010037 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010038
10039 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010040 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010041
10042 if (NULL == callbackContext)
10043 {
10044 hddLog(VOS_TRACE_LEVEL_ERROR,
10045 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010046 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010047 return;
10048 }
10049
Jeff Johnson72a40512013-12-19 10:14:15 -080010050 /* there is a race condition that exists between this callback
10051 function and the caller since the caller could time out either
10052 before or while this code is executing. we use a spinlock to
10053 serialize these actions */
10054 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010055
10056 if (POWER_CONTEXT_MAGIC != pContext->magic)
10057 {
10058 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -080010059 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010060 hddLog(VOS_TRACE_LEVEL_WARN,
10061 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010062 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -070010063 return;
10064 }
10065
Jeff Johnson72a40512013-12-19 10:14:15 -080010066 /* context is valid so caller is still waiting */
10067
10068 /* paranoia: invalidate the magic */
10069 pContext->magic = 0;
10070
10071 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -070010072 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -080010073
10074 /* serialization is complete */
10075 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010076}
10077
Katya Nigamf0511f62015-05-05 16:40:57 +053010078void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
10079{
10080 pMonCtx->typeSubtypeBitmap = 0;
10081 if( type%10 ) /* Management Packets */
10082 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
10083 type/=10;
10084 if( type%10 ) /* Control Packets */
10085 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
10086 type/=10;
10087 if( type%10 ) /* Data Packets */
10088 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
10089}
10090
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010091VOS_STATUS wlan_hdd_mon_postMsg(tANI_U32 *magic, struct completion *cmpVar,
10092 hdd_mon_ctx_t *pMonCtx , void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +053010093{
10094 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010095 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053010096
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010097 if (MON_MODE_START == pMonCtx->state)
10098 monMsg.type = WDA_MON_START_REQ;
10099 else if (MON_MODE_STOP == pMonCtx->state)
10100 monMsg.type = WDA_MON_STOP_REQ;
10101 else {
10102 hddLog(VOS_TRACE_LEVEL_ERROR,
10103 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +053010104 return VOS_STATUS_E_FAILURE;
10105 }
10106
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010107 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
10108 if (pMonModeReq == NULL) {
10109 hddLog(VOS_TRACE_LEVEL_ERROR,
10110 FL("fail to allocate memory for monitor mode req"));
10111 return VOS_STATUS_E_FAILURE;
10112 }
Katya Nigamf0511f62015-05-05 16:40:57 +053010113
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010114 pMonModeReq->magic = magic;
10115 pMonModeReq->cmpVar = cmpVar;
10116 pMonModeReq->data = pMonCtx;
10117 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +053010118
Katya Nigamf0511f62015-05-05 16:40:57 +053010119 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010120 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053010121 monMsg.bodyval = 0;
10122
10123 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
10124 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
10125 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010126 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +053010127 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010128 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +053010129}
10130
Katya Nigame7b69a82015-04-28 15:24:06 +053010131void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
10132{
10133 VOS_STATUS vosStatus;
10134 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010135 long ret;
10136 hdd_mon_ctx_t *pMonCtx = NULL;
10137 v_U32_t magic;
10138 struct completion cmpVar;
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053010139
Katya Nigame7b69a82015-04-28 15:24:06 +053010140 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
10141 if(pAdapter == NULL || pVosContext == NULL)
10142 {
10143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
10144 return ;
10145 }
Katya Nigamf0511f62015-05-05 16:40:57 +053010146
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010147 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
10148 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
10149 pMonCtx->state = MON_MODE_STOP;
10150 magic = MON_MODE_MSG_MAGIC;
10151 init_completion(&cmpVar);
10152 if (VOS_STATUS_SUCCESS !=
10153 wlan_hdd_mon_postMsg(&magic, &cmpVar,
10154 pMonCtx, hdd_monPostMsgCb)) {
10155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10156 FL("failed to post MON MODE REQ"));
10157 pMonCtx->state = MON_MODE_START;
10158 magic = 0;
10159 return;
10160 }
10161 ret = wait_for_completion_timeout(&cmpVar, MON_MODE_MSG_TIMEOUT);
10162 magic = 0;
10163 if (ret <= 0 ) {
10164 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10165 FL("timeout on monitor mode completion %ld"), ret);
10166 }
10167 }
10168
Katya Nigame7b69a82015-04-28 15:24:06 +053010169 hdd_UnregisterWext(pAdapter->dev);
10170
10171 vos_mon_stop( pVosContext );
10172
10173 vosStatus = vos_sched_close( pVosContext );
10174 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
10175 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10176 "%s: Failed to close VOSS Scheduler",__func__);
10177 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10178 }
10179
10180 vosStatus = vos_nv_close();
10181 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10182 {
10183 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10184 "%s: Failed to close NV", __func__);
10185 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10186 }
10187
10188 vos_close(pVosContext);
10189
10190 #ifdef WLAN_KD_READY_NOTIFIER
10191 nl_srv_exit(pHddCtx->ptt_pid);
10192 #else
10193 nl_srv_exit();
10194 #endif
10195
Katya Nigame7b69a82015-04-28 15:24:06 +053010196 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +053010197}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053010198/**
10199 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
10200 * @ wiphy: the wiphy to validate against
10201 *
10202 * Return: void
10203 */
10204void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
10205{
10206 int i =0;
10207 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
10208 {
10209 if (NULL != wiphy->bands[i] &&
10210 (NULL != wiphy->bands[i]->channels))
10211 {
10212 vos_mem_free(wiphy->bands[i]->channels);
10213 wiphy->bands[i]->channels = NULL;
10214 }
10215 }
10216}
Jeff Johnson295189b2012-06-20 16:38:30 -070010217/**---------------------------------------------------------------------------
10218
10219 \brief hdd_wlan_exit() - HDD WLAN exit function
10220
10221 This is the driver exit point (invoked during rmmod)
10222
10223 \param - pHddCtx - Pointer to the HDD Context
10224
10225 \return - None
10226
10227 --------------------------------------------------------------------------*/
10228void hdd_wlan_exit(hdd_context_t *pHddCtx)
10229{
10230 eHalStatus halStatus;
10231 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
10232 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +053010233 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080010234 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -080010235 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010236 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +053010237 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010238
10239 ENTER();
10240
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010241
Katya Nigame7b69a82015-04-28 15:24:06 +053010242 if (VOS_MONITOR_MODE == hdd_get_conparam())
10243 {
10244 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
10245 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053010246 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +053010247 }
10248 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -080010249 {
10250 // Unloading, restart logic is no more required.
10251 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -070010252
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053010253#ifdef FEATURE_WLAN_TDLS
10254 /* At the time of driver unloading; if tdls connection is present;
10255 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
10256 * wlan_hdd_tdls_find_peer always checks for valid context;
10257 * as load/unload in progress there can be a race condition.
10258 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
10259 * when tdls state is enabled.
10260 * As soon as driver set load/unload flag; tdls flag also needs
10261 * to be disabled so that hdd_rx_packet_cbk won't call
10262 * wlan_hdd_tdls_find_peer.
10263 */
Masti, Narayanraddi20494af2015-12-17 20:56:42 +053010264 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE,
10265 HDD_SET_TDLS_MODE_SOURCE_USER);
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053010266#endif
10267
c_hpothu5ab05e92014-06-13 17:34:05 +053010268 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10269 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -070010270 {
c_hpothu5ab05e92014-06-13 17:34:05 +053010271 pAdapter = pAdapterNode->pAdapter;
10272 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070010273 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053010274 /* Disable TX on the interface, after this hard_start_xmit() will
10275 * not be called on that interface
10276 */
10277 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10278 netif_tx_disable(pAdapter->dev);
10279
10280 /* Mark the interface status as "down" for outside world */
10281 netif_carrier_off(pAdapter->dev);
10282
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053010283 /* DeInit the adapter. This ensures that all data packets
10284 * are freed.
10285 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053010286#ifdef FEATURE_WLAN_TDLS
10287 mutex_lock(&pHddCtx->tdls_lock);
10288#endif
c_hpothu002231a2015-02-05 14:58:51 +053010289 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053010290#ifdef FEATURE_WLAN_TDLS
10291 mutex_unlock(&pHddCtx->tdls_lock);
10292#endif
Masti, Narayanraddi26378462016-01-05 18:20:28 +053010293 vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work);
10294
10295 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053010296
c_hpothu5ab05e92014-06-13 17:34:05 +053010297 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10298 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
10299 {
10300 wlan_hdd_cfg80211_deregister_frames(pAdapter);
10301 hdd_UnregisterWext(pAdapter->dev);
10302 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010303
Jeff Johnson295189b2012-06-20 16:38:30 -070010304 }
c_hpothu5ab05e92014-06-13 17:34:05 +053010305 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10306 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010307 }
mukul sharmabab477d2015-06-11 17:14:55 +053010308
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010309 // Cancel any outstanding scan requests. We are about to close all
10310 // of our adapters, but an adapter structure is what SME passes back
10311 // to our callback function. Hence if there are any outstanding scan
10312 // requests then there is a race condition between when the adapter
10313 // is closed and when the callback is invoked.We try to resolve that
10314 // race condition here by canceling any outstanding scans before we
10315 // close the adapters.
10316 // Note that the scans may be cancelled in an asynchronous manner,
10317 // so ideally there needs to be some kind of synchronization. Rather
10318 // than introduce a new synchronization here, we will utilize the
10319 // fact that we are about to Request Full Power, and since that is
10320 // synchronized, the expectation is that by the time Request Full
10321 // Power has completed all scans will be cancelled.
10322 if (pHddCtx->scan_info.mScanPending)
10323 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +053010324 if(NULL != pAdapter)
10325 {
10326 hddLog(VOS_TRACE_LEVEL_INFO,
10327 FL("abort scan mode: %d sessionId: %d"),
10328 pAdapter->device_mode,
10329 pAdapter->sessionId);
10330 }
10331 hdd_abort_mac_scan(pHddCtx,
10332 pHddCtx->scan_info.sessionId,
10333 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010334 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010335 }
c_hpothu5ab05e92014-06-13 17:34:05 +053010336 else
Jeff Johnson88ba7742013-02-27 14:36:02 -080010337 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010338 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +053010339 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
10340 {
10341 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
10342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10343 "%s: in middle of FTM START", __func__);
10344 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
10345 msecs_to_jiffies(20000));
10346 if(!lrc)
10347 {
10348 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10349 "%s: timedout on ftmStartCmpVar fatal error", __func__);
10350 }
10351 }
Jeff Johnson88ba7742013-02-27 14:36:02 -080010352 wlan_hdd_ftm_close(pHddCtx);
10353 goto free_hdd_ctx;
10354 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010355
Jeff Johnson295189b2012-06-20 16:38:30 -070010356 /* DeRegister with platform driver as client for Suspend/Resume */
10357 vosStatus = hddDeregisterPmOps(pHddCtx);
10358 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
10359 {
10360 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
10361 VOS_ASSERT(0);
10362 }
10363
10364 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
10365 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
10366 {
10367 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
10368 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010369
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010370 //Stop the traffic monitor timer
10371 if ( VOS_TIMER_STATE_RUNNING ==
10372 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
10373 {
10374 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
10375 }
10376
10377 // Destroy the traffic monitor timer
10378 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
10379 &pHddCtx->tx_rx_trafficTmr)))
10380 {
10381 hddLog(VOS_TRACE_LEVEL_ERROR,
10382 "%s: Cannot deallocate Traffic monitor timer", __func__);
10383 }
10384
Bhargav Shahd0715912015-10-01 18:17:37 +053010385 if (VOS_TIMER_STATE_RUNNING ==
10386 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
10387 vos_timer_stop(&pHddCtx->delack_timer);
10388 }
10389
10390 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
10391 &pHddCtx->delack_timer))) {
10392 hddLog(VOS_TRACE_LEVEL_ERROR,
10393 "%s: Cannot deallocate Bus bandwidth timer", __func__);
10394 }
10395
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053010396 if (VOS_TIMER_STATE_RUNNING ==
10397 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) {
10398 vos_timer_stop(&pHddCtx->tdls_source_timer);
10399 }
10400
10401 vos_timer_destroy(&pHddCtx->tdls_source_timer);
10402
Jeff Johnson295189b2012-06-20 16:38:30 -070010403 //Disable IMPS/BMPS as we do not want the device to enter any power
10404 //save mode during shutdown
10405 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
10406 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
10407 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
10408
10409 //Ensure that device is in full power as we will touch H/W during vos_Stop
10410 init_completion(&powerContext.completion);
10411 powerContext.magic = POWER_CONTEXT_MAGIC;
10412
10413 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
10414 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
10415
10416 if (eHAL_STATUS_SUCCESS != halStatus)
10417 {
10418 if (eHAL_STATUS_PMC_PENDING == halStatus)
10419 {
10420 /* request was sent -- wait for the response */
10421 lrc = wait_for_completion_interruptible_timeout(
10422 &powerContext.completion,
10423 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -070010424 if (lrc <= 0)
10425 {
10426 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010427 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -070010428 }
10429 }
10430 else
10431 {
10432 hddLog(VOS_TRACE_LEVEL_ERROR,
10433 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010434 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -070010435 /* continue -- need to clean up as much as possible */
10436 }
10437 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +053010438 if ((eHAL_STATUS_SUCCESS == halStatus) ||
10439 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
10440 {
10441 /* This will issue a dump command which will clean up
10442 BTQM queues and unblock MC thread */
10443 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
10444 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010445
Jeff Johnson72a40512013-12-19 10:14:15 -080010446 /* either we never sent a request, we sent a request and received a
10447 response or we sent a request and timed out. if we never sent a
10448 request or if we sent a request and got a response, we want to
10449 clear the magic out of paranoia. if we timed out there is a
10450 race condition such that the callback function could be
10451 executing at the same time we are. of primary concern is if the
10452 callback function had already verified the "magic" but had not
10453 yet set the completion variable when a timeout occurred. we
10454 serialize these activities by invalidating the magic while
10455 holding a shared spinlock which will cause us to block if the
10456 callback is currently executing */
10457 spin_lock(&hdd_context_lock);
10458 powerContext.magic = 0;
10459 spin_unlock(&hdd_context_lock);
10460
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +053010461 /* If Device is shutdown, no point for SME to wait for responses
10462 from device. Pre Close SME */
10463 if(wcnss_device_is_shutdown())
10464 {
10465 sme_PreClose(pHddCtx->hHal);
10466 }
Yue Ma0d4891e2013-08-06 17:01:45 -070010467 hdd_debugfs_exit(pHddCtx);
10468
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010469#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +053010470 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010471 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10472#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +053010473 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010474 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10475
Jeff Johnson295189b2012-06-20 16:38:30 -070010476 // Unregister the Net Device Notifier
10477 unregister_netdevice_notifier(&hdd_netdev_notifier);
10478
Jeff Johnson295189b2012-06-20 16:38:30 -070010479 hdd_stop_all_adapters( pHddCtx );
10480
Jeff Johnson295189b2012-06-20 16:38:30 -070010481#ifdef WLAN_BTAMP_FEATURE
10482 vosStatus = WLANBAP_Stop(pVosContext);
10483 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10484 {
10485 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10486 "%s: Failed to stop BAP",__func__);
10487 }
10488#endif //WLAN_BTAMP_FEATURE
10489
10490 //Stop all the modules
10491 vosStatus = vos_stop( pVosContext );
10492 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10493 {
10494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10495 "%s: Failed to stop VOSS",__func__);
10496 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053010497 if (isSsrPanicOnFailure())
10498 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070010499 }
10500
Jeff Johnson295189b2012-06-20 16:38:30 -070010501 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -070010502 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010503
10504 //Close the scheduler before calling vos_close to make sure no thread is
10505 // scheduled after the each module close is called i.e after all the data
10506 // structures are freed.
10507 vosStatus = vos_sched_close( pVosContext );
10508 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
10509 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10510 "%s: Failed to close VOSS Scheduler",__func__);
10511 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10512 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010513#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10514 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010515 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070010516#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010517 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010518 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010519
Mihir Shete7a24b5f2013-12-21 12:18:31 +053010520#ifdef CONFIG_ENABLE_LINUX_REG
10521 vosStatus = vos_nv_close();
10522 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10523 {
10524 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10525 "%s: Failed to close NV", __func__);
10526 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10527 }
10528#endif
10529
Jeff Johnson295189b2012-06-20 16:38:30 -070010530 //Close VOSS
10531 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
10532 vos_close(pVosContext);
10533
Jeff Johnson295189b2012-06-20 16:38:30 -070010534 //Close Watchdog
10535 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10536 vos_watchdog_close(pVosContext);
10537
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053010538 //Clean up HDD Nlink Service
10539 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053010540
Manjeet Singh47ee8472016-04-11 11:57:18 +053010541 hdd_close_tx_queues(pHddCtx);
c_manjeecfd1efb2015-09-25 19:32:34 +053010542 wlan_free_fwr_mem_dump_buffer();
10543 memdump_deinit();
10544
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010545#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010546 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010547 {
10548 wlan_logging_sock_deactivate_svc();
10549 }
10550#endif
10551
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053010552#ifdef WLAN_KD_READY_NOTIFIER
10553 nl_srv_exit(pHddCtx->ptt_pid);
10554#else
10555 nl_srv_exit();
10556#endif /* WLAN_KD_READY_NOTIFIER */
10557
Abhishek Singh00b71972016-01-07 10:51:04 +053010558#ifdef WLAN_FEATURE_RMC
10559 hdd_close_cesium_nl_sock();
10560#endif /* WLAN_FEATURE_RMC */
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053010561
Jeff Johnson295189b2012-06-20 16:38:30 -070010562 hdd_close_all_adapters( pHddCtx );
10563
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053010564 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
10565
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +053010566free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -070010567 /* free the power on lock from platform driver */
10568 if (free_riva_power_on_lock("wlan"))
10569 {
10570 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
10571 __func__);
10572 }
10573
c_hpothu78c7b602014-05-17 17:35:49 +053010574 //Free up dynamically allocated members inside HDD Adapter
10575 if (pHddCtx->cfg_ini)
10576 {
10577 kfree(pHddCtx->cfg_ini);
10578 pHddCtx->cfg_ini= NULL;
10579 }
10580
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053010581 /* FTM/MONITOR mode, WIPHY did not registered
Leo Changf04ddad2013-09-18 13:46:38 -070010582 If un-register here, system crash will happen */
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053010583 if (!(VOS_FTM_MODE == hdd_get_conparam() ||
10584 VOS_MONITOR_MODE == hdd_get_conparam()))
Leo Changf04ddad2013-09-18 13:46:38 -070010585 {
10586 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053010587 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -070010588 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010589 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010590 if (hdd_is_ssr_required())
10591 {
10592 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -070010593 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -070010594 msleep(5000);
10595 }
10596 hdd_set_ssr_required (VOS_FALSE);
10597}
10598
10599
10600/**---------------------------------------------------------------------------
10601
10602 \brief hdd_update_config_from_nv() - Function to update the contents of
10603 the running configuration with parameters taken from NV storage
10604
10605 \param - pHddCtx - Pointer to the HDD global context
10606
10607 \return - VOS_STATUS_SUCCESS if successful
10608
10609 --------------------------------------------------------------------------*/
10610static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
10611{
Jeff Johnson295189b2012-06-20 16:38:30 -070010612 v_BOOL_t itemIsValid = VOS_FALSE;
10613 VOS_STATUS status;
10614 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
10615 v_U8_t macLoop;
10616
10617 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
10618 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
10619 if(status != VOS_STATUS_SUCCESS)
10620 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010621 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070010622 return VOS_STATUS_E_FAILURE;
10623 }
10624
10625 if (itemIsValid == VOS_TRUE)
10626 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010627 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -070010628 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
10629 VOS_MAX_CONCURRENCY_PERSONA);
10630 if(status != VOS_STATUS_SUCCESS)
10631 {
10632 /* Get MAC from NV fail, not update CFG info
10633 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -080010634 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070010635 return VOS_STATUS_E_FAILURE;
10636 }
10637
10638 /* If first MAC is not valid, treat all others are not valid
10639 * Then all MACs will be got from ini file */
10640 if(vos_is_macaddr_zero(&macFromNV[0]))
10641 {
10642 /* MAC address in NV file is not configured yet */
10643 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
10644 return VOS_STATUS_E_INVAL;
10645 }
10646
10647 /* Get MAC address from NV, update CFG info */
10648 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
10649 {
10650 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
10651 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010652 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -070010653 /* This MAC is not valid, skip it
10654 * This MAC will be got from ini file */
10655 }
10656 else
10657 {
10658 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
10659 (v_U8_t *)&macFromNV[macLoop].bytes[0],
10660 VOS_MAC_ADDR_SIZE);
10661 }
10662 }
10663 }
10664 else
10665 {
10666 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
10667 return VOS_STATUS_E_FAILURE;
10668 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010669
Jeff Johnson295189b2012-06-20 16:38:30 -070010670
10671 return VOS_STATUS_SUCCESS;
10672}
10673
10674/**---------------------------------------------------------------------------
10675
10676 \brief hdd_post_voss_start_config() - HDD post voss start config helper
10677
10678 \param - pAdapter - Pointer to the HDD
10679
10680 \return - None
10681
10682 --------------------------------------------------------------------------*/
10683VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
10684{
10685 eHalStatus halStatus;
10686 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010687 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -070010688
Jeff Johnson295189b2012-06-20 16:38:30 -070010689
10690 // Send ready indication to the HDD. This will kick off the MAC
10691 // into a 'running' state and should kick off an initial scan.
10692 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
10693 if ( !HAL_STATUS_SUCCESS( halStatus ) )
10694 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010695 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -070010696 "code %08d [x%08x]",__func__, halStatus, halStatus );
10697 return VOS_STATUS_E_FAILURE;
10698 }
10699
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010700 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -070010701 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
10702 // And RIVA will crash
10703 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
10704 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010705 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
10706 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
10707
10708
Jeff Johnson295189b2012-06-20 16:38:30 -070010709 return VOS_STATUS_SUCCESS;
10710}
10711
Jeff Johnson295189b2012-06-20 16:38:30 -070010712/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010713void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070010714{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010715
10716 vos_wake_lock_acquire(&wlan_wake_lock, reason);
10717
Jeff Johnson295189b2012-06-20 16:38:30 -070010718}
10719
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010720void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070010721{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010722
10723 vos_wake_lock_release(&wlan_wake_lock, reason);
10724
Jeff Johnson295189b2012-06-20 16:38:30 -070010725}
10726
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010727void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010728{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010729
10730 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
10731 reason);
10732
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010733}
10734
Jeff Johnson295189b2012-06-20 16:38:30 -070010735/**---------------------------------------------------------------------------
10736
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010737 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
10738 information between Host and Riva
10739
10740 This function gets reported version of FW
10741 It also finds the version of Riva headers used to compile the host
10742 It compares the above two and prints a warning if they are different
10743 It gets the SW and HW version string
10744 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
10745 indicating the features they support through a bitmap
10746
10747 \param - pHddCtx - Pointer to HDD context
10748
10749 \return - void
10750
10751 --------------------------------------------------------------------------*/
10752
10753void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
10754{
10755
10756 tSirVersionType versionCompiled;
10757 tSirVersionType versionReported;
10758 tSirVersionString versionString;
10759 tANI_U8 fwFeatCapsMsgSupported = 0;
10760 VOS_STATUS vstatus;
10761
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080010762 memset(&versionCompiled, 0, sizeof(versionCompiled));
10763 memset(&versionReported, 0, sizeof(versionReported));
10764
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010765 /* retrieve and display WCNSS version information */
10766 do {
10767
10768 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
10769 &versionCompiled);
10770 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10771 {
10772 hddLog(VOS_TRACE_LEVEL_FATAL,
10773 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010774 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010775 break;
10776 }
10777
10778 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
10779 &versionReported);
10780 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10781 {
10782 hddLog(VOS_TRACE_LEVEL_FATAL,
10783 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010784 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010785 break;
10786 }
10787
10788 if ((versionCompiled.major != versionReported.major) ||
10789 (versionCompiled.minor != versionReported.minor) ||
10790 (versionCompiled.version != versionReported.version) ||
10791 (versionCompiled.revision != versionReported.revision))
10792 {
10793 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
10794 "Host expected %u.%u.%u.%u\n",
10795 WLAN_MODULE_NAME,
10796 (int)versionReported.major,
10797 (int)versionReported.minor,
10798 (int)versionReported.version,
10799 (int)versionReported.revision,
10800 (int)versionCompiled.major,
10801 (int)versionCompiled.minor,
10802 (int)versionCompiled.version,
10803 (int)versionCompiled.revision);
10804 }
10805 else
10806 {
10807 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
10808 WLAN_MODULE_NAME,
10809 (int)versionReported.major,
10810 (int)versionReported.minor,
10811 (int)versionReported.version,
10812 (int)versionReported.revision);
10813 }
10814
10815 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
10816 versionString,
10817 sizeof(versionString));
10818 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10819 {
10820 hddLog(VOS_TRACE_LEVEL_FATAL,
10821 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010822 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010823 break;
10824 }
10825
10826 pr_info("%s: WCNSS software version %s\n",
10827 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +053010828 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010829
10830 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
10831 versionString,
10832 sizeof(versionString));
10833 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10834 {
10835 hddLog(VOS_TRACE_LEVEL_FATAL,
10836 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010837 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010838 break;
10839 }
10840
10841 pr_info("%s: WCNSS hardware version %s\n",
10842 WLAN_MODULE_NAME, versionString);
10843
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010844 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
10845 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010846 send the message only if it the riva is 1.1
10847 minor numbers for different riva branches:
10848 0 -> (1.0)Mainline Build
10849 1 -> (1.1)Mainline Build
10850 2->(1.04) Stability Build
10851 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010852 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010853 ((versionReported.minor>=1) && (versionReported.version>=1)))
10854 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
10855 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010856
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010857 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -080010858 {
10859#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
10860 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
10861 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
10862#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -070010863 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
10864 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
10865 {
10866 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
10867 }
10868
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010869 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -080010870 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010871
10872 } while (0);
10873
10874}
Neelansh Mittaledafed22014-09-04 18:54:39 +053010875void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
10876{
10877 struct sk_buff *skb;
10878 struct nlmsghdr *nlh;
10879 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053010880 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +053010881 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +053010882
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053010883 if (in_interrupt() || irqs_disabled() || in_atomic())
10884 flags = GFP_ATOMIC;
10885
10886 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +053010887
10888 if(skb == NULL) {
10889 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10890 "%s: alloc_skb failed", __func__);
10891 return;
10892 }
10893
10894 nlh = (struct nlmsghdr *)skb->data;
10895 nlh->nlmsg_pid = 0; /* from kernel */
10896 nlh->nlmsg_flags = 0;
10897 nlh->nlmsg_seq = 0;
10898 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
10899
10900 ani_hdr = NLMSG_DATA(nlh);
10901 ani_hdr->type = type;
10902
10903 switch(type) {
10904 case WLAN_SVC_SAP_RESTART_IND:
10905 ani_hdr->length = 0;
10906 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
10907 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
10908 break;
Bhargav Shahd0715912015-10-01 18:17:37 +053010909 case WLAN_SVC_WLAN_TP_IND:
10910 ani_hdr->length = len;
10911 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
10912 + len));
10913 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
10914 memcpy(nl_data, data, len);
10915 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
10916 break;
Bhargav shah23c94942015-10-13 12:48:35 +053010917 case WLAN_MSG_RPS_ENABLE_IND:
10918 ani_hdr->length = len;
10919 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
10920 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
10921 memcpy(nl_data, data, len);
10922 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
10923 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +053010924 default:
10925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10926 "Attempt to send unknown nlink message %d", type);
10927 kfree_skb(skb);
10928 return;
10929 }
10930
10931 nl_srv_bcast(skb);
10932
10933 return;
10934}
10935
Bhargav Shahd0715912015-10-01 18:17:37 +053010936/**
10937 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
10938 * @pHddCtx: Valid Global HDD context pointer
10939 * @rx_packets: Number of RX packet in perticular time
10940 *
10941 * Based on the RX packet this function calculate next value of tcp delack.
10942 * This function compare rx packet value to high and low threshold limit.
10943 *
10944 * Return: void
10945 */
10946void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
10947{
10948 /* average of rx_packets and prev_rx is taken so that
10949 bus width doesnot fluctuate much */
10950 uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
10951 TP_IND_TYPE next_rx_level = pHddCtx->cur_rx_level;
Neelansh Mittaledafed22014-09-04 18:54:39 +053010952
Bhargav Shahd0715912015-10-01 18:17:37 +053010953 pHddCtx->prev_rx = rx_packets;
10954 if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
10955 next_rx_level = TP_IND_HIGH;
10956 else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
10957 next_rx_level = TP_IND_LOW;
10958
10959 hdd_set_delack_value(pHddCtx, next_rx_level);
10960}
10961
10962#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))
10963
10964/**
10965 * hdd_tcp_delack_compute_function() - get link status
10966 * @priv: Valid Global HDD context pointer
10967 *
10968 * This function find number of RX packet during timer life span.
10969 * It request tcp delack with number of RX packet and re-configure delack timer
10970 * for tcpDelAckComputeInterval timer interval.
10971 *
10972 * Return: void
10973 */
10974void hdd_tcp_delack_compute_function(void *priv)
10975{
10976 hdd_context_t *pHddCtx = (hdd_context_t *)priv;
10977 hdd_adapter_t *pAdapter = NULL;
10978 v_U32_t rx_packets = 0;
10979 hdd_adapter_list_node_t *pAdapterNode = NULL;
10980 VOS_STATUS status = 0;
10981
10982 for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
10983 NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
10984 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
10985 if ((pAdapter = pAdapterNode->pAdapter) == NULL)
10986 continue;
10987
10988 rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
10989 pAdapter->prev_rx_packets);
10990 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
10991 }
10992
10993 hdd_request_tcp_delack(pHddCtx, rx_packets);
10994
10995 vos_timer_start(&pHddCtx->delack_timer,
10996 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
10997}
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010998
10999/**---------------------------------------------------------------------------
11000
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011001 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
11002
11003 \param - pHddCtx - Pointer to the hdd context
11004
11005 \return - true if hardware supports 5GHz
11006
11007 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +053011008boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011009{
11010 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
11011 * then hardware support 5Ghz.
11012 */
11013 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
11014 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053011015 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011016 return true;
11017 }
11018 else
11019 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053011020 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011021 __func__);
11022 return false;
11023 }
11024}
11025
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011026/**---------------------------------------------------------------------------
11027
11028 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
11029 generate function
11030
11031 This is generate the random mac address for WLAN interface
11032
11033 \param - pHddCtx - Pointer to HDD context
11034 idx - Start interface index to get auto
11035 generated mac addr.
11036 mac_addr - Mac address
11037
11038 \return - 0 for success, < 0 for failure
11039
11040 --------------------------------------------------------------------------*/
11041
11042static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
11043 int idx, v_MACADDR_t mac_addr)
11044{
11045 int i;
11046 unsigned int serialno;
11047 serialno = wcnss_get_serial_number();
11048
11049 if (0 != serialno)
11050 {
11051 /* MAC address has 3 bytes of OUI so we have a maximum of 3
11052 bytes of the serial number that can be used to generate
11053 the other 3 bytes of the MAC address. Mask off all but
11054 the lower 3 bytes (this will also make sure we don't
11055 overflow in the next step) */
11056 serialno &= 0x00FFFFFF;
11057
11058 /* we need a unique address for each session */
11059 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
11060
11061 /* autogen other Mac addresses */
11062 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
11063 {
11064 /* start with the entire default address */
11065 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
11066 /* then replace the lower 3 bytes */
11067 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
11068 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
11069 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
11070
11071 serialno++;
11072 hddLog(VOS_TRACE_LEVEL_ERROR,
11073 "%s: Derived Mac Addr: "
11074 MAC_ADDRESS_STR, __func__,
11075 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
11076 }
11077
11078 }
11079 else
11080 {
11081 hddLog(LOGE, FL("Failed to Get Serial NO"));
11082 return -1;
11083 }
11084 return 0;
11085}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011086
Katya Nigame7b69a82015-04-28 15:24:06 +053011087int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
11088{
11089 VOS_STATUS status;
11090 v_CONTEXT_t pVosContext= NULL;
11091 hdd_adapter_t *pAdapter= NULL;
11092
11093 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11094
11095 if (NULL == pVosContext)
11096 {
11097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11098 "%s: Trying to open VOSS without a PreOpen", __func__);
11099 VOS_ASSERT(0);
11100 return VOS_STATUS_E_FAILURE;
11101 }
11102
11103 status = vos_nv_open();
11104 if (!VOS_IS_STATUS_SUCCESS(status))
11105 {
11106 /* NV module cannot be initialized */
11107 hddLog( VOS_TRACE_LEVEL_FATAL,
11108 "%s: vos_nv_open failed", __func__);
11109 return VOS_STATUS_E_FAILURE;
11110 }
11111
11112 status = vos_init_wiphy_from_nv_bin();
11113 if (!VOS_IS_STATUS_SUCCESS(status))
11114 {
11115 /* NV module cannot be initialized */
11116 hddLog( VOS_TRACE_LEVEL_FATAL,
11117 "%s: vos_init_wiphy failed", __func__);
11118 goto err_vos_nv_close;
11119 }
11120
11121 status = vos_open( &pVosContext, pHddCtx->parent_dev);
11122 if ( !VOS_IS_STATUS_SUCCESS( status ))
11123 {
11124 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
11125 goto err_vos_nv_close;
11126 }
11127
11128 status = vos_mon_start( pVosContext );
11129 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11130 {
11131 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
11132 goto err_vosclose;
11133 }
11134
11135 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
11136 WDA_featureCapsExchange(pVosContext);
11137 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
11138
11139 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
11140 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
11141 if( pAdapter == NULL )
11142 {
11143 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
11144 goto err_close_adapter;
11145 }
11146
11147 //Initialize the nlink service
11148 if(nl_srv_init() != 0)
11149 {
11150 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
11151 goto err_close_adapter;
11152 }
11153 return VOS_STATUS_SUCCESS;
11154
11155err_close_adapter:
11156 hdd_close_all_adapters( pHddCtx );
11157 vos_mon_stop( pVosContext );
11158err_vosclose:
11159 status = vos_sched_close( pVosContext );
11160 if (!VOS_IS_STATUS_SUCCESS(status)) {
11161 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
11162 "%s: Failed to close VOSS Scheduler", __func__);
11163 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
11164 }
11165 vos_close(pVosContext );
11166
11167err_vos_nv_close:
11168 vos_nv_close();
11169
11170return status;
11171}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011172/**---------------------------------------------------------------------------
11173
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011174 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
11175 completed to flush out the scan results
11176
11177 11d scan is done during driver load and is a passive scan on all
11178 channels supported by the device, 11d scans may find some APs on
11179 frequencies which are forbidden to be used in the regulatory domain
11180 the device is operating in. If these APs are notified to the supplicant
11181 it may try to connect to these APs, thus flush out all the scan results
11182 which are present in SME after 11d scan is done.
11183
11184 \return - eHalStatus
11185
11186 --------------------------------------------------------------------------*/
11187static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
11188 tANI_U32 scanId, eCsrScanStatus status)
11189{
11190 ENTER();
11191
11192 sme_ScanFlushResult(halHandle, 0);
11193
11194 EXIT();
11195
11196 return eHAL_STATUS_SUCCESS;
11197}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011198/**---------------------------------------------------------------------------
11199
11200 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
11201 logging is completed successfully.
11202
11203 \return - None
11204
11205 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +053011206void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011207{
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011208 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011209
11210 if (NULL == pHddCtx)
11211 {
11212 hddLog(VOS_TRACE_LEVEL_ERROR,
11213 "%s: HDD context is NULL",__func__);
11214 return;
11215 }
11216
c_manjeecfd1efb2015-09-25 19:32:34 +053011217 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +053011218 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011219 {
11220 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
11221 pHddCtx->mgmt_frame_logging = TRUE;
11222 }
11223 else
11224 {
11225 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
11226 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +053011227 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011228 }
11229
c_manjeecfd1efb2015-09-25 19:32:34 +053011230 /*Check feature supported by FW*/
11231 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
11232 {
11233 //Store fwr mem dump size given by firmware.
11234 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
11235 }
11236 else
11237 {
11238 wlan_store_fwr_mem_dump_size(0);
11239 }
11240
11241
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011242}
11243/**---------------------------------------------------------------------------
11244
11245 \brief hdd_init_frame_logging - function to initialize frame logging.
11246 Currently only Mgmt Frames are logged in both TX
11247 and Rx direction and are sent to userspace
11248 application using logger thread when queried.
11249
11250 \return - None
11251
11252 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011253void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011254{
11255 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011256 tSirFWLoggingInitParam wlanFWLoggingInitParam = {0};
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011257
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011258 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
11259 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011260 {
11261 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
11262 return;
11263 }
11264
c_manjeecfd1efb2015-09-25 19:32:34 +053011265 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011266 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
11267 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +053011268 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
11269 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011270
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011271 if (pHddCtx->cfg_ini->enableFWLogging ||
11272 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011273 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011274 wlanFWLoggingInitParam.enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011275 }
11276
Sushant Kaushik46804902015-07-08 14:46:03 +053011277 if (pHddCtx->cfg_ini->enableMgmtLogging)
11278 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011279 wlanFWLoggingInitParam.enableFlag |= WLAN_FRAME_LOG_EN;
Sushant Kaushik46804902015-07-08 14:46:03 +053011280 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011281 if (pHddCtx->cfg_ini->enableBMUHWtracing)
11282 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011283 wlanFWLoggingInitParam.enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011284 }
c_manjeecfd1efb2015-09-25 19:32:34 +053011285 if(pHddCtx->cfg_ini->enableFwrMemDump &&
11286 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
11287 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011288 wlanFWLoggingInitParam.enableFlag |= WLAN_FW_MEM_DUMP_EN;
c_manjeecfd1efb2015-09-25 19:32:34 +053011289 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011290 if( wlanFWLoggingInitParam.enableFlag == 0 )
c_manjeecfd1efb2015-09-25 19:32:34 +053011291 {
11292 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
11293 return;
11294 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011295 wlanFWLoggingInitParam.frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
11296 wlanFWLoggingInitParam.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
11297 wlanFWLoggingInitParam.bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
11298 wlanFWLoggingInitParam.continuousFrameLogging =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011299 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011300
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011301 wlanFWLoggingInitParam.enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011302
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011303 wlanFWLoggingInitParam.minLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011304 pHddCtx->cfg_ini->minLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011305 wlanFWLoggingInitParam.maxLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011306 pHddCtx->cfg_ini->maxLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011307 wlanFWLoggingInitParam.fwlogInitCallback = hdd_init_frame_logging_done;
11308 wlanFWLoggingInitParam.fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011309
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011310 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, &wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011311
11312 if (eHAL_STATUS_SUCCESS != halStatus)
11313 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011314 hddLog(LOGE, FL("sme_InitMgmtFrameLogging failed, returned %d"),
11315 halStatus);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011316 }
11317
11318 return;
11319}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011320
Bhargav shah23c94942015-10-13 12:48:35 +053011321static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
11322{
11323 hdd_adapter_t *adapter;
11324 hdd_adapter_list_node_t *adapter_node, *next;
11325 VOS_STATUS status = VOS_STATUS_SUCCESS;
11326 struct wlan_rps_data rps_data;
11327 int count;
11328
11329 if(!hdd_ctxt->cfg_ini->rps_mask)
11330 {
11331 return;
11332 }
11333
11334 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
11335 {
11336 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
11337 }
11338
11339 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
11340
11341 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
11342 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
11343 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
11344
11345 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
11346
11347 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
11348 {
11349 adapter = adapter_node->pAdapter;
11350 if (NULL != adapter) {
11351 strlcpy(rps_data.ifname, adapter->dev->name,
11352 sizeof(rps_data.ifname));
11353 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
11354 (void *)&rps_data,sizeof(rps_data));
11355 }
11356 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
11357 adapter_node = next;
11358 }
11359}
11360
Masti, Narayanraddi26378462016-01-05 18:20:28 +053011361void wlan_hdd_schedule_defer_scan(struct work_struct *work)
11362{
11363 scan_context_t *scan_ctx =
11364 container_of(work, scan_context_t, scan_work.work);
11365
11366 if (NULL == scan_ctx)
11367 {
11368 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11369 FL("scan_ctx is NULL"));
11370 return;
11371 }
11372
11373 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
11374 return;
11375
11376 scan_ctx->attempt++;
11377
11378 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
11379#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11380 scan_ctx->dev,
11381#endif
11382 scan_ctx->scan_request);
11383}
11384
11385int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx,
11386 struct wiphy *wiphy,
11387#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11388 struct net_device *dev,
11389#endif
11390 struct cfg80211_scan_request *request)
11391{
11392 scan_context_t *scan_ctx;
11393
11394 ENTER();
11395 if (0 != (wlan_hdd_validate_context(pHddCtx)))
11396 {
11397 return -1;
11398 }
11399
11400 scan_ctx = &pHddCtx->scan_ctxt;
11401
11402 scan_ctx->wiphy = wiphy;
11403#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11404 scan_ctx->dev = dev;
11405#endif
11406
11407 scan_ctx->scan_request = request;
11408
11409 EXIT();
11410 return 0;
11411}
11412
11413void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
11414 struct wiphy *wiphy,
11415#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11416 struct net_device *dev,
11417#endif
11418 struct cfg80211_scan_request *request,
11419 unsigned long delay)
11420{
11421 if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic)
11422 {
11423#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11424 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request);
11425#else
11426 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request);
11427#endif
11428 pHddCtx->scan_ctxt.attempt = 0;
11429 pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC;
11430 }
11431 schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay);
11432}
11433
11434void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx)
11435{
11436 scan_ctx->magic = 0;
11437 scan_ctx->attempt = 0;
11438 scan_ctx->reject = 0;
11439 scan_ctx->scan_request = NULL;
11440
11441 return;
11442}
11443
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011444/**---------------------------------------------------------------------------
11445
Jeff Johnson295189b2012-06-20 16:38:30 -070011446 \brief hdd_wlan_startup() - HDD init function
11447
11448 This is the driver startup code executed once a WLAN device has been detected
11449
11450 \param - dev - Pointer to the underlying device
11451
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011452 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -070011453
11454 --------------------------------------------------------------------------*/
11455
11456int hdd_wlan_startup(struct device *dev )
11457{
11458 VOS_STATUS status;
11459 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011460 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011461 hdd_context_t *pHddCtx = NULL;
11462 v_CONTEXT_t pVosContext= NULL;
11463#ifdef WLAN_BTAMP_FEATURE
11464 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
11465 WLANBAP_ConfigType btAmpConfig;
11466 hdd_config_t *pConfig;
11467#endif
11468 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011469 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011470 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -070011471
11472 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011473 /*
11474 * cfg80211: wiphy allocation
11475 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011476 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070011477
11478 if(wiphy == NULL)
11479 {
11480 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011481 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011482 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011483 pHddCtx = wiphy_priv(wiphy);
11484
Jeff Johnson295189b2012-06-20 16:38:30 -070011485 //Initialize the adapter context to zeros.
11486 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
11487
Jeff Johnson295189b2012-06-20 16:38:30 -070011488 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011489 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +053011490 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011491
11492 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
11493
Siddharth Bhalcd92b782015-06-29 12:25:40 +053011494 /* register for riva power on lock to platform driver
11495 * Locking power early to ensure FW doesn't reset by kernel while
11496 * host driver is busy initializing itself */
11497 if (req_riva_power_on_lock("wlan"))
11498 {
11499 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
11500 __func__);
11501 goto err_free_hdd_context;
11502 }
11503
Jeff Johnson295189b2012-06-20 16:38:30 -070011504 /*Get vos context here bcoz vos_open requires it*/
11505 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11506
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -080011507 if(pVosContext == NULL)
11508 {
11509 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
11510 goto err_free_hdd_context;
11511 }
11512
Jeff Johnson295189b2012-06-20 16:38:30 -070011513 //Save the Global VOSS context in adapter context for future.
11514 pHddCtx->pvosContext = pVosContext;
11515
11516 //Save the adapter context in global context for future.
11517 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
11518
Jeff Johnson295189b2012-06-20 16:38:30 -070011519 pHddCtx->parent_dev = dev;
11520
11521 init_completion(&pHddCtx->full_pwr_comp_var);
11522 init_completion(&pHddCtx->standby_comp_var);
11523 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011524 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080011525 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +053011526 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053011527 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053011528 init_completion(&pHddCtx->mc_sus_event_var);
11529 init_completion(&pHddCtx->tx_sus_event_var);
11530 init_completion(&pHddCtx->rx_sus_event_var);
11531
Amar Singhala49cbc52013-10-08 18:37:44 -070011532
mukul sharma4bd8d2e2015-08-13 20:33:25 +053011533 hdd_init_ll_stats_ctx(pHddCtx);
11534
Amar Singhala49cbc52013-10-08 18:37:44 -070011535#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -070011536 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -070011537#else
11538 init_completion(&pHddCtx->driver_crda_req);
11539#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011540
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +053011541#ifdef WLAN_FEATURE_EXTSCAN
11542 init_completion(&pHddCtx->ext_scan_context.response_event);
11543#endif /* WLAN_FEATURE_EXTSCAN */
11544
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053011545 spin_lock_init(&pHddCtx->schedScan_lock);
11546
Jeff Johnson295189b2012-06-20 16:38:30 -070011547 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
11548
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053011549 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
11550 hdd_processSpoofMacAddrRequest);
11551
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011552#ifdef FEATURE_WLAN_TDLS
11553 /* tdls_lock is initialized before an hdd_open_adapter ( which is
11554 * invoked by other instances also) to protect the concurrent
11555 * access for the Adapters by TDLS module.
11556 */
11557 mutex_init(&pHddCtx->tdls_lock);
11558#endif
Siddharth Bhal76972212014-10-15 16:22:51 +053011559 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +053011560 mutex_init(&pHddCtx->wmmLock);
11561
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +053011562 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +053011563 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011564
Agarwal Ashish1f422872014-07-22 00:11:55 +053011565 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011566 // Load all config first as TL config is needed during vos_open
11567 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
11568 if(pHddCtx->cfg_ini == NULL)
11569 {
11570 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
11571 goto err_free_hdd_context;
11572 }
11573
11574 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
11575
11576 // Read and parse the qcom_cfg.ini file
11577 status = hdd_parse_config_ini( pHddCtx );
11578 if ( VOS_STATUS_SUCCESS != status )
11579 {
11580 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
11581 __func__, WLAN_INI_FILE);
11582 goto err_config;
11583 }
Arif Hussaind5218912013-12-05 01:10:55 -080011584#ifdef MEMORY_DEBUG
11585 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
11586 vos_mem_init();
11587
11588 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
11589 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
11590#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011591
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +053011592 /* INI has been read, initialise the configuredMcastBcastFilter with
11593 * INI value as this will serve as the default value
11594 */
11595 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
11596 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
11597 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011598
11599 if (false == hdd_is_5g_supported(pHddCtx))
11600 {
11601 //5Ghz is not supported.
11602 if (1 != pHddCtx->cfg_ini->nBandCapability)
11603 {
11604 hddLog(VOS_TRACE_LEVEL_INFO,
11605 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
11606 pHddCtx->cfg_ini->nBandCapability = 1;
11607 }
11608 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053011609
11610 /* If SNR Monitoring is enabled, FW has to parse all beacons
11611 * for calcaluting and storing the average SNR, so set Nth beacon
11612 * filter to 1 to enable FW to parse all the beaocons
11613 */
11614 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
11615 {
11616 /* The log level is deliberately set to WARN as overriding
11617 * nthBeaconFilter to 1 will increase power cosumption and this
11618 * might just prove helpful to detect the power issue.
11619 */
11620 hddLog(VOS_TRACE_LEVEL_WARN,
11621 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
11622 pHddCtx->cfg_ini->nthBeaconFilter = 1;
11623 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011624 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011625 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -070011626 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -080011627 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070011628 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -080011629 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
11630 {
11631 hddLog(VOS_TRACE_LEVEL_FATAL,
11632 "%s: wlan_hdd_cfg80211_init return failure", __func__);
11633 goto err_config;
11634 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011635 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011636
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011637 // Update VOS trace levels based upon the cfg.ini
11638 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
11639 pHddCtx->cfg_ini->vosTraceEnableBAP);
11640 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
11641 pHddCtx->cfg_ini->vosTraceEnableTL);
11642 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
11643 pHddCtx->cfg_ini->vosTraceEnableWDI);
11644 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
11645 pHddCtx->cfg_ini->vosTraceEnableHDD);
11646 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
11647 pHddCtx->cfg_ini->vosTraceEnableSME);
11648 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
11649 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +053011650 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
11651 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011652 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
11653 pHddCtx->cfg_ini->vosTraceEnableWDA);
11654 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
11655 pHddCtx->cfg_ini->vosTraceEnableSYS);
11656 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
11657 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011658 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
11659 pHddCtx->cfg_ini->vosTraceEnableSAP);
11660 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
11661 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011662
Jeff Johnson295189b2012-06-20 16:38:30 -070011663 // Update WDI trace levels based upon the cfg.ini
11664 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
11665 pHddCtx->cfg_ini->wdiTraceEnableDAL);
11666 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
11667 pHddCtx->cfg_ini->wdiTraceEnableCTL);
11668 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
11669 pHddCtx->cfg_ini->wdiTraceEnableDAT);
11670 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
11671 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -070011672
Jeff Johnson88ba7742013-02-27 14:36:02 -080011673 if (VOS_FTM_MODE == hdd_get_conparam())
11674 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011675 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
11676 {
11677 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
11678 goto err_free_hdd_context;
11679 }
11680 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +053011681 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +053011682 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011683 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -080011684 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011685
Katya Nigame7b69a82015-04-28 15:24:06 +053011686 if( VOS_MONITOR_MODE == hdd_get_conparam())
11687 {
11688 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
11689 {
11690 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
11691 goto err_free_hdd_context;
11692 }
11693 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
11694 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
11695 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
11696 return VOS_STATUS_SUCCESS;
11697 }
11698
Jeff Johnson88ba7742013-02-27 14:36:02 -080011699 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -070011700 if(pHddCtx->cfg_ini->fIsLogpEnabled)
11701 {
11702 status = vos_watchdog_open(pVosContext,
11703 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
11704
11705 if(!VOS_IS_STATUS_SUCCESS( status ))
11706 {
11707 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011708 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011709 }
11710 }
11711
11712 pHddCtx->isLogpInProgress = FALSE;
11713 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
11714
Amar Singhala49cbc52013-10-08 18:37:44 -070011715#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070011716 /* initialize the NV module. This is required so that
11717 we can initialize the channel information in wiphy
11718 from the NV.bin data. The channel information in
11719 wiphy needs to be initialized before wiphy registration */
11720
11721 status = vos_nv_open();
11722 if (!VOS_IS_STATUS_SUCCESS(status))
11723 {
11724 /* NV module cannot be initialized */
11725 hddLog( VOS_TRACE_LEVEL_FATAL,
11726 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +053011727 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -070011728 }
11729
11730 status = vos_init_wiphy_from_nv_bin();
11731 if (!VOS_IS_STATUS_SUCCESS(status))
11732 {
11733 /* NV module cannot be initialized */
11734 hddLog( VOS_TRACE_LEVEL_FATAL,
11735 "%s: vos_init_wiphy failed", __func__);
11736 goto err_vos_nv_close;
11737 }
11738
Amar Singhala49cbc52013-10-08 18:37:44 -070011739#endif
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053011740 //Initialize the nlink service
11741 if(nl_srv_init() != 0)
11742 {
11743 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
11744 goto err_vos_nv_close;
11745 }
11746
11747#ifdef WLAN_KD_READY_NOTIFIER
11748 pHddCtx->kd_nl_init = 1;
11749#endif /* WLAN_KD_READY_NOTIFIER */
11750
Girish Gowlibf0e1ab2015-01-19 16:05:16 +053011751 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053011752 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070011753 if ( !VOS_IS_STATUS_SUCCESS( status ))
11754 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011755 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053011756 goto err_nl_srv;
Jeff Johnson295189b2012-06-20 16:38:30 -070011757 }
11758
Jeff Johnson295189b2012-06-20 16:38:30 -070011759 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
11760
11761 if ( NULL == pHddCtx->hHal )
11762 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011763 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011764 goto err_vosclose;
11765 }
11766
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011767 status = vos_preStart( pHddCtx->pvosContext );
11768 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11769 {
11770 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011771 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011772 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011773
Arif Hussaineaf68602013-12-30 23:10:44 -080011774 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
11775 {
11776 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
11777 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
11778 __func__, enable_dfs_chan_scan);
11779 }
11780 if (0 == enable_11d || 1 == enable_11d)
11781 {
11782 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
11783 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
11784 __func__, enable_11d);
11785 }
11786
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011787 /* Note that the vos_preStart() sequence triggers the cfg download.
11788 The cfg download must occur before we update the SME config
11789 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -070011790 status = hdd_set_sme_config( pHddCtx );
11791
11792 if ( VOS_STATUS_SUCCESS != status )
11793 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011794 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011795 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011796 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011797
Jeff Johnson295189b2012-06-20 16:38:30 -070011798 /* In the integrated architecture we update the configuration from
11799 the INI file and from NV before vOSS has been started so that
11800 the final contents are available to send down to the cCPU */
11801
11802 // Apply the cfg.ini to cfg.dat
11803 if (FALSE == hdd_update_config_dat(pHddCtx))
11804 {
11805 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011806 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011807 }
11808
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011809 // Get mac addr from platform driver
11810 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
11811
11812 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011813 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011814 /* Store the mac addr for first interface */
11815 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
11816
11817 hddLog(VOS_TRACE_LEVEL_ERROR,
11818 "%s: WLAN Mac Addr: "
11819 MAC_ADDRESS_STR, __func__,
11820 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
11821
11822 /* Here, passing Arg2 as 1 because we do not want to change the
11823 last 3 bytes (means non OUI bytes) of first interface mac
11824 addr.
11825 */
11826 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
11827 {
11828 hddLog(VOS_TRACE_LEVEL_ERROR,
11829 "%s: Failed to generate wlan interface mac addr "
11830 "using MAC from ini file ", __func__);
11831 }
11832 }
11833 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
11834 {
11835 // Apply the NV to cfg.dat
11836 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070011837#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
11838 /* There was not a valid set of MAC Addresses in NV. See if the
11839 default addresses were modified by the cfg.ini settings. If so,
11840 we'll use them, but if not, we'll autogenerate a set of MAC
11841 addresses based upon the device serial number */
11842
11843 static const v_MACADDR_t default_address =
11844 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070011845
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011846 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
11847 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011848 {
11849 /* cfg.ini has the default address, invoke autogen logic */
11850
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011851 /* Here, passing Arg2 as 0 because we want to change the
11852 last 3 bytes (means non OUI bytes) of all the interfaces
11853 mac addr.
11854 */
11855 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
11856 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070011857 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011858 hddLog(VOS_TRACE_LEVEL_ERROR,
11859 "%s: Failed to generate wlan interface mac addr "
11860 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
11861 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070011862 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011863 }
11864 else
11865#endif //WLAN_AUTOGEN_MACADDR_FEATURE
11866 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011867 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011868 "%s: Invalid MAC address in NV, using MAC from ini file "
11869 MAC_ADDRESS_STR, __func__,
11870 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
11871 }
11872 }
11873 {
11874 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011875
11876 /* Set the MAC Address Currently this is used by HAL to
11877 * add self sta. Remove this once self sta is added as
11878 * part of session open.
11879 */
Jeff Johnson295189b2012-06-20 16:38:30 -070011880 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
11881 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
11882 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011883
Jeff Johnson295189b2012-06-20 16:38:30 -070011884 if (!HAL_STATUS_SUCCESS( halStatus ))
11885 {
11886 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
11887 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011888 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011889 }
11890 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011891
11892 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
11893 Note: Firmware image will be read and downloaded inside vos_start API */
11894 status = vos_start( pHddCtx->pvosContext );
11895 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11896 {
11897 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053011898 if (isSsrPanicOnFailure())
11899 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011900 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011901 }
11902
Leo Chang6cec3e22014-01-21 15:33:49 -080011903#ifdef FEATURE_WLAN_CH_AVOID
11904 /* Plug in avoid channel notification callback
11905 * This should happen before ADD_SELF_STA
11906 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053011907
11908 /* check the Channel Avoidance is enabled */
11909 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
11910 {
11911 sme_AddChAvoidCallback(pHddCtx->hHal,
11912 hdd_hostapd_ch_avoid_cb);
11913 }
Leo Chang6cec3e22014-01-21 15:33:49 -080011914#endif /* FEATURE_WLAN_CH_AVOID */
11915
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011916 /* Exchange capability info between Host and FW and also get versioning info from FW */
11917 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011918
Agarwal Ashishad9281b2014-06-10 14:57:30 +053011919#ifdef CONFIG_ENABLE_LINUX_REG
11920 status = wlan_hdd_init_channels(pHddCtx);
11921 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11922 {
11923 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
11924 __func__);
11925 goto err_vosstop;
11926 }
11927#endif
11928
Jeff Johnson295189b2012-06-20 16:38:30 -070011929 status = hdd_post_voss_start_config( pHddCtx );
11930 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11931 {
11932 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
11933 __func__);
11934 goto err_vosstop;
11935 }
Amar Singhala49cbc52013-10-08 18:37:44 -070011936
11937#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011938 wlan_hdd_cfg80211_update_reg_info( wiphy );
11939
11940 /* registration of wiphy dev with cfg80211 */
11941 if (0 > wlan_hdd_cfg80211_register(wiphy))
11942 {
11943 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
11944 goto err_vosstop;
11945 }
Amar Singhala49cbc52013-10-08 18:37:44 -070011946#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011947
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011948#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011949 /* registration of wiphy dev with cfg80211 */
11950 if (0 > wlan_hdd_cfg80211_register(wiphy))
11951 {
11952 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
11953 goto err_vosstop;
11954 }
11955
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011956 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011957 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11958 {
11959 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
11960 __func__);
11961 goto err_unregister_wiphy;
11962 }
11963#endif
11964
c_hpothu4a298be2014-12-22 21:12:51 +053011965 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
11966
Jeff Johnson295189b2012-06-20 16:38:30 -070011967 if (VOS_STA_SAP_MODE == hdd_get_conparam())
11968 {
11969 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
11970 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
11971 }
11972 else
11973 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011974 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
11975 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
11976 if (pAdapter != NULL)
11977 {
Katya Nigama7d81d72014-11-12 12:44:34 +053011978 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070011979 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053011980 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
11981 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
11982 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070011983
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053011984 /* Generate the P2P Device Address. This consists of the device's
11985 * primary MAC address with the locally administered bit set.
11986 */
11987 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070011988 }
11989 else
11990 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053011991 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
11992 if (p2p_dev_addr != NULL)
11993 {
11994 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
11995 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
11996 }
11997 else
11998 {
11999 hddLog(VOS_TRACE_LEVEL_FATAL,
12000 "%s: Failed to allocate mac_address for p2p_device",
12001 __func__);
12002 goto err_close_adapter;
12003 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012004 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012005
12006 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
12007 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
12008 if ( NULL == pP2pAdapter )
12009 {
12010 hddLog(VOS_TRACE_LEVEL_FATAL,
12011 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012012 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070012013 goto err_close_adapter;
12014 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012015 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012016 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012017
12018 if( pAdapter == NULL )
12019 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012020 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
12021 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070012022 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012023
Arif Hussain66559122013-11-21 10:11:40 -080012024 if (country_code)
12025 {
12026 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080012027 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080012028 hdd_checkandupdate_dfssetting(pAdapter, country_code);
12029#ifndef CONFIG_ENABLE_LINUX_REG
12030 hdd_checkandupdate_phymode(pAdapter, country_code);
12031#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080012032 ret = sme_ChangeCountryCode(pHddCtx->hHal,
12033 (void *)(tSmeChangeCountryCallback)
12034 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080012035 country_code,
12036 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012037 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080012038 if (eHAL_STATUS_SUCCESS == ret)
12039 {
Arif Hussaincb607082013-12-20 11:57:42 -080012040 ret = wait_for_completion_interruptible_timeout(
12041 &pAdapter->change_country_code,
12042 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
12043
12044 if (0 >= ret)
12045 {
12046 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12047 "%s: SME while setting country code timed out", __func__);
12048 }
Arif Hussain66559122013-11-21 10:11:40 -080012049 }
12050 else
12051 {
Arif Hussaincb607082013-12-20 11:57:42 -080012052 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12053 "%s: SME Change Country code from module param fail ret=%d",
12054 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080012055 }
12056 }
12057
Jeff Johnson295189b2012-06-20 16:38:30 -070012058#ifdef WLAN_BTAMP_FEATURE
12059 vStatus = WLANBAP_Open(pVosContext);
12060 if(!VOS_IS_STATUS_SUCCESS(vStatus))
12061 {
12062 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12063 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070012064 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070012065 }
12066
12067 vStatus = BSL_Init(pVosContext);
12068 if(!VOS_IS_STATUS_SUCCESS(vStatus))
12069 {
12070 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12071 "%s: Failed to Init BSL",__func__);
12072 goto err_bap_close;
12073 }
12074 vStatus = WLANBAP_Start(pVosContext);
12075 if (!VOS_IS_STATUS_SUCCESS(vStatus))
12076 {
12077 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12078 "%s: Failed to start TL",__func__);
12079 goto err_bap_close;
12080 }
12081
12082 pConfig = pHddCtx->cfg_ini;
12083 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
12084 status = WLANBAP_SetConfig(&btAmpConfig);
12085
12086#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070012087
Mihir Shete9c238772014-10-15 14:35:16 +053012088 /*
12089 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
12090 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
12091 * which is greater than 0xf. So the below check is safe to make
12092 * sure that there is no entry for UapsdMask in the ini
12093 */
12094 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
12095 {
12096 if(IS_DYNAMIC_WMM_PS_ENABLED)
12097 {
12098 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
12099 __func__);
12100 pHddCtx->cfg_ini->UapsdMask =
12101 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
12102 }
12103 else
12104 {
12105 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
12106 __func__);
12107 pHddCtx->cfg_ini->UapsdMask =
12108 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
12109 }
12110 }
12111
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070012112#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
12113 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
12114 {
12115 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
12116 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
12117 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
12118 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
12119 }
12120#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012121
Agarwal Ashish4b87f922014-06-18 03:03:21 +053012122 wlan_hdd_tdls_init(pHddCtx);
12123
Masti, Narayanraddi26378462016-01-05 18:20:28 +053012124 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
12125
12126 vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work,
12127 wlan_hdd_schedule_defer_scan);
12128
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053012129 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
12130
Jeff Johnson295189b2012-06-20 16:38:30 -070012131 /* Register with platform driver as client for Suspend/Resume */
12132 status = hddRegisterPmOps(pHddCtx);
12133 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12134 {
12135 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
12136#ifdef WLAN_BTAMP_FEATURE
12137 goto err_bap_stop;
12138#else
Jeff Johnsone7245742012-09-05 17:12:55 -070012139 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070012140#endif //WLAN_BTAMP_FEATURE
12141 }
12142
Yue Ma0d4891e2013-08-06 17:01:45 -070012143 /* Open debugfs interface */
12144 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
12145 {
12146 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12147 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070012148 }
12149
Jeff Johnson295189b2012-06-20 16:38:30 -070012150 /* Register TM level change handler function to the platform */
12151 status = hddDevTmRegisterNotifyCallback(pHddCtx);
12152 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12153 {
12154 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
12155 goto err_unregister_pmops;
12156 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012157
Jeff Johnson295189b2012-06-20 16:38:30 -070012158 // register net device notifier for device change notification
12159 ret = register_netdevice_notifier(&hdd_netdev_notifier);
12160
12161 if(ret < 0)
12162 {
12163 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053012164 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070012165 }
12166
Jeff Johnson295189b2012-06-20 16:38:30 -070012167 //Initialize the BTC service
12168 if(btc_activate_service(pHddCtx) != 0)
12169 {
12170 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012171 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070012172 }
12173
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053012174#ifdef FEATURE_OEM_DATA_SUPPORT
12175 //Initialize the OEM service
12176 if (oem_activate_service(pHddCtx) != 0)
12177 {
12178 hddLog(VOS_TRACE_LEVEL_FATAL,
12179 "%s: oem_activate_service failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012180 goto err_reg_netdev;
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053012181 }
12182#endif
12183
Jeff Johnson295189b2012-06-20 16:38:30 -070012184#ifdef PTT_SOCK_SVC_ENABLE
12185 //Initialize the PTT service
12186 if(ptt_sock_activate_svc(pHddCtx) != 0)
12187 {
12188 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012189 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070012190 }
12191#endif
12192
Abhishek Singh00b71972016-01-07 10:51:04 +053012193#ifdef WLAN_FEATURE_RMC
12194 if (hdd_open_cesium_nl_sock() < 0)
12195 {
12196 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
12197 goto err_reg_netdev;
12198 }
12199#endif
12200
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012201#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12202 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
12203 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053012204 if(wlan_logging_sock_activate_svc(
12205 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053012206 pHddCtx->cfg_ini->wlanLoggingNumBuf,
12207 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
12208 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053012209 {
12210 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
12211 " failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012212 goto err_reg_netdev;
Deepthi Gowri78083a32014-11-04 12:55:51 +053012213 }
12214 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
12215 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053012216 if (!pHddCtx->cfg_ini->gEnableDebugLog)
12217 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053012218 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
12219 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012220 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012221
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012222 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
12223 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053012224 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053012225 pHddCtx->cfg_ini->enableContFWLogging ||
12226 pHddCtx->cfg_ini->enableFwrMemDump )
12227 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012228 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012229 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012230 }
12231 else
12232 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012233 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012234 }
12235
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012236#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012237
12238
Sushant Kaushik215778f2015-05-21 14:05:36 +053012239 if (vos_is_multicast_logging())
12240 wlan_logging_set_log_level();
12241
Jeff Johnson295189b2012-06-20 16:38:30 -070012242 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012243 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070012244 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070012245 /* Action frame registered in one adapter which will
12246 * applicable to all interfaces
12247 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053012248 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012249 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012250
12251 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053012252 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012253
Jeff Johnsone7245742012-09-05 17:12:55 -070012254#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
12255 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012256 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070012257 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012258
Jeff Johnsone7245742012-09-05 17:12:55 -070012259#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012260 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012261 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012262 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012263
Jeff Johnsone7245742012-09-05 17:12:55 -070012264
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012265 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
12266 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012267
Katya Nigam5c306ea2014-06-19 15:39:54 +053012268 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012269 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012270 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053012271
12272#ifdef FEATURE_WLAN_SCAN_PNO
12273 /*SME must send channel update configuration to RIVA*/
12274 sme_UpdateChannelConfig(pHddCtx->hHal);
12275#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053012276 /* Send the update default channel list to the FW*/
12277 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053012278
12279 /* Fwr capabilities received, Set the Dot11 mode */
Abhishek Singh41ebce12016-02-03 10:43:21 +053012280 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
12281 hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode));
Mukul Sharma45063942015-04-01 20:07:59 +053012282 sme_SetDefDot11Mode(pHddCtx->hHal);
12283
Abhishek Singha306a442013-11-07 18:39:01 +053012284#ifndef CONFIG_ENABLE_LINUX_REG
12285 /*updating wiphy so that regulatory user hints can be processed*/
12286 if (wiphy)
12287 {
12288 regulatory_hint(wiphy, "00");
12289 }
12290#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012291 // Initialize the restart logic
12292 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053012293
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012294 //Register the traffic monitor timer now
12295 if ( pHddCtx->cfg_ini->dynSplitscan)
12296 {
12297 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
12298 VOS_TIMER_TYPE_SW,
12299 hdd_tx_rx_pkt_cnt_stat_timer_handler,
12300 (void *)pHddCtx);
12301 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053012302 wlan_hdd_cfg80211_nan_init(pHddCtx);
12303
Bhargav Shahd0715912015-10-01 18:17:37 +053012304 mutex_init(&pHddCtx->cur_rx_level_lock);
12305 vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
12306 hdd_tcp_delack_compute_function,(void *)pHddCtx);
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012307 vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW,
12308 wlan_hdd_change_tdls_mode, (void *)pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +053012309
Dino Mycle6fb96c12014-06-10 11:52:40 +053012310#ifdef WLAN_FEATURE_EXTSCAN
12311 sme_EXTScanRegisterCallback(pHddCtx->hHal,
12312 wlan_hdd_cfg80211_extscan_callback,
12313 pHddCtx);
12314#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012315
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053012316#ifdef FEATURE_OEM_DATA_SUPPORT
12317 sme_OemDataRegisterCallback(pHddCtx->hHal,
12318 wlan_hdd_cfg80211_oemdata_callback,
12319 pHddCtx);
12320#endif /* FEATURE_OEM_DATA_SUPPORT */
12321
Gupta, Kapil7c34b322015-09-30 13:12:35 +053012322 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012323#ifdef WLAN_NS_OFFLOAD
12324 // Register IPv6 notifier to notify if any change in IP
12325 // So that we can reconfigure the offload parameters
12326 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
12327 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
12328 if (ret)
12329 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012330 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012331 }
12332 else
12333 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012334 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012335 }
12336#endif
12337
12338 // Register IPv4 notifier to notify if any change in IP
12339 // So that we can reconfigure the offload parameters
12340 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
12341 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
12342 if (ret)
12343 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012344 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012345 }
12346 else
12347 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012348 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012349 }
c_manjeecfd1efb2015-09-25 19:32:34 +053012350 /*Fw mem dump procfs initialization*/
12351 memdump_init();
Bhargav shah23c94942015-10-13 12:48:35 +053012352 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012353
Jeff Johnson295189b2012-06-20 16:38:30 -070012354 goto success;
12355
Jeff Johnson295189b2012-06-20 16:38:30 -070012356err_reg_netdev:
12357 unregister_netdevice_notifier(&hdd_netdev_notifier);
12358
Jeff Johnson295189b2012-06-20 16:38:30 -070012359err_unregister_pmops:
12360 hddDevTmUnregisterNotifyCallback(pHddCtx);
12361 hddDeregisterPmOps(pHddCtx);
12362
Yue Ma0d4891e2013-08-06 17:01:45 -070012363 hdd_debugfs_exit(pHddCtx);
12364
Jeff Johnson295189b2012-06-20 16:38:30 -070012365#ifdef WLAN_BTAMP_FEATURE
12366err_bap_stop:
12367 WLANBAP_Stop(pVosContext);
12368#endif
12369
12370#ifdef WLAN_BTAMP_FEATURE
12371err_bap_close:
12372 WLANBAP_Close(pVosContext);
12373#endif
12374
Jeff Johnson295189b2012-06-20 16:38:30 -070012375err_close_adapter:
12376 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053012377#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012378err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053012379#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053012380 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012381 hdd_wlan_free_wiphy_channels(wiphy);
12382
Jeff Johnson295189b2012-06-20 16:38:30 -070012383err_vosstop:
12384 vos_stop(pVosContext);
12385
Amar Singhala49cbc52013-10-08 18:37:44 -070012386err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070012387 status = vos_sched_close( pVosContext );
12388 if (!VOS_IS_STATUS_SUCCESS(status)) {
12389 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12390 "%s: Failed to close VOSS Scheduler", __func__);
12391 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
12392 }
Amar Singhala49cbc52013-10-08 18:37:44 -070012393 vos_close(pVosContext );
12394
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012395err_nl_srv:
12396#ifdef WLAN_KD_READY_NOTIFIER
12397 nl_srv_exit(pHddCtx->ptt_pid);
12398#else
12399 nl_srv_exit();
12400#endif /* WLAN_KD_READY_NOTIFIER */
Amar Singhal0a402232013-10-11 20:57:16 -070012401err_vos_nv_close:
12402
c_hpothue6a36282014-03-19 12:27:38 +053012403#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070012404 vos_nv_close();
12405
c_hpothu70f8d812014-03-22 22:59:23 +053012406#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012407
12408err_wdclose:
12409 if(pHddCtx->cfg_ini->fIsLogpEnabled)
12410 vos_watchdog_close(pVosContext);
12411
Jeff Johnson295189b2012-06-20 16:38:30 -070012412err_config:
12413 kfree(pHddCtx->cfg_ini);
12414 pHddCtx->cfg_ini= NULL;
12415
12416err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012417 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053012418 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070012419 wiphy_free(wiphy) ;
12420 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070012421 VOS_BUG(1);
12422
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080012423 if (hdd_is_ssr_required())
12424 {
12425 /* WDI timeout had happened during load, so SSR is needed here */
12426 subsystem_restart("wcnss");
12427 msleep(5000);
12428 }
12429 hdd_set_ssr_required (VOS_FALSE);
12430
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012431 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012432
12433success:
12434 EXIT();
12435 return 0;
12436}
12437
12438/**---------------------------------------------------------------------------
12439
Jeff Johnson32d95a32012-09-10 13:15:23 -070012440 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070012441
Jeff Johnson32d95a32012-09-10 13:15:23 -070012442 This is the driver entry point - called in different timeline depending
12443 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070012444
12445 \param - None
12446
12447 \return - 0 for success, non zero for failure
12448
12449 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070012450static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070012451{
12452 VOS_STATUS status;
12453 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012454 struct device *dev = NULL;
12455 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012456#ifdef HAVE_WCNSS_CAL_DOWNLOAD
12457 int max_retries = 0;
12458#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012459#ifdef HAVE_CBC_DONE
12460 int max_cbc_retries = 0;
12461#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012462
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012463#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12464 wlan_logging_sock_init_svc();
12465#endif
12466
Jeff Johnson295189b2012-06-20 16:38:30 -070012467 ENTER();
12468
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012469 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070012470
12471 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
12472 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
12473
Jeff Johnson295189b2012-06-20 16:38:30 -070012474#ifdef ANI_BUS_TYPE_PCI
12475
12476 dev = wcnss_wlan_get_device();
12477
12478#endif // ANI_BUS_TYPE_PCI
12479
12480#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012481
12482#ifdef HAVE_WCNSS_CAL_DOWNLOAD
12483 /* wait until WCNSS driver downloads NV */
12484 while (!wcnss_device_ready() && 5 >= ++max_retries) {
12485 msleep(1000);
12486 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012487
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012488 if (max_retries >= 5) {
12489 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012490 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012491#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12492 wlan_logging_sock_deinit_svc();
12493#endif
12494
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012495 return -ENODEV;
12496 }
12497#endif
12498
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012499#ifdef HAVE_CBC_DONE
12500 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
12501 msleep(1000);
12502 }
12503 if (max_cbc_retries >= 10) {
12504 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
12505 }
12506#endif
12507
Jeff Johnson295189b2012-06-20 16:38:30 -070012508 dev = wcnss_wlan_get_device();
12509#endif // ANI_BUS_TYPE_PLATFORM
12510
12511
12512 do {
12513 if (NULL == dev) {
12514 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
12515 ret_status = -1;
12516 break;
12517 }
12518
Jeff Johnson295189b2012-06-20 16:38:30 -070012519#ifdef TIMER_MANAGER
12520 vos_timer_manager_init();
12521#endif
12522
12523 /* Preopen VOSS so that it is ready to start at least SAL */
12524 status = vos_preOpen(&pVosContext);
12525
12526 if (!VOS_IS_STATUS_SUCCESS(status))
12527 {
12528 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
12529 ret_status = -1;
12530 break;
12531 }
12532
Sushant Kaushik02beb352015-06-04 15:15:01 +053012533 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053012534 hdd_register_debug_callback();
12535
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012536#ifndef MODULE
12537 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
12538 */
12539 hdd_set_conparam((v_UINT_t)con_mode);
12540#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012541
12542 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012543 if (hdd_wlan_startup(dev))
12544 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012545 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012546 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012547 vos_preClose( &pVosContext );
12548 ret_status = -1;
12549 break;
12550 }
12551
Jeff Johnson295189b2012-06-20 16:38:30 -070012552 } while (0);
12553
12554 if (0 != ret_status)
12555 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012556#ifdef TIMER_MANAGER
12557 vos_timer_exit();
12558#endif
12559#ifdef MEMORY_DEBUG
12560 vos_mem_exit();
12561#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012562 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012563#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12564 wlan_logging_sock_deinit_svc();
12565#endif
12566
Jeff Johnson295189b2012-06-20 16:38:30 -070012567 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
12568 }
12569 else
12570 {
12571 //Send WLAN UP indication to Nlink Service
12572 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
12573
12574 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070012575 }
12576
12577 EXIT();
12578
12579 return ret_status;
12580}
12581
Jeff Johnson32d95a32012-09-10 13:15:23 -070012582/**---------------------------------------------------------------------------
12583
12584 \brief hdd_module_init() - Init Function
12585
12586 This is the driver entry point (invoked when module is loaded using insmod)
12587
12588 \param - None
12589
12590 \return - 0 for success, non zero for failure
12591
12592 --------------------------------------------------------------------------*/
12593#ifdef MODULE
12594static int __init hdd_module_init ( void)
12595{
12596 return hdd_driver_init();
12597}
Jeff Johnson32d95a32012-09-10 13:15:23 -070012598#else /* #ifdef MODULE */
12599static int __init hdd_module_init ( void)
12600{
12601 /* Driver initialization is delayed to fwpath_changed_handler */
12602 return 0;
12603}
Jeff Johnson32d95a32012-09-10 13:15:23 -070012604#endif /* #ifdef MODULE */
12605
Jeff Johnson295189b2012-06-20 16:38:30 -070012606
12607/**---------------------------------------------------------------------------
12608
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012609 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070012610
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012611 This is the driver exit point (invoked when module is unloaded using rmmod
12612 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070012613
12614 \param - None
12615
12616 \return - None
12617
12618 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012619static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070012620{
12621 hdd_context_t *pHddCtx = NULL;
12622 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053012623 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053012624 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012625
12626 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
12627
12628 //Get the global vos context
12629 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12630
12631 if(!pVosContext)
12632 {
12633 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
12634 goto done;
12635 }
12636
12637 //Get the HDD context.
12638 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
12639
12640 if(!pHddCtx)
12641 {
12642 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
12643 }
Katya Nigame7b69a82015-04-28 15:24:06 +053012644 else if (VOS_MONITOR_MODE == hdd_get_conparam())
12645 {
12646 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
12647 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
12648 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
12649 hdd_wlan_exit(pHddCtx);
12650 vos_preClose( &pVosContext );
12651 goto done;
12652 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012653 else
12654 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053012655 /* We wait for active entry threads to exit from driver
12656 * by waiting until rtnl_lock is available.
12657 */
12658 rtnl_lock();
12659 rtnl_unlock();
12660
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012661 INIT_COMPLETION(pHddCtx->ssr_comp_var);
12662 if ((pHddCtx->isLogpInProgress) && (FALSE ==
12663 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
12664 {
Siddharth Bhala204f572015-01-17 02:03:36 +053012665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012666 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053012667 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
12668 msecs_to_jiffies(30000));
12669 if(!rc)
12670 {
12671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12672 "%s:SSR timedout, fatal error", __func__);
12673 VOS_BUG(0);
12674 }
12675 }
12676
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012677 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
12678 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012679
c_hpothu8adb97b2014-12-08 19:38:20 +053012680 /* Driver Need to send country code 00 in below condition
12681 * 1) If gCountryCodePriority is set to 1; and last country
12682 * code set is through 11d. This needs to be done in case
12683 * when NV country code is 00.
12684 * This Needs to be done as when kernel store last country
12685 * code and if stored country code is not through 11d,
12686 * in sme_HandleChangeCountryCodeByUser we will disable 11d
12687 * in next load/unload as soon as we get any country through
12688 * 11d. In sme_HandleChangeCountryCodeByUser
12689 * pMsg->countryCode will be last countryCode and
12690 * pMac->scan.countryCode11d will be country through 11d so
12691 * due to mismatch driver will disable 11d.
12692 *
12693 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053012694
c_hpothu8adb97b2014-12-08 19:38:20 +053012695 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053012696 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053012697 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053012698 {
12699 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053012700 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053012701 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
12702 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053012703
c_hpothu8adb97b2014-12-08 19:38:20 +053012704 //Do all the cleanup before deregistering the driver
12705 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012706 }
12707
Jeff Johnson295189b2012-06-20 16:38:30 -070012708 vos_preClose( &pVosContext );
12709
12710#ifdef TIMER_MANAGER
12711 vos_timer_exit();
12712#endif
12713#ifdef MEMORY_DEBUG
12714 vos_mem_exit();
12715#endif
12716
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012717#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12718 wlan_logging_sock_deinit_svc();
12719#endif
12720
Jeff Johnson295189b2012-06-20 16:38:30 -070012721done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012722 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012723
Jeff Johnson295189b2012-06-20 16:38:30 -070012724 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
12725}
12726
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012727/**---------------------------------------------------------------------------
12728
12729 \brief hdd_module_exit() - Exit function
12730
12731 This is the driver exit point (invoked when module is unloaded using rmmod)
12732
12733 \param - None
12734
12735 \return - None
12736
12737 --------------------------------------------------------------------------*/
12738static void __exit hdd_module_exit(void)
12739{
12740 hdd_driver_exit();
12741}
12742
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012743#ifdef MODULE
12744static int fwpath_changed_handler(const char *kmessage,
12745 struct kernel_param *kp)
12746{
Jeff Johnson76052702013-04-16 13:55:05 -070012747 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012748}
12749
12750static int con_mode_handler(const char *kmessage,
12751 struct kernel_param *kp)
12752{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070012753 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012754}
12755#else /* #ifdef MODULE */
12756/**---------------------------------------------------------------------------
12757
Jeff Johnson76052702013-04-16 13:55:05 -070012758 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012759
Jeff Johnson76052702013-04-16 13:55:05 -070012760 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012761 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070012762 - invoked when module parameter fwpath is modified from userspace to signal
12763 initializing the WLAN driver or when con_mode is modified from userspace
12764 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012765
12766 \return - 0 for success, non zero for failure
12767
12768 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070012769static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012770{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070012771 int ret_status;
12772
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012773 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070012774 ret_status = hdd_driver_init();
12775 wlan_hdd_inited = ret_status ? 0 : 1;
12776 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012777 }
12778
12779 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070012780
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012781 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070012782
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070012783 ret_status = hdd_driver_init();
12784 wlan_hdd_inited = ret_status ? 0 : 1;
12785 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012786}
12787
Jeff Johnson295189b2012-06-20 16:38:30 -070012788/**---------------------------------------------------------------------------
12789
Jeff Johnson76052702013-04-16 13:55:05 -070012790 \brief fwpath_changed_handler() - Handler Function
12791
12792 Handle changes to the fwpath parameter
12793
12794 \return - 0 for success, non zero for failure
12795
12796 --------------------------------------------------------------------------*/
12797static int fwpath_changed_handler(const char *kmessage,
12798 struct kernel_param *kp)
12799{
12800 int ret;
12801
12802 ret = param_set_copystring(kmessage, kp);
12803 if (0 == ret)
12804 ret = kickstart_driver();
12805 return ret;
12806}
12807
12808/**---------------------------------------------------------------------------
12809
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012810 \brief con_mode_handler() -
12811
12812 Handler function for module param con_mode when it is changed by userspace
12813 Dynamically linked - do nothing
12814 Statically linked - exit and init driver, as in rmmod and insmod
12815
Jeff Johnson76052702013-04-16 13:55:05 -070012816 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012817
Jeff Johnson76052702013-04-16 13:55:05 -070012818 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012819
12820 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070012821static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012822{
Jeff Johnson76052702013-04-16 13:55:05 -070012823 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012824
Jeff Johnson76052702013-04-16 13:55:05 -070012825 ret = param_set_int(kmessage, kp);
12826 if (0 == ret)
12827 ret = kickstart_driver();
12828 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012829}
12830#endif /* #ifdef MODULE */
12831
12832/**---------------------------------------------------------------------------
12833
Jeff Johnson295189b2012-06-20 16:38:30 -070012834 \brief hdd_get_conparam() -
12835
12836 This is the driver exit point (invoked when module is unloaded using rmmod)
12837
12838 \param - None
12839
12840 \return - tVOS_CON_MODE
12841
12842 --------------------------------------------------------------------------*/
12843tVOS_CON_MODE hdd_get_conparam ( void )
12844{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012845#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070012846 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012847#else
12848 return (tVOS_CON_MODE)curr_con_mode;
12849#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012850}
12851void hdd_set_conparam ( v_UINT_t newParam )
12852{
12853 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012854#ifndef MODULE
12855 curr_con_mode = con_mode;
12856#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012857}
12858/**---------------------------------------------------------------------------
12859
12860 \brief hdd_softap_sta_deauth() - function
12861
12862 This to take counter measure to handle deauth req from HDD
12863
12864 \param - pAdapter - Pointer to the HDD
12865
12866 \param - enable - boolean value
12867
12868 \return - None
12869
12870 --------------------------------------------------------------------------*/
12871
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012872VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
12873 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070012874{
Jeff Johnson295189b2012-06-20 16:38:30 -070012875 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012876 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070012877
12878 ENTER();
12879
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012880 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
12881 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070012882
12883 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012884 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012885 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070012886
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012887 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070012888
12889 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012890 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070012891}
12892
12893/**---------------------------------------------------------------------------
12894
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012895 \brief hdd_del_all_sta() - function
12896
12897 This function removes all the stations associated on stopping AP/P2P GO.
12898
12899 \param - pAdapter - Pointer to the HDD
12900
12901 \return - None
12902
12903 --------------------------------------------------------------------------*/
12904
12905int hdd_del_all_sta(hdd_adapter_t *pAdapter)
12906{
12907 v_U16_t i;
12908 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012909 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12910 ptSapContext pSapCtx = NULL;
12911 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12912 if(pSapCtx == NULL){
12913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12914 FL("psapCtx is NULL"));
12915 return 1;
12916 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012917 ENTER();
12918
12919 hddLog(VOS_TRACE_LEVEL_INFO,
12920 "%s: Delete all STAs associated.",__func__);
12921 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
12922 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
12923 )
12924 {
12925 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
12926 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012927 if ((pSapCtx->aStaInfo[i].isUsed) &&
12928 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012929 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012930 struct tagCsrDelStaParams delStaParams;
12931
12932 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012933 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053012934 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
12935 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012936 &delStaParams);
12937 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012938 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012939 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012940 }
12941 }
12942 }
12943
12944 EXIT();
12945 return 0;
12946}
12947
12948/**---------------------------------------------------------------------------
12949
Jeff Johnson295189b2012-06-20 16:38:30 -070012950 \brief hdd_softap_sta_disassoc() - function
12951
12952 This to take counter measure to handle deauth req from HDD
12953
12954 \param - pAdapter - Pointer to the HDD
12955
12956 \param - enable - boolean value
12957
12958 \return - None
12959
12960 --------------------------------------------------------------------------*/
12961
12962void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
12963{
12964 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12965
12966 ENTER();
12967
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053012968 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070012969
12970 //Ignore request to disassoc bcmc station
12971 if( pDestMacAddress[0] & 0x1 )
12972 return;
12973
12974 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
12975}
12976
12977void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
12978{
12979 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12980
12981 ENTER();
12982
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053012983 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070012984
12985 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
12986}
12987
Jeff Johnson295189b2012-06-20 16:38:30 -070012988/**---------------------------------------------------------------------------
12989 *
12990 * \brief hdd_get__concurrency_mode() -
12991 *
12992 *
12993 * \param - None
12994 *
12995 * \return - CONCURRENCY MODE
12996 *
12997 * --------------------------------------------------------------------------*/
12998tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
12999{
13000 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
13001 hdd_context_t *pHddCtx;
13002
13003 if (NULL != pVosContext)
13004 {
13005 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
13006 if (NULL != pHddCtx)
13007 {
13008 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
13009 }
13010 }
13011
13012 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013013 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013014 return VOS_STA;
13015}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013016v_BOOL_t
13017wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
13018{
13019 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013020
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013021 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
13022 if (pAdapter == NULL)
13023 {
13024 hddLog(VOS_TRACE_LEVEL_INFO,
13025 FL("GO doesn't exist"));
13026 return TRUE;
13027 }
13028 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
13029 {
13030 hddLog(VOS_TRACE_LEVEL_INFO,
13031 FL("GO started"));
13032 return TRUE;
13033 }
13034 else
13035 /* wait till GO changes its interface to p2p device */
13036 hddLog(VOS_TRACE_LEVEL_INFO,
13037 FL("Del_bss called, avoid apps suspend"));
13038 return FALSE;
13039
13040}
Jeff Johnson295189b2012-06-20 16:38:30 -070013041/* Decide whether to allow/not the apps power collapse.
13042 * Allow apps power collapse if we are in connected state.
13043 * if not, allow only if we are in IMPS */
13044v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
13045{
13046 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080013047 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080013048 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070013049 hdd_config_t *pConfig = pHddCtx->cfg_ini;
13050 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13051 hdd_adapter_t *pAdapter = NULL;
13052 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080013053 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013054
Jeff Johnson295189b2012-06-20 16:38:30 -070013055 if (VOS_STA_SAP_MODE == hdd_get_conparam())
13056 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013057
Yathish9f22e662012-12-10 14:21:35 -080013058 concurrent_state = hdd_get_concurrency_mode();
13059
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013060 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
13061 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
13062 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080013063#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013064
Yathish9f22e662012-12-10 14:21:35 -080013065 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013066 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080013067 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
13068 return TRUE;
13069#endif
13070
Jeff Johnson295189b2012-06-20 16:38:30 -070013071 /*loop through all adapters. TBD fix for Concurrency */
13072 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13073 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13074 {
13075 pAdapter = pAdapterNode->pAdapter;
13076 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
13077 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
13078 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080013079 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053013080 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053013081 && pmcState != STOPPED && pmcState != STANDBY &&
13082 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080013083 (eANI_BOOLEAN_TRUE == scanRspPending) ||
13084 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070013085 {
Mukul Sharma4be88422015-03-09 20:29:07 +053013086 if(pmcState == FULL_POWER &&
13087 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
13088 {
13089 /*
13090 * When SCO indication comes from Coex module , host will
13091 * enter in to full power mode, but this should not prevent
13092 * apps processor power collapse.
13093 */
13094 hddLog(LOG1,
13095 FL("Allow apps power collapse"
13096 "even when sco indication is set"));
13097 return TRUE;
13098 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080013099 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080013100 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
13101 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070013102 return FALSE;
13103 }
13104 }
13105 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13106 pAdapterNode = pNext;
13107 }
13108 return TRUE;
13109}
13110
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080013111/* Decides whether to send suspend notification to Riva
13112 * if any adapter is in BMPS; then it is required */
13113v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
13114{
13115 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
13116 hdd_config_t *pConfig = pHddCtx->cfg_ini;
13117
13118 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
13119 {
13120 return TRUE;
13121 }
13122 return FALSE;
13123}
13124
Jeff Johnson295189b2012-06-20 16:38:30 -070013125void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13126{
13127 switch(mode)
13128 {
Chilam Ngc4244af2013-04-01 15:37:32 -070013129 case VOS_STA_MODE:
13130 case VOS_P2P_CLIENT_MODE:
13131 case VOS_P2P_GO_MODE:
13132 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070013133 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053013134 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070013135 break;
13136 default:
13137 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070013138 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053013139 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
13140 "Number of open sessions for mode %d = %d"),
13141 pHddCtx->concurrency_mode, mode,
13142 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070013143}
13144
13145
13146void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13147{
13148 switch(mode)
13149 {
Chilam Ngc4244af2013-04-01 15:37:32 -070013150 case VOS_STA_MODE:
13151 case VOS_P2P_CLIENT_MODE:
13152 case VOS_P2P_GO_MODE:
13153 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053013154 pHddCtx->no_of_open_sessions[mode]--;
13155 if (!(pHddCtx->no_of_open_sessions[mode]))
13156 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013157 break;
13158 default:
13159 break;
13160 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053013161 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
13162 "Number of open sessions for mode %d = %d"),
13163 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
13164
13165}
13166/**---------------------------------------------------------------------------
13167 *
13168 * \brief wlan_hdd_incr_active_session()
13169 *
13170 * This function increments the number of active sessions
13171 * maintained per device mode
13172 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
13173 * Incase of SAP/P2P GO upon bss start it is incremented
13174 *
13175 * \param pHddCtx - HDD Context
13176 * \param mode - device mode
13177 *
13178 * \return - None
13179 *
13180 * --------------------------------------------------------------------------*/
13181void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13182{
13183 switch (mode) {
13184 case VOS_STA_MODE:
13185 case VOS_P2P_CLIENT_MODE:
13186 case VOS_P2P_GO_MODE:
13187 case VOS_STA_SAP_MODE:
13188 pHddCtx->no_of_active_sessions[mode]++;
13189 break;
13190 default:
13191 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
13192 break;
13193 }
13194 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
13195 mode,
13196 pHddCtx->no_of_active_sessions[mode]);
13197}
13198
13199/**---------------------------------------------------------------------------
13200 *
13201 * \brief wlan_hdd_decr_active_session()
13202 *
13203 * This function decrements the number of active sessions
13204 * maintained per device mode
13205 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
13206 * Incase of SAP/P2P GO upon bss stop it is decremented
13207 *
13208 * \param pHddCtx - HDD Context
13209 * \param mode - device mode
13210 *
13211 * \return - None
13212 *
13213 * --------------------------------------------------------------------------*/
13214void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13215{
Bhargav Shahd0715912015-10-01 18:17:37 +053013216
Agarwal Ashish51325b52014-06-16 16:50:49 +053013217 switch (mode) {
13218 case VOS_STA_MODE:
13219 case VOS_P2P_CLIENT_MODE:
13220 case VOS_P2P_GO_MODE:
13221 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053013222 if (pHddCtx->no_of_active_sessions[mode] > 0)
13223 pHddCtx->no_of_active_sessions[mode]--;
13224 else
13225 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
13226 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053013227 break;
13228 default:
13229 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
13230 break;
13231 }
13232 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
13233 mode,
13234 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070013235}
13236
Jeff Johnsone7245742012-09-05 17:12:55 -070013237/**---------------------------------------------------------------------------
13238 *
13239 * \brief wlan_hdd_restart_init
13240 *
13241 * This function initalizes restart timer/flag. An internal function.
13242 *
13243 * \param - pHddCtx
13244 *
13245 * \return - None
13246 *
13247 * --------------------------------------------------------------------------*/
13248
13249static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
13250{
13251 /* Initialize */
13252 pHddCtx->hdd_restart_retries = 0;
13253 atomic_set(&pHddCtx->isRestartInProgress, 0);
13254 vos_timer_init(&pHddCtx->hdd_restart_timer,
13255 VOS_TIMER_TYPE_SW,
13256 wlan_hdd_restart_timer_cb,
13257 pHddCtx);
13258}
13259/**---------------------------------------------------------------------------
13260 *
13261 * \brief wlan_hdd_restart_deinit
13262 *
13263 * This function cleans up the resources used. An internal function.
13264 *
13265 * \param - pHddCtx
13266 *
13267 * \return - None
13268 *
13269 * --------------------------------------------------------------------------*/
13270
13271static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
13272{
13273
13274 VOS_STATUS vos_status;
13275 /* Block any further calls */
13276 atomic_set(&pHddCtx->isRestartInProgress, 1);
13277 /* Cleanup */
13278 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
13279 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013280 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070013281 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
13282 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013283 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070013284
13285}
13286
13287/**---------------------------------------------------------------------------
13288 *
13289 * \brief wlan_hdd_framework_restart
13290 *
13291 * This function uses a cfg80211 API to start a framework initiated WLAN
13292 * driver module unload/load.
13293 *
13294 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
13295 *
13296 *
13297 * \param - pHddCtx
13298 *
13299 * \return - VOS_STATUS_SUCCESS: Success
13300 * VOS_STATUS_E_EMPTY: Adapter is Empty
13301 * VOS_STATUS_E_NOMEM: No memory
13302
13303 * --------------------------------------------------------------------------*/
13304
13305static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
13306{
13307 VOS_STATUS status = VOS_STATUS_SUCCESS;
13308 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013309 int len = (sizeof (struct ieee80211_mgmt));
13310 struct ieee80211_mgmt *mgmt = NULL;
13311
13312 /* Prepare the DEAUTH managment frame with reason code */
13313 mgmt = kzalloc(len, GFP_KERNEL);
13314 if(mgmt == NULL)
13315 {
13316 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13317 "%s: memory allocation failed (%d bytes)", __func__, len);
13318 return VOS_STATUS_E_NOMEM;
13319 }
13320 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070013321
13322 /* Iterate over all adapters/devices */
13323 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013324 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
13325 {
13326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13327 FL("fail to get adapter: %p %d"), pAdapterNode, status);
13328 goto end;
13329 }
13330
Jeff Johnsone7245742012-09-05 17:12:55 -070013331 do
13332 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013333 if(pAdapterNode->pAdapter &&
13334 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070013335 {
13336 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13337 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
13338 pAdapterNode->pAdapter->dev->name,
13339 pAdapterNode->pAdapter->device_mode,
13340 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013341 /*
13342 * CFG80211 event to restart the driver
13343 *
13344 * 'cfg80211_send_unprot_deauth' sends a
13345 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
13346 * of SME(Linux Kernel) state machine.
13347 *
13348 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
13349 * the driver.
13350 *
13351 */
Abhishek Singh00b71972016-01-07 10:51:04 +053013352
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053013353#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
13354 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
13355#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013356 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053013357#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013358 }
13359 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13360 pAdapterNode = pNext;
13361 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
13362
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013363 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013364 /* Free the allocated management frame */
13365 kfree(mgmt);
13366
Jeff Johnsone7245742012-09-05 17:12:55 -070013367 /* Retry until we unload or reach max count */
13368 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
13369 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
13370
13371 return status;
13372
13373}
13374/**---------------------------------------------------------------------------
13375 *
13376 * \brief wlan_hdd_restart_timer_cb
13377 *
13378 * Restart timer callback. An internal function.
13379 *
13380 * \param - User data:
13381 *
13382 * \return - None
13383 *
13384 * --------------------------------------------------------------------------*/
13385
13386void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
13387{
13388 hdd_context_t *pHddCtx = usrDataForCallback;
13389 wlan_hdd_framework_restart(pHddCtx);
13390 return;
13391
13392}
13393
13394
13395/**---------------------------------------------------------------------------
13396 *
13397 * \brief wlan_hdd_restart_driver
13398 *
13399 * This function sends an event to supplicant to restart the WLAN driver.
13400 *
13401 * This function is called from vos_wlanRestart.
13402 *
13403 * \param - pHddCtx
13404 *
13405 * \return - VOS_STATUS_SUCCESS: Success
13406 * VOS_STATUS_E_EMPTY: Adapter is Empty
13407 * VOS_STATUS_E_ALREADY: Request already in progress
13408
13409 * --------------------------------------------------------------------------*/
13410VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
13411{
13412 VOS_STATUS status = VOS_STATUS_SUCCESS;
13413
13414 /* A tight check to make sure reentrancy */
13415 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
13416 {
Mihir Shetefd528652014-06-23 19:07:50 +053013417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070013418 "%s: WLAN restart is already in progress", __func__);
13419
13420 return VOS_STATUS_E_ALREADY;
13421 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070013422 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080013423#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053013424 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070013425#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070013426
Jeff Johnsone7245742012-09-05 17:12:55 -070013427 return status;
13428}
13429
Bhargav Shahd0715912015-10-01 18:17:37 +053013430/**
13431 * hdd_get_total_sessions() - provide total number of active sessions
13432 * @pHddCtx: Valid Global HDD context pointer
13433 *
13434 * This function iterates through pAdaptors and find the number of all active
13435 * sessions. This active sessions includes connected sta, p2p client and number
13436 * of client connected to sap/p2p go.
13437 *
13438 * Return: Total number of active sessions.
13439 */
13440v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx)
13441{
13442 v_U8_t active_session = 0;
13443 hdd_station_ctx_t *pHddStaCtx;
13444 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13445 hdd_adapter_t *pAdapter;
13446 VOS_STATUS status;
13447
13448 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13449 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
13450 pAdapter = pAdapterNode->pAdapter;
13451 switch (pAdapter->device_mode) {
13452 case VOS_STA_MODE:
13453 case VOS_P2P_CLIENT_MODE:
13454 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13455 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
13456 active_session += 1;
13457 break;
13458 case VOS_STA_SAP_MODE:
13459 case VOS_P2P_GO_MODE:
13460 active_session += hdd_softap_get_connected_sta(pAdapter);
13461 break;
13462 default:
13463 break;
13464 }
13465
13466 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
13467 pAdapterNode = pNext;
13468 }
13469
13470 return active_session;
13471}
13472
13473/**
13474 * hdd_set_delack_value() - Set delack value
13475 * @pHddCtx: Valid Global HDD context pointer
13476 * @next_rx_level: Value to set for delack
13477 *
13478 * This function compare present value and next value of delack. If the both
13479 * are diffrent then it sets next value .
13480 *
13481 * Return: void.
13482 */
13483void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
13484{
13485 if (pHddCtx->cur_rx_level != next_rx_level) {
13486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13487 "%s: TCP DELACK trigger level %d",
13488 __func__, next_rx_level);
13489 mutex_lock(&pHddCtx->cur_rx_level_lock);
13490 pHddCtx->cur_rx_level = next_rx_level;
13491 mutex_unlock(&pHddCtx->cur_rx_level_lock);
13492 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &next_rx_level,
13493 sizeof(next_rx_level));
13494 }
13495}
13496
13497/**
13498 * hdd_set_default_stop_delack_timer() - Start delack timer
13499 * @pHddCtx: Valid Global HDD context pointer
13500 *
13501 * This function stop delack timer and set delack value to default..
13502 *
13503 * Return: void.
13504 */
13505
13506void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
13507{
13508 if (VOS_TIMER_STATE_RUNNING !=
13509 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
13510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13511 "%s: Can not stop timer", __func__);
13512 return;
13513 }
13514
13515 vos_timer_stop(&pHddCtx->delack_timer);
13516 hdd_set_delack_value(pHddCtx, TP_IND_LOW);
13517}
13518
13519/**
13520 * hdd_start_delack_timer() - Start delack timer
13521 * @pHddCtx: Valid Global HDD context pointer
13522 *
13523 * This function starts the delack timer for tcpDelAckComputeInterval time
13524 * interval.The default timer value is 2 second.
13525 *
13526 * Return: void.
13527 */
13528void hdd_start_delack_timer(hdd_context_t *pHddCtx)
13529{
13530 if (VOS_TIMER_STATE_RUNNING ==
13531 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
13532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13533 "%s: Timer is already running", __func__);
13534 return;
13535 }
13536
13537 vos_timer_start(&pHddCtx->delack_timer,
13538 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
13539}
13540
13541/**
13542 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
13543 * @pHddCtx: Valid Global HDD context pointer
13544 *
13545 * This function updates the prev_rx_packets count from the corresponding
13546 * pAdapter states. This prev_rx_packets will diffed with the packet count
13547 * at the end of delack timer. That can give number of RX packet is spacific
13548 * time.
13549 *
13550 * Return: void.
13551 */
13552void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
13553{
13554 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13555 hdd_adapter_t *pAdapter;
13556 VOS_STATUS status;
13557
13558 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13559 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
13560 pAdapter = pAdapterNode->pAdapter;
13561 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
13562 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13563 pAdapterNode = pNext;
13564 }
13565}
13566
13567/**
13568 * hdd_manage_delack_timer() - start\stop delack timer
13569 * @pHddCtx: Valid Global HDD context pointer
13570 *
13571 * This function check the number of concerent session present, it starts the
13572 * delack timer if only one session is present.
13573 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
13574 *
13575 * Return: void.
13576 */
13577void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
13578{
13579 uint8_t sessions;
13580
13581 if (!pHddCtx->cfg_ini->enable_delack) {
13582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13583 "%s: TCP DELACK is not enabled", __func__);
13584 return;
13585 }
13586
13587 /* Blindly stop timer of BTCOEX and TDLS Session is up */
13588 if (pHddCtx->mode != 0) {
13589 hdd_set_default_stop_delack_timer(pHddCtx);
13590 return;
13591 }
13592
13593 sessions = hdd_get_total_sessions(pHddCtx);
13594 if (sessions == 1) {
13595 hdd_update_prev_rx_packet_count(pHddCtx);
13596 hdd_start_delack_timer(pHddCtx);
13597 } else {
13598 hdd_set_default_stop_delack_timer(pHddCtx);
13599 }
13600}
13601
Mihir Shetee1093ba2014-01-21 20:13:32 +053013602/**---------------------------------------------------------------------------
13603 *
13604 * \brief wlan_hdd_init_channels
13605 *
13606 * This function is used to initialize the channel list in CSR
13607 *
13608 * This function is called from hdd_wlan_startup
13609 *
13610 * \param - pHddCtx: HDD context
13611 *
13612 * \return - VOS_STATUS_SUCCESS: Success
13613 * VOS_STATUS_E_FAULT: Failure reported by SME
13614
13615 * --------------------------------------------------------------------------*/
13616static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
13617{
13618 eHalStatus status;
13619
13620 status = sme_InitChannels(pHddCtx->hHal);
13621 if (HAL_STATUS_SUCCESS(status))
13622 {
13623 return VOS_STATUS_SUCCESS;
13624 }
13625 else
13626 {
13627 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
13628 __func__, status);
13629 return VOS_STATUS_E_FAULT;
13630 }
13631}
13632
Mihir Shete04206452014-11-20 17:50:58 +053013633#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013634VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013635{
13636 eHalStatus status;
13637
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013638 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013639 if (HAL_STATUS_SUCCESS(status))
13640 {
13641 return VOS_STATUS_SUCCESS;
13642 }
13643 else
13644 {
13645 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
13646 __func__, status);
13647 return VOS_STATUS_E_FAULT;
13648 }
13649}
Mihir Shete04206452014-11-20 17:50:58 +053013650#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070013651/*
13652 * API to find if there is any STA or P2P-Client is connected
13653 */
13654VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
13655{
13656 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
13657}
Jeff Johnsone7245742012-09-05 17:12:55 -070013658
Mihir Shetee2ae82a2015-03-16 14:08:49 +053013659
13660/*
13661 * API to find if the firmware will send logs using DXE channel
13662 */
13663v_U8_t hdd_is_fw_logging_enabled(void)
13664{
13665 hdd_context_t *pHddCtx;
13666
13667 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
13668 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
13669
Sachin Ahuja084313e2015-05-21 17:57:10 +053013670 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053013671}
13672
Agarwal Ashish57e84372014-12-05 18:26:53 +053013673/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053013674 * API to find if the firmware will send trace logs using DXE channel
13675 */
13676v_U8_t hdd_is_fw_ev_logging_enabled(void)
13677{
13678 hdd_context_t *pHddCtx;
13679
13680 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
13681 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
13682
13683 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
13684}
13685/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053013686 * API to find if there is any session connected
13687 */
13688VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
13689{
13690 return sme_is_any_session_connected(pHddCtx->hHal);
13691}
13692
13693
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013694int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
13695{
13696 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13697 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053013698 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053013699 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013700
13701 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053013702 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013703 if (pScanInfo->mScanPending)
13704 {
c_hpothua3d45d52015-01-05 14:11:17 +053013705 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
13706 eCSR_SCAN_ABORT_DEFAULT);
13707 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13708 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013709
c_hpothua3d45d52015-01-05 14:11:17 +053013710 /* If there is active scan command lets wait for the completion else
13711 * there is no need to wait as scan command might be in the SME pending
13712 * command list.
13713 */
13714 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
13715 {
c_hpothua3d45d52015-01-05 14:11:17 +053013716 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013717 &pScanInfo->abortscan_event_var,
13718 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053013719 if (0 >= status)
13720 {
13721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053013722 "%s: Timeout or Interrupt occurred while waiting for abort"
13723 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053013724 return -ETIMEDOUT;
13725 }
13726 }
13727 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
13728 {
13729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13730 FL("hdd_abort_mac_scan failed"));
13731 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013732 }
13733 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053013734 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013735}
13736
Abhishek Singh7d624e12015-11-30 14:29:27 +053013737/**
13738 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
13739 * user space
13740 * @frame_ind: Management frame data to be informed.
13741 *
13742 * This function is used to indicate management frame to
13743 * user space
13744 *
13745 * Return: None
13746 *
13747 */
13748void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
13749{
13750 hdd_context_t *hdd_ctx = NULL;
13751 hdd_adapter_t *adapter = NULL;
13752 v_CONTEXT_t vos_context = NULL;
13753
13754 /* Get the global VOSS context.*/
13755 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13756 if (!vos_context) {
13757 hddLog(LOGE, FL("Global VOS context is Null"));
13758 return;
13759 }
13760 /* Get the HDD context.*/
13761 hdd_ctx =
13762 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
13763
13764 if (0 != wlan_hdd_validate_context(hdd_ctx))
13765 {
13766 return;
13767 }
13768 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
13769 frame_ind->sessionId);
13770
13771 if ((NULL != adapter) &&
13772 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
13773 __hdd_indicate_mgmt_frame(adapter,
13774 frame_ind->frameLen,
13775 frame_ind->frameBuf,
13776 frame_ind->frameType,
13777 frame_ind->rxChan,
13778 frame_ind->rxRssi);
13779 return;
13780
13781}
13782
c_hpothu225aa7c2014-10-22 17:45:13 +053013783VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
13784{
13785 hdd_adapter_t *pAdapter;
13786 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13787 VOS_STATUS vosStatus;
13788
13789 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13790 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
13791 {
13792 pAdapter = pAdapterNode->pAdapter;
13793 if (NULL != pAdapter)
13794 {
13795 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
13796 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
13797 WLAN_HDD_P2P_GO == pAdapter->device_mode)
13798 {
13799 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
13800 pAdapter->device_mode);
13801 if (VOS_STATUS_SUCCESS !=
13802 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
13803 {
13804 hddLog(LOGE, FL("failed to abort ROC"));
13805 return VOS_STATUS_E_FAILURE;
13806 }
13807 }
13808 }
13809 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13810 pAdapterNode = pNext;
13811 }
13812 return VOS_STATUS_SUCCESS;
13813}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053013814
Mihir Shete0be28772015-02-17 18:42:14 +053013815hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
13816{
13817 hdd_adapter_t *pAdapter;
13818 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13819 hdd_cfg80211_state_t *cfgState;
13820 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
13821 VOS_STATUS vosStatus;
13822
13823 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
13824 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
13825 {
13826 pAdapter = pAdapterNode->pAdapter;
13827 if (NULL != pAdapter)
13828 {
13829 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
13830 pRemainChanCtx = cfgState->remain_on_chan_ctx;
13831 if (pRemainChanCtx)
13832 break;
13833 }
13834 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
13835 pAdapterNode = pNext;
13836 }
13837 return pRemainChanCtx;
13838}
13839
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053013840/**
13841 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
13842 *
13843 * @pHddCtx: HDD context within host driver
13844 * @dfsScanMode: dfsScanMode passed from ioctl
13845 *
13846 */
13847
13848VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
13849 tANI_U8 dfsScanMode)
13850{
13851 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13852 hdd_adapter_t *pAdapter;
13853 VOS_STATUS vosStatus;
13854 hdd_station_ctx_t *pHddStaCtx;
13855 eHalStatus status = eHAL_STATUS_SUCCESS;
13856
13857 if(!pHddCtx)
13858 {
13859 hddLog(LOGE, FL("HDD context is Null"));
13860 return eHAL_STATUS_FAILURE;
13861 }
13862
13863 if (pHddCtx->scan_info.mScanPending)
13864 {
13865 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
13866 pHddCtx->scan_info.sessionId);
13867 hdd_abort_mac_scan(pHddCtx,
13868 pHddCtx->scan_info.sessionId,
13869 eCSR_SCAN_ABORT_DEFAULT);
13870 }
13871
13872 if (!dfsScanMode)
13873 {
13874 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
13875 while ((NULL != pAdapterNode) &&
13876 (VOS_STATUS_SUCCESS == vosStatus))
13877 {
13878 pAdapter = pAdapterNode->pAdapter;
13879
13880 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
13881 {
13882 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13883
13884 if(!pHddStaCtx)
13885 {
13886 hddLog(LOGE, FL("HDD STA context is Null"));
13887 return eHAL_STATUS_FAILURE;
13888 }
13889
13890 /* if STA is already connected on DFS channel,
13891 disconnect immediately*/
13892 if (hdd_connIsConnected(pHddStaCtx) &&
13893 (NV_CHANNEL_DFS ==
13894 vos_nv_getChannelEnabledState(
13895 pHddStaCtx->conn_info.operationChannel)))
13896 {
13897 status = sme_RoamDisconnect(pHddCtx->hHal,
13898 pAdapter->sessionId,
13899 eCSR_DISCONNECT_REASON_UNSPECIFIED);
13900 hddLog(LOG1, FL("Client connected on DFS channel %d,"
13901 "sme_RoamDisconnect returned with status: %d"
13902 "for sessionid: %d"), pHddStaCtx->conn_info.
13903 operationChannel, status, pAdapter->sessionId);
13904 }
13905 }
13906
13907 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
13908 &pNext);
13909 pAdapterNode = pNext;
13910 }
13911 }
13912
13913 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
13914 sme_UpdateDFSRoamMode(pHddCtx->hHal,
13915 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
13916
13917 status = sme_HandleDFSChanScan(pHddCtx->hHal);
13918 if (!HAL_STATUS_SUCCESS(status))
13919 {
13920 hddLog(LOGE,
13921 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
13922 return status;
13923 }
13924
13925 return status;
13926}
13927
Nirav Shah7e3c8132015-06-22 23:51:42 +053013928static int hdd_log2_ceil(unsigned value)
13929{
13930 /* need to switch to unsigned math so that negative values
13931 * will right-shift towards 0 instead of -1
13932 */
13933 unsigned tmp = value;
13934 int log2 = -1;
13935
13936 if (value == 0)
13937 return 0;
13938
13939 while (tmp) {
13940 log2++;
13941 tmp >>= 1;
13942 }
13943 if (1U << log2 != value)
13944 log2++;
13945
13946 return log2;
13947}
13948
13949/**
13950 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
13951 * @pAdapter: adapter handle
13952 *
13953 * Return: vos status
13954 */
13955VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
13956{
13957 int hash_elem, log2, i;
13958
13959 spin_lock_bh( &pAdapter->sta_hash_lock);
13960 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
13961 spin_unlock_bh( &pAdapter->sta_hash_lock);
13962 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13963 "%s: hash already attached for session id %d",
13964 __func__, pAdapter->sessionId);
13965 return VOS_STATUS_SUCCESS;
13966 }
13967 spin_unlock_bh( &pAdapter->sta_hash_lock);
13968
13969 hash_elem = WLAN_MAX_STA_COUNT;
13970 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
13971 log2 = hdd_log2_ceil(hash_elem);
13972 hash_elem = 1 << log2;
13973
13974 pAdapter->sta_id_hash.mask = hash_elem - 1;
13975 pAdapter->sta_id_hash.idx_bits = log2;
13976 pAdapter->sta_id_hash.bins =
13977 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
13978 if (!pAdapter->sta_id_hash.bins) {
13979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13980 "%s: malloc failed for session %d",
13981 __func__, pAdapter->sessionId);
13982 return VOS_STATUS_E_NOMEM;
13983 }
13984
13985 for (i = 0; i < hash_elem; i++)
13986 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
13987
13988 spin_lock_bh( &pAdapter->sta_hash_lock);
13989 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
13990 spin_unlock_bh( &pAdapter->sta_hash_lock);
13991 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13992 "%s: Station ID Hash attached for session id %d",
13993 __func__, pAdapter->sessionId);
13994
13995 return VOS_STATUS_SUCCESS;
13996}
13997
13998/**
13999 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
14000 * @pAdapter: adapter handle
14001 *
14002 * Return: vos status
14003 */
14004VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
14005{
14006 int hash_elem, i;
14007 v_SIZE_t size;
14008
14009 spin_lock_bh( &pAdapter->sta_hash_lock);
14010 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14011 spin_unlock_bh( &pAdapter->sta_hash_lock);
14012 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14013 "%s: hash not initialized for session id %d",
14014 __func__, pAdapter->sessionId);
14015 return VOS_STATUS_SUCCESS;
14016 }
14017
14018 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
14019 spin_unlock_bh( &pAdapter->sta_hash_lock);
14020
14021 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
14022
14023 /* free all station info*/
14024 for (i = 0; i < hash_elem; i++) {
14025 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
14026 if (size != 0) {
14027 VOS_STATUS status;
14028 hdd_staid_hash_node_t *sta_info_node = NULL;
14029 hdd_staid_hash_node_t *next_node = NULL;
14030 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
14031 (hdd_list_node_t**) &sta_info_node );
14032
14033 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14034 {
14035 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
14036 &sta_info_node->node);
14037 vos_mem_free(sta_info_node);
14038
14039 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
14040 (hdd_list_node_t*)sta_info_node,
14041 (hdd_list_node_t**)&next_node);
14042 sta_info_node = next_node;
14043 }
14044 }
14045 }
14046
14047 vos_mem_free(pAdapter->sta_id_hash.bins);
14048 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14049 "%s: Station ID Hash detached for session id %d",
14050 __func__, pAdapter->sessionId);
14051 return VOS_STATUS_SUCCESS;
14052}
14053
14054/**
14055 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
14056 * @pAdapter: adapter handle
14057 * @mac_addr_in: input mac address
14058 *
14059 * Return: index derived from mac address
14060 */
14061int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
14062 v_MACADDR_t *mac_addr_in)
14063{
14064 uint16 index;
14065 struct hdd_align_mac_addr_t * mac_addr =
14066 (struct hdd_align_mac_addr_t *)mac_addr_in;
14067
14068 index = mac_addr->bytes_ab ^
14069 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
14070 index ^= index >> pAdapter->sta_id_hash.idx_bits;
14071 index &= pAdapter->sta_id_hash.mask;
14072 return index;
14073}
14074
14075/**
14076 * hdd_sta_id_hash_add_entry() - add entry in hash
14077 * @pAdapter: adapter handle
14078 * @sta_id: station id
14079 * @mac_addr: mac address
14080 *
14081 * Return: vos status
14082 */
14083VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
14084 v_U8_t sta_id, v_MACADDR_t *mac_addr)
14085{
14086 uint16 index;
14087 hdd_staid_hash_node_t *sta_info_node = NULL;
14088
Nirav Shah7e3c8132015-06-22 23:51:42 +053014089 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
14090 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
14091 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053014092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14093 "%s: malloc failed", __func__);
14094 return VOS_STATUS_E_NOMEM;
14095 }
14096
14097 sta_info_node->sta_id = sta_id;
14098 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
14099
Nirav Shah303ed5c2015-08-24 10:29:25 +053014100 spin_lock_bh( &pAdapter->sta_hash_lock);
14101 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14102 spin_unlock_bh( &pAdapter->sta_hash_lock);
14103 vos_mem_free(sta_info_node);
14104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14105 "%s: hash is not initialized for session id %d",
14106 __func__, pAdapter->sessionId);
14107 return VOS_STATUS_E_FAILURE;
14108 }
14109
Nirav Shah7e3c8132015-06-22 23:51:42 +053014110 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
14111 (hdd_list_node_t*) sta_info_node );
14112 spin_unlock_bh( &pAdapter->sta_hash_lock);
14113 return VOS_STATUS_SUCCESS;
14114}
14115
14116/**
14117 * hdd_sta_id_hash_remove_entry() - remove entry from hash
14118 * @pAdapter: adapter handle
14119 * @sta_id: station id
14120 * @mac_addr: mac address
14121 *
14122 * Return: vos status
14123 */
14124VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
14125 v_U8_t sta_id, v_MACADDR_t *mac_addr)
14126{
14127 uint16 index;
14128 VOS_STATUS status;
14129 hdd_staid_hash_node_t *sta_info_node = NULL;
14130 hdd_staid_hash_node_t *next_node = NULL;
14131
14132 spin_lock_bh( &pAdapter->sta_hash_lock);
14133 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14134 spin_unlock_bh( &pAdapter->sta_hash_lock);
14135 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14136 "%s: hash is not initialized for session id %d",
14137 __func__, pAdapter->sessionId);
14138 return VOS_STATUS_E_FAILURE;
14139 }
14140
14141 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
14142 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
14143 (hdd_list_node_t**) &sta_info_node );
14144
14145 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14146 {
14147 if (sta_info_node->sta_id == sta_id) {
14148 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
14149 &sta_info_node->node);
14150 vos_mem_free(sta_info_node);
14151 break;
14152 }
14153 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
14154 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
14155 sta_info_node = next_node;
14156 }
14157 spin_unlock_bh( &pAdapter->sta_hash_lock);
14158 return status;
14159}
14160
14161/**
14162 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
14163 * @pAdapter: adapter handle
14164 * @mac_addr_in: mac address
14165 *
14166 * Return: station id
14167 */
14168int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
14169 v_MACADDR_t *mac_addr_in)
14170{
14171 uint8 is_found = 0;
14172 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
14173 uint16 index;
14174 VOS_STATUS status;
14175 hdd_staid_hash_node_t *sta_info_node = NULL;
14176 hdd_staid_hash_node_t *next_node = NULL;
14177
14178 spin_lock_bh( &pAdapter->sta_hash_lock);
14179 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14180 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053014181 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053014182 FL("hash is not initialized for session id %d"),
14183 pAdapter->sessionId);
14184 return HDD_WLAN_INVALID_STA_ID;
14185 }
14186
14187 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
14188 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
14189 (hdd_list_node_t**) &sta_info_node );
14190
14191 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14192 {
14193 if (vos_mem_compare(&sta_info_node->mac_addr,
14194 mac_addr_in, sizeof(v_MACADDR_t))) {
14195 is_found = 1;
14196 sta_id = sta_info_node->sta_id;
14197 break;
14198 }
14199 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
14200 (hdd_list_node_t*)sta_info_node,
14201 (hdd_list_node_t**)&next_node);
14202 sta_info_node = next_node;
14203 }
14204 spin_unlock_bh( &pAdapter->sta_hash_lock);
14205 return sta_id;
14206}
14207
c_manjeecfd1efb2015-09-25 19:32:34 +053014208/*FW memory dump feature*/
14209/**
14210 * This structure hold information about the /proc file
14211 *
14212 */
14213static struct proc_dir_entry *proc_file, *proc_dir;
14214
14215/**
14216 * memdump_read() - perform read operation in memory dump proc file
14217 *
14218 * @file - handle for the proc file.
14219 * @buf - pointer to user space buffer.
14220 * @count - number of bytes to be read.
14221 * @pos - offset in the from buffer.
14222 *
14223 * This function performs read operation for the memory dump proc file.
14224 *
14225 * Return: number of bytes read on success, error code otherwise.
14226 */
14227static ssize_t memdump_read(struct file *file, char __user *buf,
14228 size_t count, loff_t *pos)
14229{
14230 int status;
14231 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
14232 size_t ret_count;
c_manjeef1495642015-10-13 18:35:01 +053014233 loff_t bytes_left;
c_manjeecfd1efb2015-09-25 19:32:34 +053014234 ENTER();
14235
14236 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
14237 status = wlan_hdd_validate_context(hdd_ctx);
14238 if (0 != status) {
14239 return -EINVAL;
14240 }
14241
14242 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
14243 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
14244 return -EINVAL;
14245 }
14246
14247 /* run fs_read_handler in an atomic context*/
14248 vos_ssr_protect(__func__);
c_manjeef1495642015-10-13 18:35:01 +053014249 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left);
14250 if(bytes_left == 0)
c_manjeecfd1efb2015-09-25 19:32:34 +053014251 {
14252 /*Free the fwr mem dump buffer */
14253 wlan_free_fwr_mem_dump_buffer();
14254 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeef1495642015-10-13 18:35:01 +053014255 ret_count=0;
c_manjeecfd1efb2015-09-25 19:32:34 +053014256 }
14257 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
14258 vos_ssr_unprotect(__func__);
14259 EXIT();
14260 return ret_count;
14261}
14262
14263/**
14264 * struct memdump_fops - file operations for memory dump feature
14265 * @read - read function for memory dump operation.
14266 *
14267 * This structure initialize the file operation handle for memory
14268 * dump feature
14269 */
14270static const struct file_operations memdump_fops = {
14271 read: memdump_read
14272};
14273
14274/*
14275* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
14276* To be passed by HDD to WDA and called upon receiving of response
14277* from firmware
14278* @fwMemDumpReqContext : memory dump request context
14279* @dump_rsp : dump response from HAL
14280* Returns none
14281*/
14282void wlan_hdd_fw_mem_dump_cb(void *fwMemDumpReqContext,
14283 tAniFwrDumpRsp *dump_rsp)
14284{
c_manjeef1495642015-10-13 18:35:01 +053014285 struct hdd_fw_mem_dump_req_ctx *pHddFwMemDumpCtx = (struct hdd_fw_mem_dump_req_ctx *)fwMemDumpReqContext;
c_manjeecfd1efb2015-09-25 19:32:34 +053014286
c_manjeef1495642015-10-13 18:35:01 +053014287 ENTER();
14288 spin_lock(&hdd_context_lock);
14289 if(!pHddFwMemDumpCtx || (FW_MEM_DUMP_MAGIC != pHddFwMemDumpCtx->magic)) {
14290 spin_unlock(&hdd_context_lock);
14291 return;
14292 }
14293 /* report the status to requesting function and free mem.*/
c_manjeecfd1efb2015-09-25 19:32:34 +053014294 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
c_manjeef1495642015-10-13 18:35:01 +053014295 hddLog(LOGE, FL("fw dump request declined by fwr"));
14296 //set the request completion variable
14297 complete(&(pHddFwMemDumpCtx->req_completion));
c_manjeecfd1efb2015-09-25 19:32:34 +053014298 //Free the allocated fwr dump
14299 wlan_free_fwr_mem_dump_buffer();
14300 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeecfd1efb2015-09-25 19:32:34 +053014301 }
c_manjeef1495642015-10-13 18:35:01 +053014302 else {
14303 hddLog(LOG1, FL("fw dump request accepted by fwr"));
14304 /* register the HDD callback which will be called by SVC */
14305 wlan_set_svc_fw_mem_dump_req_cb((void*)wlan_hdd_fw_mem_dump_req_cb,(void*)pHddFwMemDumpCtx);
14306 }
14307 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014308 EXIT();
14309
14310}
14311
14312/**
14313 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
14314 *
14315 * This function removes file/dir under proc file system that was
14316 * processing firmware memory dump
14317 *
14318 * Return: None
14319 */
14320static void memdump_procfs_remove(void)
14321{
14322 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
14323 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
14324 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
14325 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
14326 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
14327}
14328
14329/**
14330 * memdump_procfs_init() - Initialize procfs for memory dump
14331 *
14332 * @vos_ctx - Global vos context.
14333 *
14334 * This function create file under proc file system to be used later for
14335 * processing firmware memory dump
14336 *
14337 * Return: 0 on success, error code otherwise.
14338 */
14339static int memdump_procfs_init(void *vos_ctx)
14340{
14341 hdd_context_t *hdd_ctx;
14342
14343 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14344 if (!hdd_ctx) {
14345 hddLog(LOGE , FL("Invalid HDD context"));
14346 return -EINVAL;
14347 }
14348
14349 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
14350 if (proc_dir == NULL) {
14351 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
14352 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
14353 PROCFS_MEMDUMP_DIR);
14354 return -ENOMEM;
14355 }
14356
14357 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
14358 S_IRUSR | S_IWUSR, proc_dir,
14359 &memdump_fops, hdd_ctx);
14360 if (proc_file == NULL) {
14361 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
14362 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
14363 PROCFS_MEMDUMP_NAME);
14364 return -ENOMEM;
14365 }
14366
14367 hddLog(LOG1 , FL("/proc/%s/%s created"),
14368 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
14369
14370 return 0;
14371}
14372
14373/**
14374 * memdump_init() - Initialization function for memory dump feature
14375 *
14376 * This function creates proc file for memdump feature and registers
14377 * HDD callback function with SME.
14378 *
14379 * Return - 0 on success, error otherwise
14380 */
14381int memdump_init(void)
14382{
14383 hdd_context_t *hdd_ctx;
14384 void *vos_ctx;
14385 int status = 0;
14386
14387 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14388 if (!vos_ctx) {
14389 hddLog(LOGE, FL("Invalid VOS context"));
14390 return -EINVAL;
14391 }
14392
14393 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14394 if (!hdd_ctx) {
14395 hddLog(LOGE , FL("Invalid HDD context"));
14396 return -EINVAL;
14397 }
14398
14399 status = memdump_procfs_init(vos_ctx);
14400 if (status) {
14401 hddLog(LOGE , FL("Failed to create proc file"));
14402 return status;
14403 }
14404
14405 return 0;
14406}
14407
14408/**
14409 * memdump_deinit() - De initialize memdump feature
14410 *
14411 * This function removes proc file created for memdump feature.
14412 *
14413 * Return: None
14414 */
14415int memdump_deinit(void)
14416{
14417 hdd_context_t *hdd_ctx;
14418 void *vos_ctx;
14419
14420 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14421 if (!vos_ctx) {
14422 hddLog(LOGE, FL("Invalid VOS context"));
14423 return -EINVAL;
14424 }
14425
14426 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14427 if(!hdd_ctx) {
14428 hddLog(LOGE , FL("Invalid HDD context"));
14429 return -EINVAL;
14430 }
14431
14432 memdump_procfs_remove();
14433 return 0;
14434}
14435
14436/**
14437 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
14438 * Return: HAL status
14439 */
14440
14441int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
14442{
14443 tAniFwrDumpReq fw_mem_dump_req={0};
c_manjeef1495642015-10-13 18:35:01 +053014444 struct hdd_fw_mem_dump_req_ctx fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053014445 eHalStatus status = eHAL_STATUS_FAILURE;
Abhishek Singh4eca9822015-12-09 18:07:34 +053014446 int ret=0, result;
c_manjeecfd1efb2015-09-25 19:32:34 +053014447 ENTER();
c_manjeef1495642015-10-13 18:35:01 +053014448
c_manjeecfd1efb2015-09-25 19:32:34 +053014449 /*Check whether a dump request is already going on
14450 *Caution this function will free previously held memory if new dump request is allowed*/
14451 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
14452 hddLog(LOGE, FL("Fw memdump already in progress"));
14453 return -EBUSY;
14454 }
14455 //Allocate memory for fw mem dump buffer
14456 ret = wlan_fwr_mem_dump_buffer_allocation();
14457 if(ret == -EFAULT)
14458 {
14459 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
14460 return ret;
14461 }
14462 if (0 != ret) {
14463 hddLog(LOGE, FL("Fwr mem Allocation failed"));
14464 return -ENOMEM;
14465 }
c_manjeef1495642015-10-13 18:35:01 +053014466 init_completion(&fw_mem_dump_ctx.req_completion);
14467 fw_mem_dump_ctx.magic = FW_MEM_DUMP_MAGIC;
14468 fw_mem_dump_ctx.status = false;
14469
c_manjeecfd1efb2015-09-25 19:32:34 +053014470 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
c_manjeef1495642015-10-13 18:35:01 +053014471 fw_mem_dump_req.fwMemDumpReqContext = &fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053014472 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
14473 if(eHAL_STATUS_SUCCESS != status)
14474 {
14475 hddLog(VOS_TRACE_LEVEL_ERROR,
14476 "%s: fw_mem_dump_req failed ", __func__);
14477 wlan_free_fwr_mem_dump_buffer();
c_manjeef1495642015-10-13 18:35:01 +053014478 ret = -EFAULT;
14479 goto cleanup;
c_manjeecfd1efb2015-09-25 19:32:34 +053014480 }
c_manjeef1495642015-10-13 18:35:01 +053014481 /*wait for fw mem dump completion to send event to userspace*/
Abhishek Singh4eca9822015-12-09 18:07:34 +053014482 result =
14483 wait_for_completion_timeout(&fw_mem_dump_ctx.req_completion,
14484 msecs_to_jiffies(FW_MEM_DUMP_TIMEOUT_MS));
14485 if (0 >= result )
c_manjeef1495642015-10-13 18:35:01 +053014486 {
14487 hddLog(VOS_TRACE_LEVEL_ERROR,
Abhishek Singh4eca9822015-12-09 18:07:34 +053014488 "%s: fw_mem_dump_req timeout %d ", __func__,result);
14489 ret = -ETIMEDOUT;
c_manjeef1495642015-10-13 18:35:01 +053014490 }
14491cleanup:
14492 spin_lock(&hdd_context_lock);
14493 fw_mem_dump_ctx.magic = 0;
Abhishek Singh4eca9822015-12-09 18:07:34 +053014494 if(!ret && !fw_mem_dump_ctx.status)
14495 ret = -EFAULT;
c_manjeef1495642015-10-13 18:35:01 +053014496 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014497
c_manjeef1495642015-10-13 18:35:01 +053014498 EXIT();
Abhishek Singh4eca9822015-12-09 18:07:34 +053014499 return ret;
c_manjeef1495642015-10-13 18:35:01 +053014500}
14501
14502/**
14503 * HDD callback which will be called by SVC to indicate mem dump completion.
14504 */
14505void wlan_hdd_fw_mem_dump_req_cb(struct hdd_fw_mem_dump_req_ctx* pHddFwMemDumpCtx)
14506{
14507 if (!pHddFwMemDumpCtx) {
14508 hddLog(VOS_TRACE_LEVEL_ERROR,
14509 "%s: HDD context not valid ", __func__);
14510 return;
14511 }
14512 spin_lock(&hdd_context_lock);
14513 /* check the req magic and set status */
14514 if (pHddFwMemDumpCtx->magic == FW_MEM_DUMP_MAGIC)
14515 {
14516 pHddFwMemDumpCtx->status = true;
14517 //signal the completion
14518 complete(&(pHddFwMemDumpCtx->req_completion));
14519 }
14520 else
14521 {
14522 hddLog(VOS_TRACE_LEVEL_ERROR,
14523 "%s: fw mem dump request possible timeout ", __func__);
14524 }
14525 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014526}
14527
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053014528void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
14529{
14530 if (NULL == pAdapter)
14531 {
14532 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
14533 return;
14534 }
14535 init_completion(&pAdapter->session_open_comp_var);
14536 init_completion(&pAdapter->session_close_comp_var);
14537 init_completion(&pAdapter->disconnect_comp_var);
14538 init_completion(&pAdapter->linkup_event_var);
14539 init_completion(&pAdapter->cancel_rem_on_chan_var);
14540 init_completion(&pAdapter->rem_on_chan_ready_event);
14541 init_completion(&pAdapter->pno_comp_var);
14542#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14543 init_completion(&pAdapter->offchannel_tx_event);
14544#endif
14545 init_completion(&pAdapter->tx_action_cnf_event);
14546#ifdef FEATURE_WLAN_TDLS
14547 init_completion(&pAdapter->tdls_add_station_comp);
14548 init_completion(&pAdapter->tdls_del_station_comp);
14549 init_completion(&pAdapter->tdls_mgmt_comp);
14550 init_completion(&pAdapter->tdls_link_establish_req_comp);
14551#endif
14552
14553#ifdef WLAN_FEATURE_RMC
14554 init_completion(&pAdapter->ibss_peer_info_comp);
14555#endif /* WLAN_FEATURE_RMC */
14556 init_completion(&pAdapter->ula_complete);
14557 init_completion(&pAdapter->change_country_code);
14558
14559#ifdef FEATURE_WLAN_BATCH_SCAN
14560 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
14561 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
14562#endif
14563
14564 return;
14565}
c_manjeecfd1efb2015-09-25 19:32:34 +053014566
14567
Jeff Johnson295189b2012-06-20 16:38:30 -070014568//Register the module init/exit functions
14569module_init(hdd_module_init);
14570module_exit(hdd_module_exit);
14571
14572MODULE_LICENSE("Dual BSD/GPL");
14573MODULE_AUTHOR("Qualcomm Atheros, Inc.");
14574MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
14575
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014576module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
14577 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070014578
Jeff Johnson76052702013-04-16 13:55:05 -070014579module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070014580 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080014581
14582module_param(enable_dfs_chan_scan, int,
14583 S_IRUSR | S_IRGRP | S_IROTH);
14584
14585module_param(enable_11d, int,
14586 S_IRUSR | S_IRGRP | S_IROTH);
14587
14588module_param(country_code, charp,
14589 S_IRUSR | S_IRGRP | S_IROTH);