blob: c6e3e8c9c610e689ac16b21d26d96f6ee37c240e [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05302 * Copyright (c) 2012-2018 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"
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +0530123#include "wlan_hdd_request_manager.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700124
125#ifdef MODULE
126#define WLAN_MODULE_NAME module_name(THIS_MODULE)
127#else
128#define WLAN_MODULE_NAME "wlan"
129#endif
130
131#ifdef TIMER_MANAGER
132#define TIMER_MANAGER_STR " +TIMER_MANAGER"
133#else
134#define TIMER_MANAGER_STR ""
135#endif
136
137#ifdef MEMORY_DEBUG
138#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
139#else
140#define MEMORY_DEBUG_STR ""
141#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530142#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700143/* the Android framework expects this param even though we don't use it */
144#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700145static char fwpath_buffer[BUF_LEN];
146static struct kparam_string fwpath = {
147 .string = fwpath_buffer,
148 .maxlen = BUF_LEN,
149};
Arif Hussain66559122013-11-21 10:11:40 -0800150
151static char *country_code;
152static int enable_11d = -1;
153static int enable_dfs_chan_scan = -1;
154
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);
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530251void hdd_set_vowifi_mode(hdd_context_t *hdd_ctx, bool enable);
Jeff Johnsone7245742012-09-05 17:12:55 -0700252
Jeff Johnson295189b2012-06-20 16:38:30 -0700253v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +0530254 struct sk_buff *skb
255#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
256 , void *accel_priv
257#endif
258#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
259 , select_queue_fallback_t fallback
260#endif
261);
Jeff Johnson295189b2012-06-20 16:38:30 -0700262
263#ifdef WLAN_FEATURE_PACKET_FILTERING
264static void hdd_set_multicast_list(struct net_device *dev);
265#endif
266
267void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
268
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800269#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800270void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
271static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700272static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
273 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
274 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +0530275static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
276 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800277#endif
Ratheesh S P21280412015-05-19 14:21:52 +0530278
279/* Store WLAN driver info in a global variable such that crash debugger
280 can extract it from driver debug symbol and crashdump for post processing */
281tANI_U8 g_wlan_driver[ ] = "pronto_driver";
282
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800283#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700284VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800285#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700286
Mihir Shetee1093ba2014-01-21 20:13:32 +0530287static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530288const char * hdd_device_modetoString(v_U8_t device_mode)
289{
290 switch(device_mode)
291 {
292 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
293 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
294 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
295 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
296 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
297 CASE_RETURN_STRING( WLAN_HDD_FTM );
298 CASE_RETURN_STRING( WLAN_HDD_IBSS );
299 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
300 default:
301 return "device_mode Unknown";
302 }
303}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530304
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530305static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700306 unsigned long state,
307 void *ndev)
308{
309 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700310 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700311 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700312#ifdef WLAN_BTAMP_FEATURE
313 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700314#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530315 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700316
317 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700318 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700319 (strncmp(dev->name, "p2p", 3)))
320 return NOTIFY_DONE;
321
Jeff Johnson295189b2012-06-20 16:38:30 -0700322 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700323 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700324
Jeff Johnson27cee452013-03-27 11:10:24 -0700325 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700326 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800327 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700328 VOS_ASSERT(0);
329 return NOTIFY_DONE;
330 }
331
Jeff Johnson27cee452013-03-27 11:10:24 -0700332 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
333 if (NULL == pHddCtx)
334 {
335 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
336 VOS_ASSERT(0);
337 return NOTIFY_DONE;
338 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800339 if (pHddCtx->isLogpInProgress)
340 return NOTIFY_DONE;
341
Jeff Johnson27cee452013-03-27 11:10:24 -0700342
343 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
344 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700345
346 switch (state) {
347 case NETDEV_REGISTER:
348 break;
349
350 case NETDEV_UNREGISTER:
351 break;
352
353 case NETDEV_UP:
354 break;
355
356 case NETDEV_DOWN:
357 break;
358
359 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700360 if(TRUE == pAdapter->isLinkUpSvcNeeded)
361 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700362 break;
363
364 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530365 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530366 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530367 {
368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
369 "%s: Timeout occurred while waiting for abortscan %ld",
370 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700371 }
372 else
373 {
374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530375 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700376 }
377#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700379 status = WLANBAP_StopAmp();
380 if(VOS_STATUS_SUCCESS != status )
381 {
382 pHddCtx->isAmpAllowed = VOS_TRUE;
383 hddLog(VOS_TRACE_LEVEL_FATAL,
384 "%s: Failed to stop AMP", __func__);
385 }
386 else
387 {
388 //a state m/c implementation in PAL is TBD to avoid this delay
389 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700390 if ( pHddCtx->isAmpAllowed )
391 {
392 WLANBAP_DeregisterFromHCI();
393 pHddCtx->isAmpAllowed = VOS_FALSE;
394 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700395 }
396#endif //WLAN_BTAMP_FEATURE
397 break;
398
399 default:
400 break;
401 }
402
403 return NOTIFY_DONE;
404}
405
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530406static int hdd_netdev_notifier_call(struct notifier_block * nb,
407 unsigned long state,
408 void *ndev)
409{
410 int ret;
411 vos_ssr_protect(__func__);
412 ret = __hdd_netdev_notifier_call( nb, state, ndev);
413 vos_ssr_unprotect(__func__);
414 return ret;
415}
416
Jeff Johnson295189b2012-06-20 16:38:30 -0700417struct notifier_block hdd_netdev_notifier = {
418 .notifier_call = hdd_netdev_notifier_call,
419};
420
421/*---------------------------------------------------------------------------
422 * Function definitions
423 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700424void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
425void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700426//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700427static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700428#ifndef MODULE
429/* current con_mode - used only for statically linked driver
430 * con_mode is changed by userspace to indicate a mode change which will
431 * result in calling the module exit and init functions. The module
432 * exit function will clean up based on the value of con_mode prior to it
433 * being changed by userspace. So curr_con_mode records the current con_mode
434 * for exit when con_mode becomes the next mode for init
435 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700436static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700437#endif
438
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +0530439#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
440/**
441 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
442 * @hdd_ctx: hdd global context
443 *
444 * Return: none
445 */
446static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
447{
448 uint8_t i;
449
450 mutex_init(&hdd_ctx->op_ctx.op_lock);
451 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
452 {
453 hdd_ctx->op_ctx.op_table[i].request_id = 0;
454 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
455 }
456}
457#else
458static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
459{
460}
461#endif
462
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800463/**---------------------------------------------------------------------------
464
465 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
466
467 Called immediately after the cfg.ini is read in order to configure
468 the desired trace levels.
469
470 \param - moduleId - module whose trace level is being configured
471 \param - bitmask - bitmask of log levels to be enabled
472
473 \return - void
474
475 --------------------------------------------------------------------------*/
476static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
477{
478 wpt_tracelevel level;
479
480 /* if the bitmask is the default value, then a bitmask was not
481 specified in cfg.ini, so leave the logging level alone (it
482 will remain at the "compiled in" default value) */
483 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
484 {
485 return;
486 }
487
488 /* a mask was specified. start by disabling all logging */
489 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
490
491 /* now cycle through the bitmask until all "set" bits are serviced */
492 level = VOS_TRACE_LEVEL_FATAL;
493 while (0 != bitmask)
494 {
495 if (bitmask & 1)
496 {
497 vos_trace_setValue(moduleId, level, 1);
498 }
499 level++;
500 bitmask >>= 1;
501 }
502}
503
504
Jeff Johnson295189b2012-06-20 16:38:30 -0700505/**---------------------------------------------------------------------------
506
507 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
508
509 Called immediately after the cfg.ini is read in order to configure
510 the desired trace levels in the WDI.
511
512 \param - moduleId - module whose trace level is being configured
513 \param - bitmask - bitmask of log levels to be enabled
514
515 \return - void
516
517 --------------------------------------------------------------------------*/
518static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
519{
520 wpt_tracelevel level;
521
522 /* if the bitmask is the default value, then a bitmask was not
523 specified in cfg.ini, so leave the logging level alone (it
524 will remain at the "compiled in" default value) */
525 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
526 {
527 return;
528 }
529
530 /* a mask was specified. start by disabling all logging */
531 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
532
533 /* now cycle through the bitmask until all "set" bits are serviced */
534 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
535 while (0 != bitmask)
536 {
537 if (bitmask & 1)
538 {
539 wpalTraceSetLevel(moduleId, level, 1);
540 }
541 level++;
542 bitmask >>= 1;
543 }
544}
Jeff Johnson295189b2012-06-20 16:38:30 -0700545
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530546/*
547 * FUNCTION: wlan_hdd_validate_context
548 * This function is used to check the HDD context
549 */
550int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
551{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530552
553 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
554 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530556 "%s: HDD context is Null", __func__);
557 return -ENODEV;
558 }
559
560 if (pHddCtx->isLogpInProgress)
561 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530563 "%s: LOGP %s. Ignore!!", __func__,
564 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
565 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530566 return -EAGAIN;
567 }
568
Mihir Shete18156292014-03-11 15:38:30 +0530569 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530570 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530571 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530572 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
573 return -EAGAIN;
574 }
575 return 0;
576}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700577#ifdef CONFIG_ENABLE_LINUX_REG
578void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
579{
580 hdd_adapter_t *pAdapter = NULL;
581 hdd_station_ctx_t *pHddStaCtx = NULL;
582 eCsrPhyMode phyMode;
583 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530584
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700585 if (NULL == pHddCtx)
586 {
587 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
588 "HDD Context is null !!");
589 return ;
590 }
591
592 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
593 if (NULL == pAdapter)
594 {
595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
596 "pAdapter is null !!");
597 return ;
598 }
599
600 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
601 if (NULL == pHddStaCtx)
602 {
603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
604 "pHddStaCtx is null !!");
605 return ;
606 }
607
608 cfg_param = pHddCtx->cfg_ini;
609 if (NULL == cfg_param)
610 {
611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
612 "cfg_params not available !!");
613 return ;
614 }
615
616 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
617
618 if (!pHddCtx->isVHT80Allowed)
619 {
620 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
621 (eCSR_DOT11_MODE_11ac == phyMode) ||
622 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
623 {
624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
625 "Setting phymode to 11n!!");
626 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
627 }
628 }
629 else
630 {
631 /*New country Supports 11ac as well resetting value back from .ini*/
632 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
633 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
634 return ;
635 }
636
637 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
638 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
639 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
640 {
641 VOS_STATUS vosStatus;
642
643 // need to issue a disconnect to CSR.
644 INIT_COMPLETION(pAdapter->disconnect_comp_var);
645 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
646 pAdapter->sessionId,
647 eCSR_DISCONNECT_REASON_UNSPECIFIED );
648
649 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530650 {
651 long ret;
652
653 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700654 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530655 if (0 >= ret)
656 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
657 ret);
658 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700659
660 }
661}
662#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530663void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
664{
665 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
666 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
667 hdd_config_t *cfg_param;
668 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530669 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530670
671 if (NULL == pHddCtx)
672 {
673 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
674 "HDD Context is null !!");
675 return ;
676 }
677
678 cfg_param = pHddCtx->cfg_ini;
679
680 if (NULL == cfg_param)
681 {
682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
683 "cfg_params not available !!");
684 return ;
685 }
686
687 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
688
689 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
690 {
691 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
692 (eCSR_DOT11_MODE_11ac == phyMode) ||
693 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
694 {
695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
696 "Setting phymode to 11n!!");
697 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
698 }
699 }
700 else
701 {
702 /*New country Supports 11ac as well resetting value back from .ini*/
703 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
704 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
705 return ;
706 }
707
708 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
709 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
710 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
711 {
712 VOS_STATUS vosStatus;
713
714 // need to issue a disconnect to CSR.
715 INIT_COMPLETION(pAdapter->disconnect_comp_var);
716 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
717 pAdapter->sessionId,
718 eCSR_DISCONNECT_REASON_UNSPECIFIED );
719
720 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530721 {
722 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530723 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530724 if (ret <= 0)
725 {
726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
727 "wait on disconnect_comp_var is failed %ld", ret);
728 }
729 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530730
731 }
732}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700733#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530734
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700735void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
736{
737 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
738 hdd_config_t *cfg_param;
739
740 if (NULL == pHddCtx)
741 {
742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
743 "HDD Context is null !!");
744 return ;
745 }
746
747 cfg_param = pHddCtx->cfg_ini;
748
749 if (NULL == cfg_param)
750 {
751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
752 "cfg_params not available !!");
753 return ;
754 }
755
Agarwal Ashish738843c2014-09-25 12:27:56 +0530756 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
757 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700758 {
759 /*New country doesn't support DFS */
760 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
761 }
Ashish Kumar Dhanotiya445b3b92018-06-07 12:38:12 +0530762 else
763 {
764 /* New country Supports DFS as well resetting value back from .ini */
765 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter),
766 cfg_param->enableDFSChnlScan);
767 }
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700768
769}
770
Abhishek Singh00b71972016-01-07 10:51:04 +0530771#ifdef WLAN_FEATURE_RMC
772static int hdd_parse_setrmcenable_command(tANI_U8 *pValue, tANI_U8 *pRmcEnable)
773{
774 tANI_U8 *inPtr = pValue;
775 int tempInt;
776 int v = 0;
777 char buf[32];
778 *pRmcEnable = 0;
779
780 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
781 /*no argument after the command*/
782 if (NULL == inPtr)
783 {
784 return 0;
785 }
786
787 /*no space after the command*/
788 else if (SPACE_ASCII_VALUE != *inPtr)
789 {
790 return 0;
791 }
792
793 /*removing empty spaces*/
794 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
795
796 /*no argument followed by spaces*/
797 if ('\0' == *inPtr)
798 {
799 return 0;
800 }
801
802 /* getting the first argument which enables or disables RMC
803 * for input IP v4 address*/
Ashish Kumar Dhanotiya54d31a32017-08-04 17:12:44 +0530804 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530805 v = kstrtos32(buf, 10, &tempInt);
806 if ( v < 0)
807 {
808 return -EINVAL;
809 }
810
811 *pRmcEnable = tempInt;
812
813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
814 "ucRmcEnable: %d", *pRmcEnable);
815
816 return 0;
817}
818
819/* Function header left blank Intentionally */
820static int hdd_parse_setrmcactionperiod_command(tANI_U8 *pValue,
821 tANI_U32 *pActionPeriod)
822{
823 tANI_U8 *inPtr = pValue;
824 int tempInt;
825 int v = 0;
826 char buf[32];
827 *pActionPeriod = 0;
828
829 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
830 /*no argument after the command*/
831 if (NULL == inPtr)
832 {
833 return -EINVAL;
834 }
835
836 /*no space after the command*/
837 else if (SPACE_ASCII_VALUE != *inPtr)
838 {
839 return -EINVAL;
840 }
841
842 /*removing empty spaces*/
843 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
844
845 /*no argument followed by spaces*/
846 if ('\0' == *inPtr)
847 {
848 return 0;
849 }
850
851 /* getting the first argument which enables or disables RMC
852 * for input IP v4 address*/
Ashish Kumar Dhanotiya54d31a32017-08-04 17:12:44 +0530853 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530854 v = kstrtos32(buf, 10, &tempInt);
855 if ( v < 0)
856 {
857 return -EINVAL;
858 }
859
860 /* Range checking for passed paramter */
861 if (tempInt < WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN ||
862 tempInt > WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX)
863 {
864 return -EINVAL;
865 }
866
867 *pActionPeriod = tempInt;
868
869 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
870 "uActionPeriod: %d", *pActionPeriod);
871
872 return 0;
873}
Dundi Ravitejae110a042018-04-18 13:11:37 +0530874
875/**
876 * hdd_set_vowifi_mode() - Process VOWIFI command.
877 * @hdd_ctx: context handler
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530878 * @enable: Value to be sent as a part of the VOWIFI command
879 *
Dundi Ravitejae110a042018-04-18 13:11:37 +0530880 * Invoke the SME api if station is connected in 2.4 GHz band.
881 * Also start split scan if VOWIFIMODE and dynamic split scan
882 * both are enabled.
883
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530884 * Return: void
885 */
886void hdd_set_vowifi_mode(hdd_context_t *hdd_ctx, bool enable)
887{
888 tANI_U8 sta_chan;
889
Dundi Ravitejaab9d3092018-04-05 18:24:40 +0530890 if (!hdd_ctx->cfg_ini) {
891 hddLog(LOGE, "cfg_ini got NULL");
892 return;
893 }
894
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530895 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
896
Dundi Ravitejae110a042018-04-18 13:11:37 +0530897 if (CSR_IS_CHANNEL_24GHZ(sta_chan))
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530898 sme_set_vowifi_mode(hdd_ctx->hHal, enable);
Dundi Ravitejae110a042018-04-18 13:11:37 +0530899 else
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
901 "VoWiFi command rejected as not connected in 2.4GHz");
Dundi Ravitejae110a042018-04-18 13:11:37 +0530902
903 if (enable && hdd_ctx->cfg_ini->dynSplitscan) {
904 hdd_ctx->is_vowifi_enabled = true;
905 hdd_ctx->issplitscan_enabled = TRUE;
906 sme_enable_disable_split_scan(hdd_ctx->hHal,
907 hdd_ctx->cfg_ini->nNumStaChanCombinedConc,
908 hdd_ctx->cfg_ini->nNumP2PChanCombinedConc);
909 } else {
910 hdd_ctx->is_vowifi_enabled = false;
Dundi Ravitejaab9d3092018-04-05 18:24:40 +0530911 }
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530912}
Abhishek Singh00b71972016-01-07 10:51:04 +0530913
914/* Function header left blank Intentionally */
915static int hdd_parse_setrmcrate_command(tANI_U8 *pValue,
916 tANI_U32 *pRate, tTxrateinfoflags *pTxFlags)
917{
918 tANI_U8 *inPtr = pValue;
919 int tempInt;
920 int v = 0;
921 char buf[32];
922 *pRate = 0;
923 *pTxFlags = 0;
924
925 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
926 /*no argument after the command*/
927 if (NULL == inPtr)
928 {
929 return -EINVAL;
930 }
931
932 /*no space after the command*/
933 else if (SPACE_ASCII_VALUE != *inPtr)
934 {
935 return -EINVAL;
936 }
937
938 /*removing empty spaces*/
939 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
940
941 /*no argument followed by spaces*/
942 if ('\0' == *inPtr)
943 {
944 return 0;
945 }
946
947 /*
948 * getting the first argument which sets multicast rate.
949 */
Ashish Kumar Dhanotiya06f9f202017-08-04 15:26:27 +0530950 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530951 v = kstrtos32(buf, 10, &tempInt);
952 if ( v < 0)
953 {
954 return -EINVAL;
955 }
956
957 /*
958 * Validate the multicast rate.
959 */
960 switch (tempInt)
961 {
962 default:
963 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
964 "Unsupported rate: %d", tempInt);
965 return -EINVAL;
966 case 0:
967 case 6:
968 case 9:
969 case 12:
970 case 18:
971 case 24:
972 case 36:
973 case 48:
974 case 54:
975 *pTxFlags = eHAL_TX_RATE_LEGACY;
976 *pRate = tempInt * 10;
977 break;
978 case 65:
979 *pTxFlags = eHAL_TX_RATE_HT20;
980 *pRate = tempInt * 10;
981 break;
982 case 72:
983 *pTxFlags = eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;
984 *pRate = 722; /* fractional rate 72.2 Mbps */
985 break;
986 }
987
988 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
989 "Rate: %d", *pRate);
990
991 return 0;
992}
993
994/**---------------------------------------------------------------------------
995
996 \brief hdd_cfg80211_get_ibss_peer_info_cb() - Callback function for IBSS
997 Peer Info request
998
999 This is an asynchronous callback function from SME when the peer info
1000 is received
1001
1002 \pUserData -> Adapter private data
1003 \pPeerInfoRsp -> Peer info response
1004
1005 \return - 0 for success non-zero for failure
1006 --------------------------------------------------------------------------*/
1007static void
1008hdd_cfg80211_get_ibss_peer_info_cb(v_VOID_t *pUserData, v_VOID_t *pPeerInfoRsp)
1009{
1010 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pUserData;
1011 tSirPeerInfoRspParams *pPeerInfo = (tSirPeerInfoRspParams *)pPeerInfoRsp;
1012 hdd_station_ctx_t *pStaCtx;
1013 v_U8_t i;
1014
1015 /*Sanity check*/
1016 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
1017 {
1018 hddLog(LOGE,
1019 FL("invalid adapter or adapter has invalid magic"));
1020 return;
1021 }
1022
1023 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1024 if (NULL != pStaCtx && NULL != pPeerInfo &&
1025 eHAL_STATUS_SUCCESS == pPeerInfo->status)
1026 {
1027 pStaCtx->ibss_peer_info.status = pPeerInfo->status;
1028 pStaCtx->ibss_peer_info.numIBSSPeers = pPeerInfo->numPeers;
1029
1030 /* Paranoia check */
1031 if (pPeerInfo->numPeers < HDD_MAX_NUM_IBSS_STA)
1032 {
1033 for (i = 0; i < pPeerInfo->numPeers; i++)
1034 {
1035 memcpy(&pStaCtx->ibss_peer_info.ibssPeerList[i],
1036 &pPeerInfo->peerInfoParams[i],
1037 sizeof(hdd_ibss_peer_info_params_t));
1038 }
1039 hddLog(LOG1,
1040 FL("Peer Info copied in HDD"));
1041 }
1042 else
1043 {
1044 hddLog(LOGE,
1045 FL(" Number of peers %d returned is more than limit %d"),
1046 pPeerInfo->numPeers, HDD_MAX_NUM_IBSS_STA);
1047 }
1048 }
1049 else
1050 {
1051 hddLog(LOG1,
1052 FL("peerInfo returned is NULL"));
1053 }
1054
1055 complete(&pAdapter->ibss_peer_info_comp);
1056}
1057
1058/**---------------------------------------------------------------------------
1059
1060 \brief hdd_cfg80211_get_ibss_peer_info_all() -
1061
1062 Request function to get IBSS peer info from lower layers
1063
1064 \pAdapter -> Adapter context
1065
1066 \return - 0 for success non-zero for failure
1067 --------------------------------------------------------------------------*/
1068static
1069VOS_STATUS hdd_cfg80211_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
1070{
1071 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1072 long status;
1073 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1074
1075 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1076
1077 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1078 hdd_cfg80211_get_ibss_peer_info_cb,
1079 VOS_TRUE, 0xFF);
1080
1081 if (VOS_STATUS_SUCCESS == retStatus)
1082 {
1083 status = wait_for_completion_interruptible_timeout
1084 (&pAdapter->ibss_peer_info_comp,
1085 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1086
1087 /* status will be 0 if timed out */
1088 if (status <= 0)
1089 {
1090 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1091 __func__, status);
1092 retStatus = VOS_STATUS_E_FAILURE;
1093 return retStatus;
1094 }
1095 }
1096 else
1097 {
1098 hddLog(VOS_TRACE_LEVEL_WARN,
1099 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1100 }
1101
1102 return retStatus;
1103}
1104
1105/**---------------------------------------------------------------------------
1106
1107 \brief hdd_cfg80211_get_ibss_peer_info() -
1108
1109 Request function to get IBSS peer info from lower layers
1110
1111 \pAdapter -> Adapter context
1112 \staIdx -> Sta index for which the peer info is requested
1113
1114 \return - 0 for success non-zero for failure
1115 --------------------------------------------------------------------------*/
1116static VOS_STATUS
1117hdd_cfg80211_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx)
1118{
1119 long status;
1120 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1121 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1122
1123 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1124
1125 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1126 hdd_cfg80211_get_ibss_peer_info_cb,
1127 VOS_FALSE, staIdx);
1128
1129 if (VOS_STATUS_SUCCESS == retStatus)
1130 {
1131 status = wait_for_completion_interruptible_timeout
1132 (&pAdapter->ibss_peer_info_comp,
1133 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1134
1135 /* status = 0 on timeout */
1136 if (status <= 0)
1137 {
1138 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1139 __func__, status);
1140 retStatus = VOS_STATUS_E_FAILURE;
1141 return retStatus;
1142 }
1143 }
1144 else
1145 {
1146 hddLog(VOS_TRACE_LEVEL_WARN,
1147 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1148 }
1149
1150 return retStatus;
1151}
1152
1153/* Function header left blank Intentionally */
1154VOS_STATUS
1155hdd_parse_get_ibss_peer_info(tANI_U8 *pValue, v_MACADDR_t *pPeerMacAddr)
1156{
1157 tANI_U8 *inPtr = pValue;
1158 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1159
1160 /*no argument after the command*/
1161 if (NULL == inPtr)
1162 {
1163 return VOS_STATUS_E_FAILURE;;
1164 }
1165
1166 /*no space after the command*/
1167 else if (SPACE_ASCII_VALUE != *inPtr)
1168 {
1169 return VOS_STATUS_E_FAILURE;;
1170 }
1171
1172 /*removing empty spaces*/
1173 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
1174
1175 /*no argument followed by spaces*/
1176 if ('\0' == *inPtr)
1177 {
1178 return VOS_STATUS_E_FAILURE;;
1179 }
1180
1181 /*getting the first argument ie the peer mac address */
1182 if (inPtr[2] != ':' || inPtr[5] != ':' || inPtr[8] != ':' ||
1183 inPtr[11] != ':' || inPtr[14] != ':')
1184 {
1185 return VOS_STATUS_E_FAILURE;;
1186 }
1187 sscanf(inPtr, "%2x:%2x:%2x:%2x:%2x:%2x",
1188 (unsigned int *)&pPeerMacAddr->bytes[0],
1189 (unsigned int *)&pPeerMacAddr->bytes[1],
1190 (unsigned int *)&pPeerMacAddr->bytes[2],
1191 (unsigned int *)&pPeerMacAddr->bytes[3],
1192 (unsigned int *)&pPeerMacAddr->bytes[4],
1193 (unsigned int *)&pPeerMacAddr->bytes[5]);
1194
1195 /* The command buffer seems to be fine */
1196 return VOS_STATUS_SUCCESS;
1197}
1198
1199/* Function header left blank Intentionally */
1200static int hdd_parse_set_ibss_oui_data_command(tANI_U8 *command, tANI_U8 *ie,
1201 tANI_U32 limit)
1202{
1203 tANI_U8 len;
1204 tANI_U8 data;
1205
1206 /* skip white space */
1207 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1208 {
1209 command++;
1210 limit--;
1211 }
1212
1213 /* skip element id and element length */
1214 len = 2;
1215
1216 /* extract oui */
1217 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1218 (limit > 1))
1219 {
1220 /* Convert ASCII to decimal */
1221 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1222 ie[len++] = data;
1223 command += 2;
1224 limit -= 2;
1225 }
1226
1227 /* skip white space */
1228 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1229 {
1230 command++;
1231 limit--;
1232 }
1233
1234 /* extract data */
1235 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1236 (limit > 1))
1237 {
1238 /* Convert ASCII to decimal */
1239 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1240 ie[len++] = data;
1241 command += 2;
1242 limit -= 2;
1243 }
1244
1245 /* fill element id and element length */
1246 ie[0] = IE_EID_VENDOR;
1247 ie[1] = len - 2;
1248
1249 return len;
1250}
1251
1252static tANI_U32 hdd_find_ibss_wpa_ie_pos(tANI_U8 *addIePtr, tANI_U32 addIeLen)
1253{
1254 tANI_U32 ieLenPresent = 0;
1255 int left = addIeLen;
1256 v_U8_t *ptr = addIePtr;
1257 v_U8_t elem_id,elem_len;
1258
1259 while(left >= 2)
1260 {
1261 elem_id = ptr[0];
1262 elem_len = ptr[1];
1263 left -= 2;
1264 if(elem_len > left)
1265 {
1266 hddLog(LOGE,
1267 FL("****Invalid elem_len=%d left=%d*****"),
1268 elem_len,left);
1269 return 0;
1270 }
1271 if ((elem_id == IE_EID_VENDOR) &&
1272 (left >= WPA_OUI_TYPE_SIZE))
1273 {
1274 if (!memcmp(&ptr[2], WPA_OUI_TYPE,
1275 WPA_OUI_TYPE_SIZE))
1276 {
1277 ieLenPresent += elem_len + 2;
1278 return ieLenPresent;
1279 }
1280 }
1281 ieLenPresent += (elem_len + 2);
1282 left -= elem_len;
1283 ptr += (elem_len + 2);
1284 }
1285 return 0;
1286}
1287
1288#endif /* WLAN_FEATURE_RMC */
1289
Rajeev79dbe4c2013-10-05 11:03:42 +05301290#ifdef FEATURE_WLAN_BATCH_SCAN
1291
1292/**---------------------------------------------------------------------------
1293
1294 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
1295 input string
1296
1297 This function extracts assigned integer from string in below format:
1298 "STRING=10" : extracts integer 10 from this string
1299
1300 \param - pInPtr Pointer to input string
1301 \param - base Base for string to int conversion(10 for decimal 16 for hex)
1302 \param - pOutPtr Pointer to variable in which extracted integer needs to be
1303 assigned
1304 \param - pLastArg to tell whether it is last arguement in input string or
1305 not
1306
1307 \return - NULL for failure cases
1308 pointer to next arguement in input string for success cases
1309 --------------------------------------------------------------------------*/
1310static tANI_U8 *
1311hdd_extract_assigned_int_from_str
1312(
1313 tANI_U8 *pInPtr,
1314 tANI_U8 base,
1315 tANI_U32 *pOutPtr,
1316 tANI_U8 *pLastArg
1317)
1318{
1319 int tempInt;
1320 int v = 0;
1321 char buf[32];
1322 int val = 0;
1323 *pLastArg = FALSE;
1324
1325 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1326 if (NULL == pInPtr)
1327 {
1328 return NULL;
1329 }
1330
1331 pInPtr++;
1332
1333 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1334
1335 val = sscanf(pInPtr, "%32s ", buf);
1336 if (val < 0 && val > strlen(pInPtr))
1337 {
1338 return NULL;
1339 }
1340 pInPtr += val;
1341 v = kstrtos32(buf, base, &tempInt);
1342 if (v < 0)
1343 {
1344 return NULL;
1345 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -08001346 if (tempInt < 0)
1347 {
1348 tempInt = 0;
1349 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301350 *pOutPtr = tempInt;
1351
1352 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1353 if (NULL == pInPtr)
1354 {
1355 *pLastArg = TRUE;
1356 return NULL;
1357 }
1358 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1359
1360 return pInPtr;
1361}
1362
1363/**---------------------------------------------------------------------------
1364
1365 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
1366 input string
1367
1368 This function extracts assigned character from string in below format:
1369 "STRING=A" : extracts char 'A' from this string
1370
1371 \param - pInPtr Pointer to input string
1372 \param - pOutPtr Pointer to variable in which extracted char needs to be
1373 assigned
1374 \param - pLastArg to tell whether it is last arguement in input string or
1375 not
1376
1377 \return - NULL for failure cases
1378 pointer to next arguement in input string for success cases
1379 --------------------------------------------------------------------------*/
1380static tANI_U8 *
1381hdd_extract_assigned_char_from_str
1382(
1383 tANI_U8 *pInPtr,
1384 tANI_U8 *pOutPtr,
1385 tANI_U8 *pLastArg
1386)
1387{
1388 *pLastArg = FALSE;
1389
1390 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1391 if (NULL == pInPtr)
1392 {
1393 return NULL;
1394 }
1395
1396 pInPtr++;
1397
1398 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1399
1400 *pOutPtr = *pInPtr;
1401
1402 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1403 if (NULL == pInPtr)
1404 {
1405 *pLastArg = TRUE;
1406 return NULL;
1407 }
1408 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1409
1410 return pInPtr;
1411}
1412
1413
1414/**---------------------------------------------------------------------------
1415
1416 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
1417
1418 This function parses set batch scan command in below format:
1419 WLS_BATCHING_SET <space> followed by below arguements
1420 "SCANFREQ=XX" : Optional defaults to 30 sec
1421 "MSCAN=XX" : Required number of scans to attempt to batch
1422 "BESTN=XX" : Best Network (RSSI) defaults to 16
1423 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
1424 A. implies only 5 GHz , B. implies only 2.4GHz
1425 "RTT=X" : optional defaults to 0
1426 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
1427 error
1428
1429 For example input commands:
1430 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
1431 translated into set batch scan with following parameters:
1432 a) Frequence 60 seconds
1433 b) Batch 10 scans together
1434 c) Best RSSI to be 20
1435 d) 5GHz band only
1436 e) RTT is equal to 0
1437
1438 \param - pValue Pointer to input channel list
1439 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
1440
1441 \return - 0 for success non-zero for failure
1442
1443 --------------------------------------------------------------------------*/
1444static int
1445hdd_parse_set_batchscan_command
1446(
1447 tANI_U8 *pValue,
1448 tSirSetBatchScanReq *pHddSetBatchScanReq
1449)
1450{
1451 tANI_U8 *inPtr = pValue;
1452 tANI_U8 val = 0;
1453 tANI_U8 lastArg = 0;
Abhishek Singh00b71972016-01-07 10:51:04 +05301454 tANI_U32 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001455 tANI_U32 nMscan;
Abhishek Singh00b71972016-01-07 10:51:04 +05301456 tANI_U32 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
1457 tANI_U8 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1458 tANI_U32 nRtt = 0;
Rajeev Kumarc933d982013-11-18 20:04:20 -08001459 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +05301460
Rajeev79dbe4c2013-10-05 11:03:42 +05301461 /*go to space after WLS_BATCHING_SET command*/
1462 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1463 /*no argument after the command*/
1464 if (NULL == inPtr)
1465 {
1466 return -EINVAL;
1467 }
1468
1469 /*no space after the command*/
1470 else if (SPACE_ASCII_VALUE != *inPtr)
1471 {
1472 return -EINVAL;
1473 }
1474
1475 /*removing empty spaces*/
1476 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
1477
1478 /*no argument followed by spaces*/
1479 if ('\0' == *inPtr)
1480 {
1481 return -EINVAL;
1482 }
1483
1484 /*check and parse SCANFREQ*/
1485 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
1486 {
1487 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001488 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001489
Rajeev Kumarc933d982013-11-18 20:04:20 -08001490 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001491 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001492 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001493 }
1494
Rajeev79dbe4c2013-10-05 11:03:42 +05301495 if ( (NULL == inPtr) || (TRUE == lastArg))
1496 {
1497 return -EINVAL;
1498 }
1499 }
1500
1501 /*check and parse MSCAN*/
1502 if ((strncmp(inPtr, "MSCAN", 5) == 0))
1503 {
1504 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001505 &nMscan, &lastArg);
1506
1507 if (0 == nMscan)
1508 {
1509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1510 "invalid MSCAN=%d", nMscan);
1511 return -EINVAL;
1512 }
1513
Rajeev79dbe4c2013-10-05 11:03:42 +05301514 if (TRUE == lastArg)
1515 {
1516 goto done;
1517 }
1518 else if (NULL == inPtr)
1519 {
1520 return -EINVAL;
1521 }
1522 }
1523 else
1524 {
1525 return -EINVAL;
1526 }
1527
1528 /*check and parse BESTN*/
1529 if ((strncmp(inPtr, "BESTN", 5) == 0))
1530 {
1531 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001532 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001533
Rajeev Kumarc933d982013-11-18 20:04:20 -08001534 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001535 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001536 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001537 }
1538
Rajeev79dbe4c2013-10-05 11:03:42 +05301539 if (TRUE == lastArg)
1540 {
1541 goto done;
1542 }
1543 else if (NULL == inPtr)
1544 {
1545 return -EINVAL;
1546 }
1547 }
1548
1549 /*check and parse CHANNEL*/
1550 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
1551 {
1552 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -08001553
Rajeev79dbe4c2013-10-05 11:03:42 +05301554 if (('A' == val) || ('a' == val))
1555 {
c_hpothuebf89732014-02-25 13:00:24 +05301556 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301557 }
1558 else if (('B' == val) || ('b' == val))
1559 {
c_hpothuebf89732014-02-25 13:00:24 +05301560 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301561 }
1562 else
1563 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001564 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1565 }
1566
1567 if (TRUE == lastArg)
1568 {
1569 goto done;
1570 }
1571 else if (NULL == inPtr)
1572 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301573 return -EINVAL;
1574 }
1575 }
1576
1577 /*check and parse RTT*/
1578 if ((strncmp(inPtr, "RTT", 3) == 0))
1579 {
1580 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001581 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +05301582 if (TRUE == lastArg)
1583 {
1584 goto done;
1585 }
1586 if (NULL == inPtr)
1587 {
1588 return -EINVAL;
1589 }
1590 }
1591
1592
1593done:
1594
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001595 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1596 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1597 pHddSetBatchScanReq->bestNetwork = nBestN;
1598 pHddSetBatchScanReq->rfBand = ucRfBand;
1599 pHddSetBatchScanReq->rtt = nRtt;
1600
Rajeev79dbe4c2013-10-05 11:03:42 +05301601 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1602 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1603 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1604 pHddSetBatchScanReq->scanFrequency,
1605 pHddSetBatchScanReq->numberOfScansToBatch,
1606 pHddSetBatchScanReq->bestNetwork,
1607 pHddSetBatchScanReq->rfBand,
1608 pHddSetBatchScanReq->rtt);
1609
1610 return 0;
1611}/*End of hdd_parse_set_batchscan_command*/
1612
1613/**---------------------------------------------------------------------------
1614
1615 \brief hdd_set_batch_scan_req_callback () - This function is called after
1616 receiving set batch scan response from FW and it saves set batch scan
1617 response data FW to HDD context and sets the completion event on
1618 which hdd_ioctl is waiting
1619
1620 \param - callbackContext Pointer to HDD adapter
1621 \param - pRsp Pointer to set batch scan response data received from FW
1622
1623 \return - nothing
1624
1625 --------------------------------------------------------------------------*/
1626static void hdd_set_batch_scan_req_callback
1627(
1628 void *callbackContext,
1629 tSirSetBatchScanRsp *pRsp
1630)
1631{
1632 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1633 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1634
1635 /*sanity check*/
1636 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1637 {
1638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1639 "%s: Invalid pAdapter magic", __func__);
1640 VOS_ASSERT(0);
1641 return;
1642 }
1643 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1644
1645 /*save set batch scan response*/
1646 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1647
1648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1649 "Received set batch scan rsp from FW with nScansToBatch=%d",
1650 pHddSetBatchScanRsp->nScansToBatch);
1651
1652 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1653 complete(&pAdapter->hdd_set_batch_scan_req_var);
1654
1655 return;
1656}/*End of hdd_set_batch_scan_req_callback*/
1657
1658
1659/**---------------------------------------------------------------------------
1660
1661 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1662 info in hdd batch scan response queue
1663
1664 \param - pAdapter Pointer to hdd adapter
1665 \param - pAPMetaInfo Pointer to access point meta info
1666 \param - scanId scan ID of batch scan response
1667 \param - isLastAp tells whether AP is last AP in batch scan response or not
1668
1669 \return - nothing
1670
1671 --------------------------------------------------------------------------*/
1672static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1673 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1674{
1675 tHddBatchScanRsp *pHead;
1676 tHddBatchScanRsp *pNode;
1677 tHddBatchScanRsp *pPrev;
1678 tHddBatchScanRsp *pTemp;
1679 tANI_U8 ssidLen;
1680
1681 /*head of hdd batch scan response queue*/
1682 pHead = pAdapter->pBatchScanRsp;
1683
1684 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1685 if (NULL == pNode)
1686 {
1687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1688 "%s: Could not allocate memory", __func__);
1689 VOS_ASSERT(0);
1690 return;
1691 }
1692
1693 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1694 sizeof(pNode->ApInfo.bssid));
1695 ssidLen = strlen(pApMetaInfo->ssid);
1696 if (SIR_MAX_SSID_SIZE < ssidLen)
1697 {
1698 /*invalid scan result*/
1699 vos_mem_free(pNode);
1700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1701 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1702 return;
1703 }
1704 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1705 /*null terminate ssid*/
1706 pNode->ApInfo.ssid[ssidLen] = '\0';
1707 pNode->ApInfo.ch = pApMetaInfo->ch;
1708 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1709 pNode->ApInfo.age = pApMetaInfo->timestamp;
1710 pNode->ApInfo.batchId = scanId;
1711 pNode->ApInfo.isLastAp = isLastAp;
1712
1713 pNode->pNext = NULL;
1714 if (NULL == pHead)
1715 {
1716 pAdapter->pBatchScanRsp = pNode;
1717 }
1718 else
1719 {
1720 pTemp = pHead;
1721 while (NULL != pTemp)
1722 {
1723 pPrev = pTemp;
1724 pTemp = pTemp->pNext;
1725 }
1726 pPrev->pNext = pNode;
1727 }
1728
1729 return;
1730}/*End of hdd_populate_batch_scan_rsp_queue*/
1731
1732/**---------------------------------------------------------------------------
1733
1734 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1735 receiving batch scan response indication from FW. It saves get batch scan
1736 response data in HDD batch scan response queue. This callback sets the
1737 completion event on which hdd_ioctl is waiting only after getting complete
1738 batch scan response data from FW
1739
1740 \param - callbackContext Pointer to HDD adapter
1741 \param - pRsp Pointer to get batch scan response data received from FW
1742
1743 \return - nothing
1744
1745 --------------------------------------------------------------------------*/
1746static void hdd_batch_scan_result_ind_callback
1747(
1748 void *callbackContext,
1749 void *pRsp
1750)
1751{
1752 v_BOOL_t isLastAp;
1753 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001754 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301755 tANI_U32 numberScanList;
1756 tANI_U32 nextScanListOffset;
1757 tANI_U32 nextApMetaInfoOffset;
1758 hdd_adapter_t* pAdapter;
1759 tpSirBatchScanList pScanList;
1760 tpSirBatchScanNetworkInfo pApMetaInfo;
1761 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1762 tSirSetBatchScanReq *pReq;
1763
1764 pAdapter = (hdd_adapter_t *)callbackContext;
1765 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001766 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301767 {
1768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1769 "%s: Invalid pAdapter magic", __func__);
1770 VOS_ASSERT(0);
1771 return;
1772 }
1773
1774 /*initialize locals*/
1775 pReq = &pAdapter->hddSetBatchScanReq;
1776 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1777 isLastAp = FALSE;
1778 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001779 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301780 numberScanList = 0;
1781 nextScanListOffset = 0;
1782 nextApMetaInfoOffset = 0;
1783 pScanList = NULL;
1784 pApMetaInfo = NULL;
1785
1786 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1787 {
1788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001789 "%s: pBatchScanRsp is %pK pReq %pK", __func__, pBatchScanRsp, pReq);
Rajeev79dbe4c2013-10-05 11:03:42 +05301790 isLastAp = TRUE;
1791 goto done;
1792 }
1793
1794 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1796 "Batch scan rsp: numberScalList %d", numberScanList);
1797
1798 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1799 {
1800 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1801 "%s: numberScanList %d", __func__, numberScanList);
1802 isLastAp = TRUE;
1803 goto done;
1804 }
1805
1806 while (numberScanList)
1807 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001808 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301809 nextScanListOffset);
1810 if (NULL == pScanList)
1811 {
1812 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001813 "%s: pScanList is %pK", __func__, pScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301814 isLastAp = TRUE;
1815 goto done;
1816 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001817 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001819 "Batch scan rsp: numApMetaInfo %d scanId %d",
1820 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301821
1822 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1823 {
1824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1825 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1826 isLastAp = TRUE;
1827 goto done;
1828 }
1829
Rajeev Kumarce651e42013-10-21 18:57:15 -07001830 /*Initialize next AP meta info offset for next scan list*/
1831 nextApMetaInfoOffset = 0;
1832
Rajeev79dbe4c2013-10-05 11:03:42 +05301833 while (numApMetaInfo)
1834 {
1835 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1836 nextApMetaInfoOffset);
1837 if (NULL == pApMetaInfo)
1838 {
1839 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001840 "%s: pApMetaInfo is %pK", __func__, pApMetaInfo);
Rajeev79dbe4c2013-10-05 11:03:42 +05301841 isLastAp = TRUE;
1842 goto done;
1843 }
1844 /*calculate AP age*/
1845 pApMetaInfo->timestamp =
1846 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1847
1848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001849 "%s: bssId "MAC_ADDRESS_STR
1850 " ch %d rssi %d timestamp %d", __func__,
1851 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1852 pApMetaInfo->ch, pApMetaInfo->rssi,
1853 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301854
1855 /*mark last AP in batch scan response*/
1856 if ((TRUE == pBatchScanRsp->isLastResult) &&
1857 (1 == numberScanList) && (1 == numApMetaInfo))
1858 {
1859 isLastAp = TRUE;
1860 }
1861
1862 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1863 /*store batch scan repsonse in hdd queue*/
1864 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1865 pScanList->scanId, isLastAp);
1866 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1867
1868 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1869 numApMetaInfo--;
1870 }
1871
Rajeev Kumarce651e42013-10-21 18:57:15 -07001872 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1873 + (sizeof(tSirBatchScanNetworkInfo)
1874 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301875 numberScanList--;
1876 }
1877
1878done:
1879
1880 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1881 requested from hdd_ioctl*/
1882 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1883 (TRUE == isLastAp))
1884 {
1885 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1886 complete(&pAdapter->hdd_get_batch_scan_req_var);
1887 }
1888
1889 return;
1890}/*End of hdd_batch_scan_result_ind_callback*/
1891
1892/**---------------------------------------------------------------------------
1893
1894 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1895 response as per batch scan FR request format by putting proper markers
1896
1897 \param - pDest pointer to destination buffer
1898 \param - cur_len current length
1899 \param - tot_len total remaining size which can be written to user space
1900 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1901 \param - pAdapter Pointer to HDD adapter
1902
1903 \return - ret no of characters written
1904
1905 --------------------------------------------------------------------------*/
1906static tANI_U32
1907hdd_format_batch_scan_rsp
1908(
1909 tANI_U8 *pDest,
1910 tANI_U32 cur_len,
1911 tANI_U32 tot_len,
1912 tHddBatchScanRsp *pApMetaInfo,
1913 hdd_adapter_t* pAdapter
1914)
1915{
1916 tANI_U32 ret = 0;
1917 tANI_U32 rem_len = 0;
1918 tANI_U8 temp_len = 0;
1919 tANI_U8 temp_total_len = 0;
1920 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1921 tANI_U8 *pTemp = temp;
1922
1923 /*Batch scan reponse needs to be returned to user space in
1924 following format:
1925 "scancount=X\n" where X is the number of scans in current batch
1926 batch
1927 "trunc\n" optional present if current scan truncated
1928 "bssid=XX:XX:XX:XX:XX:XX\n"
1929 "ssid=XXXX\n"
1930 "freq=X\n" frequency in Mhz
1931 "level=XX\n"
1932 "age=X\n" ms
1933 "dist=X\n" cm (-1 if not available)
1934 "errror=X\n" (-1if not available)
1935 "====\n" (end of ap marker)
1936 "####\n" (end of scan marker)
1937 "----\n" (end of results)*/
1938 /*send scan result in above format to user space based on
1939 available length*/
1940 /*The GET response may have more data than the driver can return in its
1941 buffer. In that case the buffer should be filled to the nearest complete
1942 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1943 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1944 The final buffer should end with "----\n"*/
1945
1946 /*sanity*/
1947 if (cur_len > tot_len)
1948 {
1949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1950 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1951 return 0;
1952 }
1953 else
1954 {
1955 rem_len = (tot_len - cur_len);
1956 }
1957
1958 /*end scan marker*/
1959 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1960 {
1961 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1962 pTemp += temp_len;
1963 temp_total_len += temp_len;
1964 }
1965
1966 /*bssid*/
1967 temp_len = snprintf(pTemp, sizeof(temp),
1968 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1969 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1970 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1971 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1972 pTemp += temp_len;
1973 temp_total_len += temp_len;
1974
1975 /*ssid*/
1976 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1977 pApMetaInfo->ApInfo.ssid);
1978 pTemp += temp_len;
1979 temp_total_len += temp_len;
1980
1981 /*freq*/
1982 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001983 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301984 pTemp += temp_len;
1985 temp_total_len += temp_len;
1986
1987 /*level*/
1988 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1989 pApMetaInfo->ApInfo.rssi);
1990 pTemp += temp_len;
1991 temp_total_len += temp_len;
1992
1993 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001994 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301995 pApMetaInfo->ApInfo.age);
1996 pTemp += temp_len;
1997 temp_total_len += temp_len;
1998
1999 /*dist*/
2000 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
2001 pTemp += temp_len;
2002 temp_total_len += temp_len;
2003
2004 /*error*/
2005 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
2006 pTemp += temp_len;
2007 temp_total_len += temp_len;
2008
2009 /*end AP marker*/
2010 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
2011 pTemp += temp_len;
2012 temp_total_len += temp_len;
2013
2014 /*last AP in batch scan response*/
2015 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
2016 {
2017 /*end scan marker*/
2018 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
2019 pTemp += temp_len;
2020 temp_total_len += temp_len;
2021
2022 /*end batch scan result marker*/
2023 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
2024 pTemp += temp_len;
2025 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002026
Rajeev79dbe4c2013-10-05 11:03:42 +05302027 }
2028
2029 if (temp_total_len < rem_len)
2030 {
2031 ret = temp_total_len + 1;
2032 strlcpy(pDest, temp, ret);
2033 pAdapter->isTruncated = FALSE;
2034 }
2035 else
2036 {
2037 pAdapter->isTruncated = TRUE;
2038 if (rem_len >= strlen("%%%%"))
2039 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08002040 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05302041 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08002042 else
Rajeev79dbe4c2013-10-05 11:03:42 +05302043 {
2044 ret = 0;
2045 }
2046 }
2047
2048 return ret;
2049
2050}/*End of hdd_format_batch_scan_rsp*/
2051
2052/**---------------------------------------------------------------------------
2053
2054 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
2055 buffer starting with head of hdd batch scan response queue
2056
2057 \param - pAdapter Pointer to HDD adapter
2058 \param - pDest Pointer to user data buffer
2059 \param - cur_len current offset in user buffer
2060 \param - rem_len remaining no of bytes in user buffer
2061
2062 \return - number of bytes written in user buffer
2063
2064 --------------------------------------------------------------------------*/
2065
2066tANI_U32 hdd_populate_user_batch_scan_rsp
2067(
2068 hdd_adapter_t* pAdapter,
2069 tANI_U8 *pDest,
2070 tANI_U32 cur_len,
2071 tANI_U32 rem_len
2072)
2073{
2074 tHddBatchScanRsp *pHead;
2075 tHddBatchScanRsp *pPrev;
2076 tANI_U32 len;
2077
Rajeev79dbe4c2013-10-05 11:03:42 +05302078 pAdapter->isTruncated = FALSE;
2079
2080 /*head of hdd batch scan response queue*/
2081 pHead = pAdapter->pBatchScanRsp;
2082 while (pHead)
2083 {
2084 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
2085 pAdapter);
2086 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07002087 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05302088 cur_len += len;
2089 if(TRUE == pAdapter->isTruncated)
2090 {
2091 /*result is truncated return rest of scan rsp in next req*/
2092 cur_len = rem_len;
2093 break;
2094 }
2095 pPrev = pHead;
2096 pHead = pHead->pNext;
2097 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08002098 if (TRUE == pPrev->ApInfo.isLastAp)
2099 {
2100 pAdapter->prev_batch_id = 0;
2101 }
2102 else
2103 {
2104 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
2105 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302106 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002107 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05302108 }
2109
2110 return cur_len;
2111}/*End of hdd_populate_user_batch_scan_rsp*/
2112
2113/**---------------------------------------------------------------------------
2114
2115 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
2116 scan response data from HDD queue to user space
2117 It does following in detail:
2118 a) if HDD has enough data in its queue then it 1st copies data to user
2119 space and then send get batch scan indication message to FW. In this
2120 case it does not wait on any event and batch scan response data will
2121 be populated in HDD response queue in MC thread context after receiving
2122 indication from FW
2123 b) else send get batch scan indication message to FW and wait on an event
2124 which will be set once HDD receives complete batch scan response from
2125 FW and then this function returns batch scan response to user space
2126
2127 \param - pAdapter Pointer to HDD adapter
2128 \param - pPrivData Pointer to priv_data
2129
2130 \return - 0 for success -EFAULT for failure
2131
2132 --------------------------------------------------------------------------*/
2133
2134int hdd_return_batch_scan_rsp_to_user
2135(
2136 hdd_adapter_t* pAdapter,
2137 hdd_priv_data_t *pPrivData,
2138 tANI_U8 *command
2139)
2140{
2141 tANI_U8 *pDest;
2142 tANI_U32 count = 0;
2143 tANI_U32 len = 0;
2144 tANI_U32 cur_len = 0;
2145 tANI_U32 rem_len = 0;
2146 eHalStatus halStatus;
2147 unsigned long rc;
2148 tSirTriggerBatchScanResultInd *pReq;
2149
2150 pReq = &pAdapter->hddTriggerBatchScanResultInd;
2151 pReq->param = 0;/*batch scan client*/
2152 pDest = (tANI_U8 *)(command + pPrivData->used_len);
2153 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
2154
2155 cur_len = pPrivData->used_len;
2156 if (pPrivData->total_len > pPrivData->used_len)
2157 {
2158 rem_len = pPrivData->total_len - pPrivData->used_len;
2159 }
2160 else
2161 {
2162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2163 "%s: Invalid user data buffer total_len %d used_len %d",
2164 __func__, pPrivData->total_len, pPrivData->used_len);
2165 return -EFAULT;
2166 }
2167
2168 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2169 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2170 cur_len, rem_len);
2171 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2172
2173 /*enough scan result available in cache to return to user space or
2174 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08002175 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05302176 {
2177 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
2178 halStatus = sme_TriggerBatchScanResultInd(
2179 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2180 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
2181 pAdapter);
2182 if ( eHAL_STATUS_SUCCESS == halStatus )
2183 {
2184 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
2185 {
2186 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
2187 rc = wait_for_completion_timeout(
2188 &pAdapter->hdd_get_batch_scan_req_var,
2189 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
Abhishek Singh00b71972016-01-07 10:51:04 +05302190 if (0 >= rc)
Rajeev79dbe4c2013-10-05 11:03:42 +05302191 {
2192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Abhishek Singh00b71972016-01-07 10:51:04 +05302193 "%s: wait on hdd_get_batch_scan_req_var failed %ld",
2194 __func__, rc);
Rajeev79dbe4c2013-10-05 11:03:42 +05302195 return -EFAULT;
2196 }
2197 }
2198
2199 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07002200 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05302201 pDest += len;
2202 cur_len += len;
2203
2204 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2205 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2206 cur_len, rem_len);
2207 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2208
2209 count = 0;
2210 len = (len - pPrivData->used_len);
2211 pDest = (command + pPrivData->used_len);
2212 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002213 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302214 while(count < len)
2215 {
2216 printk("%c", *(pDest + count));
2217 count++;
2218 }
2219 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2220 "%s: copy %d data to user buffer", __func__, len);
2221 if (copy_to_user(pPrivData->buf, pDest, len))
2222 {
2223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2224 "%s: failed to copy data to user buffer", __func__);
2225 return -EFAULT;
2226 }
2227 }
2228 else
2229 {
2230 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2231 "sme_GetBatchScanScan returned failure halStatus %d",
2232 halStatus);
2233 return -EINVAL;
2234 }
2235 }
2236 else
2237 {
Rajeev79dbe4c2013-10-05 11:03:42 +05302238 count = 0;
2239 len = (len - pPrivData->used_len);
2240 pDest = (command + pPrivData->used_len);
2241 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002242 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302243 while(count < len)
2244 {
2245 printk("%c", *(pDest + count));
2246 count++;
2247 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08002248 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2249 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05302250 if (copy_to_user(pPrivData->buf, pDest, len))
2251 {
2252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2253 "%s: failed to copy data to user buffer", __func__);
2254 return -EFAULT;
2255 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302256 }
2257
2258 return 0;
2259} /*End of hdd_return_batch_scan_rsp_to_user*/
2260
Rajeev Kumar8b373292014-01-08 20:36:55 -08002261/**---------------------------------------------------------------------------
2262
2263 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
2264 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
2265 WLS_BATCHING VERSION
2266 WLS_BATCHING SET
2267 WLS_BATCHING GET
2268 WLS_BATCHING STOP
2269
2270 \param - pAdapter Pointer to HDD adapter
2271 \param - pPrivdata Pointer to priv_data
2272 \param - command Pointer to command
2273
2274 \return - 0 for success -EFAULT for failure
2275
2276 --------------------------------------------------------------------------*/
2277
2278int hdd_handle_batch_scan_ioctl
2279(
2280 hdd_adapter_t *pAdapter,
2281 hdd_priv_data_t *pPrivdata,
2282 tANI_U8 *command
2283)
2284{
2285 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08002286 hdd_context_t *pHddCtx;
2287
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302288 ENTER();
2289
Yue Mae36e3552014-03-05 17:06:20 -08002290 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2291 ret = wlan_hdd_validate_context(pHddCtx);
2292 if (ret)
2293 {
Yue Mae36e3552014-03-05 17:06:20 -08002294 goto exit;
2295 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002296
2297 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
2298 {
2299 char extra[32];
2300 tANI_U8 len = 0;
2301 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
2302
2303 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2304 {
2305 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2306 "%s: Batch scan feature is not supported by FW", __func__);
2307 ret = -EINVAL;
2308 goto exit;
2309 }
2310
2311 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
2312 version);
2313 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2314 {
2315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2316 "%s: failed to copy data to user buffer", __func__);
2317 ret = -EFAULT;
2318 goto exit;
2319 }
2320 ret = HDD_BATCH_SCAN_VERSION;
2321 }
2322 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
2323 {
2324 int status;
2325 tANI_U8 *value = (command + 16);
2326 eHalStatus halStatus;
2327 unsigned long rc;
2328 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
2329 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
2330
2331 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2332 {
2333 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2334 "%s: Batch scan feature is not supported by FW", __func__);
2335 ret = -EINVAL;
2336 goto exit;
2337 }
2338
2339 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
2340 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
2341 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
2342 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
2343 {
2344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302345 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08002346 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302347 hdd_device_modetoString(pAdapter->device_mode),
2348 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002349 ret = -EINVAL;
2350 goto exit;
2351 }
2352
2353 status = hdd_parse_set_batchscan_command(value, pReq);
2354 if (status)
2355 {
2356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2357 "Invalid WLS_BATCHING SET command");
2358 ret = -EINVAL;
2359 goto exit;
2360 }
2361
2362
2363 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
2364 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2365 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
2366 pAdapter);
2367
2368 if ( eHAL_STATUS_SUCCESS == halStatus )
2369 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302370 char extra[32];
2371 tANI_U8 len = 0;
2372 tANI_U8 mScan = 0;
2373
Rajeev Kumar8b373292014-01-08 20:36:55 -08002374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2375 "sme_SetBatchScanReq returned success halStatus %d",
2376 halStatus);
2377 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
2378 {
2379 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
2380 rc = wait_for_completion_timeout(
2381 &pAdapter->hdd_set_batch_scan_req_var,
2382 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
2383 if (0 == rc)
2384 {
2385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2386 "%s: Timeout waiting for set batch scan to complete",
2387 __func__);
2388 ret = -EINVAL;
2389 goto exit;
2390 }
2391 }
2392 if ( !pRsp->nScansToBatch )
2393 {
2394 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2395 "%s: Received set batch scan failure response from FW",
2396 __func__);
2397 ret = -EINVAL;
2398 goto exit;
2399 }
2400 /*As per the Batch Scan Framework API we should return the MIN of
2401 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302402 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002403
2404 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
2405
2406 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2407 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302408 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
2409 len = scnprintf(extra, sizeof(extra), "%d", mScan);
2410 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2411 {
2412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2413 "%s: failed to copy MSCAN value to user buffer", __func__);
2414 ret = -EFAULT;
2415 goto exit;
2416 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002417 }
2418 else
2419 {
2420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2421 "sme_SetBatchScanReq returned failure halStatus %d",
2422 halStatus);
2423 ret = -EINVAL;
2424 goto exit;
2425 }
2426 }
2427 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
2428 {
2429 eHalStatus halStatus;
2430 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
2431 pInd->param = 0;
2432
2433 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2434 {
2435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2436 "%s: Batch scan feature is not supported by FW", __func__);
2437 ret = -EINVAL;
2438 goto exit;
2439 }
2440
2441 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2442 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002444 "Batch scan is not yet enabled batch scan state %d",
2445 pAdapter->batchScanState);
2446 ret = -EINVAL;
2447 goto exit;
2448 }
2449
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002450 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2451 hdd_deinit_batch_scan(pAdapter);
2452 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2453
Rajeev Kumar8b373292014-01-08 20:36:55 -08002454 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
2455
2456 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
2457 pAdapter->sessionId);
2458 if ( eHAL_STATUS_SUCCESS == halStatus )
2459 {
2460 ret = 0;
2461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2462 "sme_StopBatchScanInd returned success halStatus %d",
2463 halStatus);
2464 }
2465 else
2466 {
2467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2468 "sme_StopBatchScanInd returned failure halStatus %d",
2469 halStatus);
2470 ret = -EINVAL;
2471 goto exit;
2472 }
2473 }
2474 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
2475 {
2476 tANI_U32 remain_len;
2477
2478 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2479 {
2480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2481 "%s: Batch scan feature is not supported by FW", __func__);
2482 ret = -EINVAL;
2483 goto exit;
2484 }
2485
2486 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2487 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302488 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002489 "Batch scan is not yet enabled could not return results"
2490 "Batch Scan state %d",
2491 pAdapter->batchScanState);
2492 ret = -EINVAL;
2493 goto exit;
2494 }
2495
2496 pPrivdata->used_len = 16;
2497 remain_len = pPrivdata->total_len - pPrivdata->used_len;
2498 if (remain_len < pPrivdata->total_len)
2499 {
2500 /*Clear previous batch scan response data if any*/
2501 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
2502 }
2503 else
2504 {
2505 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2506 "Invalid total length from user space can't fetch batch"
2507 " scan response total_len %d used_len %d remain len %d",
2508 pPrivdata->total_len, pPrivdata->used_len, remain_len);
2509 ret = -EINVAL;
2510 goto exit;
2511 }
2512 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
2513 }
2514
2515exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302516 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08002517 return ret;
2518}
2519
2520
Rajeev79dbe4c2013-10-05 11:03:42 +05302521#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
2522
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302523#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
2524/**
2525 * hdd_assign_handoff_src_reassoc - Set handoff source as REASSOC
2526 * to Handoff request
2527 * @handoffInfo: Pointer to Handoff request
2528 * @src: enum of handoff_src
2529 * Return: None
2530 */
2531#ifndef QCA_WIFI_ISOC
2532static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2533 *handoffInfo, handoff_src src)
2534{
2535 handoffInfo->src = src;
2536}
2537#else
2538static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2539 *handoffInfo, handoff_src src)
2540{
2541}
2542#endif
2543
2544/**
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302545 * hdd_reassoc() - perform a user space-directed reassoc
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302546 *
2547 * @pAdapter: Adapter upon which the command was received
2548 * @bssid: BSSID with which to reassociate
2549 * @channel: channel upon which to reassociate
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302550 * @src: The source for the trigger of this action
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302551 *
2552 * Return: 0 for success non-zero for failure
2553 */
2554#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302555int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302556 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302557{
2558 hdd_station_ctx_t *pHddStaCtx;
2559 tCsrHandoffRequest handoffInfo;
2560 hdd_context_t *pHddCtx = NULL;
2561 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2562
2563 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2564
2565 /* if not associated, no need to proceed with reassoc */
2566 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2567 hddLog(LOG1, FL("Not associated"));
2568 return -EINVAL;
2569 }
2570
2571 /* if the target bssid is same as currently associated AP,
2572 then no need to proceed with reassoc */
2573 if (!memcmp(bssid, pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr))) {
2574 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
2575 return -EINVAL;
2576 }
2577
2578 /* Check channel number is a valid channel number */
2579 if (VOS_STATUS_SUCCESS !=
2580 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
2581 hddLog(LOGE, FL("Invalid Channel %d"), channel);
2582 return -EINVAL;
2583 }
2584
2585 /* Proceed with reassoc */
2586 handoffInfo.channel = channel;
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302587 hdd_assign_handoff_src_reassoc(&handoffInfo, src);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302588 memcpy(handoffInfo.bssid, bssid, sizeof(tSirMacAddr));
2589 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
2590 return 0;
2591}
2592#else
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302593int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302594 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302595{
2596 return -EPERM;
2597}
2598#endif
2599
2600/**
2601 * hdd_parse_reassoc_v1() - parse version 1 of the REASSOC command
2602 * This function parses the v1 REASSOC command with the format
2603 * REASSOC xx:xx:xx:xx:xx:xx CH where "xx:xx:xx:xx:xx:xx" is the
2604 * Hex-ASCII representation of the BSSID and CH is the ASCII
2605 * representation of the channel. For example
2606 * REASSOC 00:0a:0b:11:22:33 48
2607 *
2608 * @pAdapter: Adapter upon which the command was received
2609 * @command: ASCII text command that was received
2610 *
2611 * Return: 0 for success non-zero for failure
2612 */
2613static int
2614hdd_parse_reassoc_v1(hdd_adapter_t *pAdapter, const char *command)
2615{
2616 tANI_U8 channel = 0;
2617 tSirMacAddr bssid;
2618 int ret;
2619
2620 ret = hdd_parse_reassoc_command_v1_data(command, bssid, &channel);
2621 if (ret)
2622 hddLog(LOGE, FL("Failed to parse reassoc command data"));
2623 else
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302624 ret = hdd_reassoc(pAdapter, bssid, channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302625
2626 return ret;
2627}
2628
2629/**
2630 * hdd_parse_reassoc_v2() - parse version 2 of the REASSOC command
2631 * This function parses the v2 REASSOC command with the format
2632 * REASSOC <android_wifi_reassoc_params>
2633 *
2634 * @pAdapter: Adapter upon which the command was received
2635 * @command: command that was received, ASCII command followed
2636 * by binary data
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302637 * @total_len: Total length of the command received
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302638 *
2639 * Return: 0 for success non-zero for failure
2640 */
2641static int
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302642hdd_parse_reassoc_v2(hdd_adapter_t *pAdapter, const char *command,
2643 int total_len)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302644{
2645 struct android_wifi_reassoc_params params;
2646 tSirMacAddr bssid;
2647 int ret;
2648
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302649 if (total_len < sizeof(params) + 8) {
2650 hddLog(LOGE, FL("Invalid command length"));
2651 return -EINVAL;
2652 }
2653
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302654 /* The params are located after "REASSOC " */
2655 memcpy(&params, command + 8, sizeof(params));
2656
2657 if (!mac_pton(params.bssid, (u8 *)&bssid)) {
2658 hddLog(LOGE, FL("MAC address parsing failed"));
2659 ret = -EINVAL;
2660 } else {
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302661 ret = hdd_reassoc(pAdapter, bssid, params.channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302662 }
2663 return ret;
2664}
2665
2666/**
2667 * hdd_parse_reassoc() - parse the REASSOC command
2668 * There are two different versions of the REASSOC command.Version 1
2669 * of the command contains a parameter list that is ASCII characters
2670 * whereas version 2 contains a combination of ASCII and binary
2671 * payload. Determine if a version 1 or a version 2 command is being
2672 * parsed by examining the parameters, and then dispatch the parser
2673 * that is appropriate for the command.
2674 *
2675 * @pAdapter: Adapter upon which the command was received
2676 * @command: command that was received
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302677 * @total_len: Total length of the command received
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302678 *
2679 * Return: 0 for success non-zero for failure
2680 */
2681static int
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302682hdd_parse_reassoc(hdd_adapter_t *pAdapter, const char *command, int total_len)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302683{
2684 int ret;
2685
2686 /*
2687 * both versions start with "REASSOC"
2688 * v1 has a bssid and channel # as an ASCII string
2689 * REASSOC xx:xx:xx:xx:xx:xx CH
2690 * v2 has a C struct
2691 * REASSOC <binary c struct>
2692 *
2693 * The first field in the v2 struct is also the bssid in ASCII.
2694 * But in the case of a v2 message the BSSID is NUL-terminated.
2695 * Hence we can peek at that offset to see if this is V1 or V2
2696 * REASSOC xx:xx:xx:xx:xx:xx*
2697 * 1111111111222222
2698 * 01234567890123456789012345
2699 */
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302700
2701 if (total_len < 26) {
2702 hddLog(LOGE, FL("Invalid command (total_len=%d)"), total_len);
2703 return -EINVAL;
2704 }
2705
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302706 if (command[25])
2707 ret = hdd_parse_reassoc_v1(pAdapter, command);
2708 else
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302709 ret = hdd_parse_reassoc_v2(pAdapter, command, total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302710
2711 return ret;
2712}
2713#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE FEATURE_WLAN_LFR */
2714
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302715struct bcn_miss_rate_priv {
2716 int bcn_miss_rate;
2717};
2718
2719/**
2720 * get_bcn_miss_rate_cb() callback invoked on receiving beacon miss
2721 * rate from firmware
2722 * @status: Status of get beacon miss rate operation
2723 * @bcnMissRate: Beacon miss rate
2724 * @context: Context passed while registering callback
2725 *
2726 * This function is invoked by WDA layer on receiving
2727 * WDI_GET_BCN_MISS_RATE_RSP
2728 *
2729 * Return: None
2730 */
2731static void get_bcn_miss_rate_cb(VOS_STATUS status, int bcnMissRate,
2732 void *context)
c_hpothu92367912014-05-01 15:18:17 +05302733{
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302734 struct hdd_request *request;
2735 struct bcn_miss_rate_priv *priv;
c_hpothu39eb1e32014-06-26 16:31:50 +05302736
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302737 request = hdd_request_get(context);
2738 if (!request) {
2739 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
2740 return;
2741 }
c_hpothu92367912014-05-01 15:18:17 +05302742
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302743 priv = hdd_request_priv(request);
c_hpothu92367912014-05-01 15:18:17 +05302744
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302745 if (VOS_STATUS_SUCCESS == status)
2746 priv->bcn_miss_rate = bcnMissRate;
2747 else
2748 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
c_hpothu92367912014-05-01 15:18:17 +05302749
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302750 hdd_request_complete(request);
2751 hdd_request_put(request);
Hanumanth Reddy Pothulad0d3c172018-05-02 18:53:05 +05302752
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302753 return;
c_hpothu92367912014-05-01 15:18:17 +05302754}
2755
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302756struct fw_stats_priv {
2757 tSirFwStatsResult *fw_stats;
2758};
2759
2760/**
2761 * hdd_fw_stats_cb() callback invoked on receiving firmware stats
2762 * from firmware
2763 * @status: Status of get firmware stats operation
2764 * @fwStatsResult: firmware stats
2765 * @context: Context passed while registering callback
2766 *
2767 * This function is invoked by WDA layer on receiving
2768 * WDI_GET_FW_STATS_RSP
2769 *
2770 * Return: None
2771 */
2772static void hdd_fw_stats_cb(VOS_STATUS status,
2773 tSirFwStatsResult *fwStatsResult, void *context)
Satyanarayana Dash72806012014-12-02 14:30:08 +05302774{
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302775 struct hdd_request *request;
2776 struct fw_stats_priv *priv;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302777
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302778 hddLog(VOS_TRACE_LEVEL_INFO, FL("with status = %d"),status);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302779
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302780 request = hdd_request_get(context);
2781 if (!request) {
2782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
2783 return;
2784 }
2785 priv = hdd_request_priv(request);
2786
2787 if (VOS_STATUS_SUCCESS == status)
2788 *priv->fw_stats = *fwStatsResult;
2789 else
2790 priv->fw_stats = NULL;
2791
2792 hdd_request_complete(request);
2793 hdd_request_put(request);
2794 return;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302795}
2796
jge35567202017-06-21 16:39:38 +08002797/*
2798 *hdd_parse_setmaxtxpower_command() - HDD Parse MAXTXPOWER command
2799 *@pValue Pointer to MAXTXPOWER command
2800 *@pTxPower Pointer to tx power
2801 *
2802 *This function parses the MAXTXPOWER command passed in the format
2803 * MAXTXPOWER<space>X(Tx power in dbm)
2804 * For example input commands:
2805 * 1) MAXTXPOWER -8 -> This is translated into set max TX power to -8 dbm
2806 * 2) MAXTXPOWER -23 -> This is translated into set max TX power to -23 dbm
2807 *
2808 *return - 0 for success non-zero for failure
2809 */
2810static int hdd_parse_setmaxtxpower_command(unsigned char *pValue, int *pTxPower)
2811{
2812 unsigned char *inPtr = pValue;
2813 int tempInt;
2814 int v = 0;
2815 *pTxPower = 0;
2816
2817 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
2818 /* no argument after the command */
2819 if (NULL == inPtr)
2820 return -EINVAL;
2821 /* no space after the command */
2822 else if (SPACE_ASCII_VALUE != *inPtr)
2823 return -EINVAL;
2824
2825 /* removing empty spaces */
2826 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
2827
2828 /* no argument followed by spaces */
2829 if ('\0' == *inPtr)
2830 return 0;
2831
2832 v = kstrtos32(inPtr, 10, &tempInt);
2833
2834 /* Range checking for passed parameter */
2835 if ((tempInt < HDD_MIN_TX_POWER) || (tempInt > HDD_MAX_TX_POWER))
2836 return -EINVAL;
2837
2838 *pTxPower = tempInt;
2839
2840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2841 "SETMAXTXPOWER: %d", *pTxPower);
2842
2843 return 0;
2844}
2845
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302846static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2847{
2848 int ret = 0;
2849
2850 if (!pCfg || !command || !extra || !len)
2851 {
2852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2853 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2854 ret = -EINVAL;
2855 return ret;
2856 }
2857
2858 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2859 {
2860 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2861 (int)pCfg->nActiveMaxChnTime);
2862 return ret;
2863 }
2864 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2865 {
2866 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2867 (int)pCfg->nActiveMinChnTime);
2868 return ret;
2869 }
2870 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2871 {
2872 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2873 (int)pCfg->nPassiveMaxChnTime);
2874 return ret;
2875 }
2876 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2877 {
2878 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2879 (int)pCfg->nPassiveMinChnTime);
2880 return ret;
2881 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302882 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2883 {
2884 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2885 (int)pCfg->nActiveMaxChnTime);
2886 return ret;
2887 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302888 else
2889 {
2890 ret = -EINVAL;
2891 }
2892
2893 return ret;
2894}
2895
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05302896/**
2897 * hdd_btc_get_dwell_time() - Get BTC dwell time parameters
2898 * @pCfg: Pointer to HDD context
2899 * @command: ASCII text command that is received
2900 * @extra: Pointer to copy data sent to user
2901 * @n: size of 'extra' buffer
2902 * @len: length copied to 'extra' buffer
2903 *
2904 * Driver commands:
2905 * wpa_cli DRIVER BTCGETDWELLTIME ESCO MAX
2906 * wpa_cli DRIVER BTCGETDWELLTIME ESCO MIN
2907 * wpa_cli DRIVER BTCGETDWELLTIME SCO MAX
2908 * wpa_cli DRIVER BTCGETDWELLTIME SCO MIN
2909 *
2910 * Return: 0 for success non-zero for failure
2911 */
2912
2913static int hdd_btc_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command,
2914 char *extra, tANI_U8 n, tANI_U8 *len)
2915{
2916 int ret = 0;
2917
2918 if (!pCfg || !command || !extra || !len)
2919 {
2920 hddLog(LOGE, FL("Argument passsed for BTCGETDWELLTIME is incorrect"));
2921 ret = -EINVAL;
2922 return ret;
2923 }
2924
2925 if (strncmp(command, "BTCGETDWELLTIME ESCO MAX", 24) == 0)
2926 {
2927 *len = scnprintf(extra, n, "BTCGETDWELLTIME ESCO MAX %u\n",
2928 (int)pCfg->max_chntime_btc_esco);
2929 return ret;
2930 }
2931 else if (strncmp(command, "BTCGETDWELLTIME ESCO MIN", 24) == 0)
2932 {
2933 *len = scnprintf(extra, n, "BTCGETDWELLTIME ESCO MIN %u\n",
2934 (int)pCfg->min_chntime_btc_esco);
2935 return ret;
2936 }
2937 else if (strncmp(command, "BTCGETDWELLTIME SCO MAX", 23) == 0)
2938 {
2939 *len = scnprintf(extra, n, "BTCGETDWELLTIME SCO MAX %u\n",
2940 (int)pCfg->max_chntime_btc_sco);
2941 return ret;
2942 }
2943 else if (strncmp(command, "BTCGETDWELLTIME SCO MIN", 23) == 0)
2944 {
2945 *len = scnprintf(extra, n, "BTCGETDWELLTIME SCO MIN %u\n",
2946 (int)pCfg->min_chntime_btc_sco);
2947 return ret;
2948 }
2949 else
2950 {
2951 ret = -EINVAL;
2952 }
2953
2954 return ret;
2955}
2956
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302957int hdd_drv_cmd_validate(tANI_U8 *command, int len)
2958{
2959 if (command[len] != ' ')
2960 return -EINVAL;
2961
2962 return 0;
2963}
2964
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05302965#ifdef WLAN_AP_STA_CONCURRENCY
2966
2967/**
2968 * hdd_conc_get_dwell_time() - Get concurrency dwell time parameters
2969 * @pCfg: Pointer to HDD context
2970 * @command: ASCII text command that is received
2971 * @extra: Pointer to copy data sent to user
2972 * @n: size of 'extra' buffer
2973 * @len: length copied to 'extra' buffer
2974 *
2975 * Driver commands:
2976 * wpa_cli DRIVER CONCGETDWELLTIME ACTIVE MAX
2977 * wpa_cli DRIVER CONCGETDWELLTIME ACTIVE MIN
2978 * wpa_cli DRIVER CONCGETDWELLTIME PASSIVE MAX
2979 * wpa_cli DRIVER CONCGETDWELLTIME PASSIVE MIN
2980 *
2981 * Return: 0 for success non-zero for failure
2982 */
2983
2984static int hdd_conc_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command,
2985 char *extra, tANI_U8 n, tANI_U8 *len)
2986{
2987 int ret = 0;
2988
2989 if (!pCfg || !command || !extra || !len)
2990 {
2991 hddLog(LOGE, FL("Argument passsed for CONCGETDWELLTIME is incorrect"));
2992 ret = -EINVAL;
2993 return ret;
2994 }
2995
2996 if (strncmp(command, "CONCGETDWELLTIME ACTIVE MAX", 27) == 0)
2997 {
2998 *len = scnprintf(extra, n, "CONCGETDWELLTIME ACTIVE MAX %u\n",
2999 (int)pCfg->nActiveMaxChnTimeConc);
3000 return ret;
3001 }
3002 else if (strncmp(command, "CONCGETDWELLTIME ACTIVE MIN", 27) == 0)
3003 {
3004 *len = scnprintf(extra, n, "CONCGETDWELLTIME ACTIVE MIN %u\n",
3005 (int)pCfg->nActiveMinChnTimeConc);
3006 return ret;
3007 }
3008 else if (strncmp(command, "CONCGETDWELLTIME PASSIVE MAX", 28) == 0)
3009 {
3010 *len = scnprintf(extra, n, "CONCGETDWELLTIME PASSIVE MAX %u\n",
3011 (int)pCfg->nPassiveMaxChnTimeConc);
3012 return ret;
3013 }
3014 else if (strncmp(command, "CONCGETDWELLTIME PASSIVE MIN", 28) == 0)
3015 {
3016 *len = scnprintf(extra, n, "CONCGETDWELLTIME PASSIVE MIN %u\n",
3017 (int)pCfg->nPassiveMinChnTimeConc);
3018 return ret;
3019 }
3020 else
3021 {
3022 ret = -EINVAL;
3023 }
3024
3025 return ret;
3026}
3027
3028/**
3029 * hdd_conc_set_dwell_time() - Set concurrency dwell time parameters
3030 * @pAdapter: Adapter upon which the command was received
3031 * @command: ASCII text command that is received
3032 *
3033 * Driver commands:
3034 * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MAX <value>
3035 * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MIN <value>
3036 * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MAX <value
3037 * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MIN <value>
3038 *
3039 * Return: 0 for success non-zero for failure
3040 */
3041
3042static int hdd_conc_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3043{
3044 tHalHandle hHal;
3045 hdd_config_t *pCfg;
3046 tANI_U8 *value = command;
3047 int val = 0, ret = 0, temp = 0;
3048 tSmeConfigParams smeConfig;
3049
3050 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3051 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
3052 {
3053 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME is incorrect"));
3054 ret = -EINVAL;
3055 return ret;
3056 }
3057
3058 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3059 sme_GetConfigParam(hHal, &smeConfig);
3060
3061 if (strncmp(command, "CONCSETDWELLTIME ACTIVE MAX", 27) == 0 )
3062 {
3063 if (hdd_drv_cmd_validate(command, 27)) {
3064 hddLog(LOGE, FL("Invalid driver command"));
3065 return -EINVAL;
3066 }
3067
3068 value = value + 28;
3069 temp = kstrtou32(value, 10, &val);
3070 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MIN ||
3071 val > CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MAX)
3072 {
3073 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME ACTIVE MAX is incorrect"));
3074 ret = -EFAULT;
3075 return ret;
3076 }
3077 pCfg->nActiveMaxChnTimeConc = val;
3078 smeConfig.csrConfig.nActiveMaxChnTimeConc = val;
3079 sme_UpdateConfig(hHal, &smeConfig);
3080 }
3081 else if (strncmp(command, "CONCSETDWELLTIME ACTIVE MIN", 27) == 0)
3082 {
3083 if (hdd_drv_cmd_validate(command, 27)) {
3084 hddLog(LOGE, FL("Invalid driver command"));
3085 return -EINVAL;
3086 }
3087
3088 value = value + 28;
3089 temp = kstrtou32(value, 10, &val);
3090 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MIN ||
3091 val > CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MAX)
3092 {
3093 hddLog(LOGE, FL("Argument passsed for CONCSETDWELLTIME ACTIVE MIN is incorrect"));
3094 ret = -EFAULT;
3095 return ret;
3096 }
3097 pCfg->nActiveMinChnTimeConc = val;
3098 smeConfig.csrConfig.nActiveMinChnTimeConc = val;
3099 sme_UpdateConfig(hHal, &smeConfig);
3100 }
3101 else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MAX", 28) == 0)
3102 {
3103 if (hdd_drv_cmd_validate(command, 28)) {
3104 hddLog(LOGE, FL("Invalid driver command"));
3105 return -EINVAL;
3106 }
3107
3108 value = value + 29;
3109 temp = kstrtou32(value, 10, &val);
3110 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MIN ||
3111 val > CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MAX)
3112 {
3113 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME PASSIVE MAX is incorrect"));
3114 ret = -EFAULT;
3115 return ret;
3116 }
3117 pCfg->nPassiveMaxChnTimeConc = val;
3118 smeConfig.csrConfig.nPassiveMaxChnTimeConc = val;
3119 sme_UpdateConfig(hHal, &smeConfig);
3120 }
3121 else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MIN", 28) == 0)
3122 {
3123 if (hdd_drv_cmd_validate(command, 28)) {
3124 hddLog(LOGE, FL("Invalid driver command"));
3125 return -EINVAL;
3126 }
3127
3128 value = value + 29;
3129 temp = kstrtou32(value, 10, &val);
3130 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MIN ||
3131 val > CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MAX )
3132 {
3133 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME PASSIVE MIN is incorrect"));
3134 ret = -EFAULT;
3135 return ret;
3136 }
3137 pCfg->nPassiveMinChnTimeConc = val;
3138 smeConfig.csrConfig.nPassiveMinChnTimeConc = val;
3139 sme_UpdateConfig(hHal, &smeConfig);
3140 }
3141 else
3142 {
3143 ret = -EINVAL;
3144 }
3145
3146 return ret;
3147}
3148
3149#endif
3150
3151/**
3152 * hdd_btc_set_dwell_time() - Set BTC dwell time parameters
3153 * @pAdapter: Adapter upon which the command was received
3154 * @command: ASCII text command that is received
3155 *
3156 * Driver commands:
3157 * wpa_cli DRIVER BTCSETDWELLTIME ESCO MAX <value>
3158 * wpa_cli DRIVER BTCSETDWELLTIME ESCO MIN <value>
3159 * wpa_cli DRIVER BTCSETDWELLTIME SCO MAX <value>
3160 * wpa_cli DRIVER BTCSETDWELLTIME SCO MIN <value>
3161 *
3162 * Return: 0 for success non-zero for failure
3163 */
3164
3165static int hdd_btc_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3166{
3167 tHalHandle hHal;
3168 hdd_config_t *pCfg;
3169 tANI_U8 *value = command;
3170 int val = 0, ret = 0, temp = 0;
3171 tSmeConfigParams smeConfig;
3172
3173 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3174 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
3175 {
3176 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME is incorrect"));
3177 ret = -EINVAL;
3178 return ret;
3179 }
3180
3181 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3182 sme_GetConfigParam(hHal, &smeConfig);
3183
3184 if (strncmp(command, "BTCSETDWELLTIME ESCO MAX", 24) == 0)
3185 {
3186 if (hdd_drv_cmd_validate(command, 24)) {
3187 hddLog(LOGE, FL("Invalid driver command"));
3188 return -EINVAL;
3189 }
3190
3191 value = value + 25;
3192 temp = kstrtou32(value, 10, &val);
3193 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MIN ||
3194 val > CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MAX)
3195 {
3196 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME ESCO MAX is incorrect"));
3197 ret = -EFAULT;
3198 return ret;
3199 }
3200 pCfg->max_chntime_btc_esco = val;
3201 smeConfig.csrConfig.max_chntime_btc_esco = val;
3202 sme_UpdateConfig(hHal, &smeConfig);
3203 }
3204 else if (strncmp(command, "BTCSETDWELLTIME ESCO MIN", 24) == 0)
3205 {
3206 if (hdd_drv_cmd_validate(command, 24)) {
3207 hddLog(LOGE, FL("Invalid driver command"));
3208 return -EINVAL;
3209 }
3210
3211 value = value + 25;
3212 temp = kstrtou32(value, 10, &val);
3213 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MIN ||
3214 val > CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MAX)
3215 {
3216 hddLog(LOGE, FL("Argument passsed for BTCSETDWELLTIME ESCO MIN is incorrect"));
3217 ret = -EFAULT;
3218 return ret;
3219 }
3220 pCfg->min_chntime_btc_esco = val;
3221 smeConfig.csrConfig.min_chntime_btc_esco = val;
3222 sme_UpdateConfig(hHal, &smeConfig);
3223 }
3224 else if (strncmp(command, "BTCSETDWELLTIME SCO MAX", 23) == 0)
3225 {
3226 if (hdd_drv_cmd_validate(command, 23)) {
3227 hddLog(LOGE, FL("Invalid driver command"));
3228 return -EINVAL;
3229 }
3230
3231 value = value + 24;
3232 temp = kstrtou32(value, 10, &val);
3233 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MIN ||
3234 val > CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MAX)
3235 {
3236 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME SCO MAX is incorrect"));
3237 ret = -EFAULT;
3238 return ret;
3239 }
3240 pCfg->max_chntime_btc_sco = val;
3241 smeConfig.csrConfig.max_chntime_btc_sco = val;
3242 sme_UpdateConfig(hHal, &smeConfig);
3243 }
3244 else if (strncmp(command, "BTCSETDWELLTIME SCO MIN", 23) == 0)
3245 {
3246 if (hdd_drv_cmd_validate(command, 23)) {
3247 hddLog(LOGE, FL("Invalid driver command"));
3248 return -EINVAL;
3249 }
3250
3251 value = value + 24;
3252 temp = kstrtou32(value, 10, &val);
3253 if (temp != 0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MIN ||
3254 val > CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MAX)
3255 {
3256 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME SCO MIN is incorrect"));
3257 ret = -EFAULT;
3258 return ret;
3259 }
3260 pCfg->min_chntime_btc_sco = val;
3261 smeConfig.csrConfig.min_chntime_btc_sco = val;
3262 sme_UpdateConfig(hHal, &smeConfig);
3263 }
3264 else
3265 {
3266 ret = -EINVAL;
3267 }
3268
3269 return ret;
3270}
3271
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303272static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3273{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303274 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303275 hdd_config_t *pCfg;
3276 tANI_U8 *value = command;
3277 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303278 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303279
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303280 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3281 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303282 {
3283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3284 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3285 ret = -EINVAL;
3286 return ret;
3287 }
3288
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303289 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3290 sme_GetConfigParam(hHal, &smeConfig);
3291
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303292 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
3293 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303294 if (hdd_drv_cmd_validate(command, 23))
3295 return -EINVAL;
3296
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303297 value = value + 24;
3298 temp = kstrtou32(value, 10, &val);
3299 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3300 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3301 {
3302 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3303 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
3304 ret = -EFAULT;
3305 return ret;
3306 }
3307 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303308 smeConfig.csrConfig.nActiveMaxChnTime = val;
3309 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303310 }
3311 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
3312 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303313 if (hdd_drv_cmd_validate(command, 23))
3314 return -EINVAL;
3315
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303316 value = value + 24;
3317 temp = kstrtou32(value, 10, &val);
3318 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
3319 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
3320 {
3321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3322 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
3323 ret = -EFAULT;
3324 return ret;
3325 }
3326 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303327 smeConfig.csrConfig.nActiveMinChnTime = val;
3328 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303329 }
3330 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
3331 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303332 if (hdd_drv_cmd_validate(command, 24))
3333 return -EINVAL;
3334
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303335 value = value + 25;
3336 temp = kstrtou32(value, 10, &val);
3337 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
3338 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
3339 {
3340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3341 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
3342 ret = -EFAULT;
3343 return ret;
3344 }
3345 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303346 smeConfig.csrConfig.nPassiveMaxChnTime = val;
3347 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303348 }
3349 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
3350 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303351 if (hdd_drv_cmd_validate(command, 24))
3352 return -EINVAL;
3353
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303354 value = value + 25;
3355 temp = kstrtou32(value, 10, &val);
3356 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
3357 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
3358 {
3359 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3360 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
3361 ret = -EFAULT;
3362 return ret;
3363 }
3364 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303365 smeConfig.csrConfig.nPassiveMinChnTime = val;
3366 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303367 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05303368 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3369 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303370 if (hdd_drv_cmd_validate(command, 12))
3371 return -EINVAL;
3372
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05303373 value = value + 13;
3374 temp = kstrtou32(value, 10, &val);
3375 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3376 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3377 {
3378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3379 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3380 ret = -EFAULT;
3381 return ret;
3382 }
3383 pCfg->nActiveMaxChnTime = val;
3384 smeConfig.csrConfig.nActiveMaxChnTime = val;
3385 sme_UpdateConfig(hHal, &smeConfig);
3386 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303387 else
3388 {
3389 ret = -EINVAL;
3390 }
3391
3392 return ret;
3393}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303394static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
3395 tANI_U8 cmd_len)
3396{
3397 tANI_U8 *value;
3398 tANI_U8 fcc_constraint;
3399
3400 eHalStatus status;
3401 int ret = 0;
3402 value = cmd + cmd_len + 1;
3403
3404 ret = kstrtou8(value, 10, &fcc_constraint);
3405 if ((ret < 0) || (fcc_constraint > 1)) {
3406 /*
3407 * If the input value is greater than max value of datatype,
3408 * then also it is a failure
3409 */
3410 hddLog(VOS_TRACE_LEVEL_ERROR,
3411 "%s: value out of range", __func__);
3412 return -EINVAL;
3413 }
3414
Agrawal Ashish842eea82016-02-04 17:56:16 +05303415 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint,
3416 pHddCtx->scan_info.mScanPending);
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303417 if (status != eHAL_STATUS_SUCCESS)
3418 ret = -EPERM;
3419
3420 return ret;
3421}
3422
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05303423/**---------------------------------------------------------------------------
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303424
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05303425 \brief hdd_enable_disable_ca_event() - When Host sends IOCTL (enabled),
3426 FW will send *ONE* CA ind to Host(even though it is duplicate).
3427 When Host send IOCTL (disable), FW doesn't perform any action.
3428 Whenever any change in CA *and* WLAN is in SAP/P2P-GO mode, FW
3429 sends CA ind to host. (regard less of IOCTL status)
3430 \param - pHddCtx - HDD context
3431 \param - command - command received from framework
3432 \param - cmd_len - len of the command
3433
3434 \return - 0 on success, appropriate error values on failure.
3435
3436 --------------------------------------------------------------------------*/
3437int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, tANI_U8* command, tANI_U8 cmd_len)
3438{
3439 tANI_U8 set_value;
3440 int ret = 0;
3441 eHalStatus status;
3442
3443 ret = wlan_hdd_validate_context(pHddCtx);
3444 if (0 != ret)
3445 {
3446 ret = -EINVAL;
3447 goto exit;
3448 }
3449
3450 if (pHddCtx->cfg_ini->gOptimizeCAevent == 0)
3451 {
3452 hddLog(VOS_TRACE_LEVEL_ERROR, "Enable gOptimizeCAevent"
3453 " ini param to control channel avooidance indication");
3454 ret = 0;
3455 goto exit;
3456 }
3457
3458 set_value = command[cmd_len + 1] - '0';
3459 status = sme_enableDisableChanAvoidIndEvent(pHddCtx->hHal, set_value);
3460 if (status != eHAL_STATUS_SUCCESS)
3461 {
3462 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to send"
3463 " enableDisableChanAoidance command to SME\n", __func__);
3464 ret = -EINVAL;
3465 }
3466
3467exit:
3468 return ret;
3469}
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303470
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303471/**
3472 * wlan_hdd_fastreassoc_handoff_request() - Post Handoff request to SME
3473 * @pHddCtx: Pointer to the HDD context
3474 * @channel: channel to reassociate
3475 * @targetApBssid: Target AP/BSSID to reassociate
3476 *
3477 * Return: None
3478 */
3479#if defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) && !defined(QCA_WIFI_ISOC)
3480static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3481 uint8_t channel, tSirMacAddr targetApBssid)
3482{
3483 tCsrHandoffRequest handoffInfo;
3484 handoffInfo.channel = channel;
3485 handoffInfo.src = FASTREASSOC;
3486 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3487 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3488}
3489#else
3490static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3491 uint8_t channel, tSirMacAddr targetApBssid)
3492{
3493}
3494#endif
3495
3496/**
3497 * csr_fastroam_neighbor_ap_event() - Function to trigger scan/roam
3498 * @pAdapter: Pointer to HDD adapter
3499 * @channel: Channel to scan/roam
3500 * @targetApBssid: BSSID to roam
3501 *
3502 * Return: None
3503 */
3504#ifdef QCA_WIFI_ISOC
3505static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3506 uint8_t channel, tSirMacAddr targetApBssid)
3507{
3508 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3509 &targetApBssid[0], eSME_ROAM_TRIGGER_SCAN, channel);
3510}
3511#else
3512static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3513 uint8_t channel, tSirMacAddr targetApBssid)
3514{
3515}
3516#endif
3517
3518/**
3519 * wlan_hdd_handle_fastreassoc() - Handle fastreassoc command
3520 * @pAdapter: pointer to hdd adapter
3521 * @command: pointer to the command received
3522 *
3523 * Return: VOS_STATUS enum
3524 */
3525static VOS_STATUS wlan_hdd_handle_fastreassoc(hdd_adapter_t *pAdapter,
3526 uint8_t *command)
3527{
3528 tANI_U8 *value = command;
3529 tANI_U8 channel = 0;
3530 tSirMacAddr targetApBssid;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303531 hdd_station_ctx_t *pHddStaCtx = NULL;
3532 hdd_context_t *pHddCtx = NULL;
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303533 int ret;
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303534 tCsrRoamModifyProfileFields mod_profile_fields;
3535 uint32_t roam_id = 0;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303536 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3537 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3538
3539 /* if not associated, no need to proceed with reassoc */
3540 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
3541 hddLog(LOG1, FL("Not associated!"));
3542 return eHAL_STATUS_FAILURE;
3543 }
3544
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303545 ret = hdd_parse_reassoc_command_v1_data(value, targetApBssid, &channel);
3546 if (ret) {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303547 hddLog(LOGE, FL("Failed to parse reassoc command data"));
3548 return eHAL_STATUS_FAILURE;
3549 }
3550
3551 /* if the target bssid is same as currently associated AP,
3552 then no need to proceed with reassoc */
3553 if (vos_mem_compare(targetApBssid,
3554 pHddStaCtx->conn_info.bssId,
3555 sizeof(tSirMacAddr))) {
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303556 sme_GetModifyProfileFields(pHddCtx->hHal, pAdapter->sessionId,
3557 &mod_profile_fields);
3558 sme_RoamReassoc(pHddCtx->hHal, pAdapter->sessionId, NULL,
3559 mod_profile_fields, &roam_id, 1);
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303560 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303561 return eHAL_STATUS_SUCCESS;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303562 }
3563
3564 /* Check channel number is a valid channel number */
3565 if (VOS_STATUS_SUCCESS !=
3566 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
3567 hddLog(LOGE, FL("Invalid Channel [%d]"), channel);
3568 return eHAL_STATUS_FAILURE;
3569 }
3570
3571 /* Proceed with reassoc */
3572 wlan_hdd_fastreassoc_handoff_request(pHddCtx, channel, targetApBssid);
3573
3574 /* Proceed with scan/roam */
3575 csr_fastroam_neighbor_ap_event(pAdapter, channel, targetApBssid);
3576
3577 return eHAL_STATUS_SUCCESS;
3578}
3579
3580/**
3581 * hdd_assign_reassoc_handoff - Set handoff source as REASSOC
3582 * @handoffInfo: Pointer to the csr Handoff Request.
3583 *
3584 * Return: None
3585 */
3586#ifndef QCA_WIFI_ISOC
3587static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3588{
3589 handoffInfo->src = REASSOC;
3590}
3591#else
3592static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3593{
3594}
3595#endif
3596
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303597/**
3598 * wlan_hdd_free_cache_channels() - Free the cache channels list
3599 * @hdd_ctx: Pointer to HDD context
3600 *
3601 * Return: None
3602 */
3603
3604static void wlan_hdd_free_cache_channels(hdd_context_t *hdd_ctx)
3605{
Ashish Kumar Dhanotiya19803832018-05-24 19:05:48 +05303606 if(!hdd_ctx || !hdd_ctx->original_channels)
3607 return;
3608
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303609 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303610 hdd_ctx->original_channels->num_channels = 0;
3611 vos_mem_free(hdd_ctx->original_channels->channel_info);
3612 hdd_ctx->original_channels->channel_info = NULL;
3613 vos_mem_free(hdd_ctx->original_channels);
3614 hdd_ctx->original_channels = NULL;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303615 mutex_unlock(&hdd_ctx->cache_channel_lock);
3616}
3617
3618/**
3619 * hdd_alloc_chan_cache() - Allocate the memory to cache the channel
3620 * info for the channels received in command SET_DISABLE_CHANNEL_LIST
3621 * @hdd_ctx: Pointer to HDD context
3622 * @num_chan: Number of channels for which memory needs to
3623 * be allocated
3624 *
3625 * Return: 0 on success and error code on failure
3626 */
3627
3628int hdd_alloc_chan_cache(hdd_context_t *hdd_ctx, int num_chan)
3629{
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303630 hdd_ctx->original_channels =
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303631 vos_mem_malloc(sizeof(struct hdd_cache_channels));
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303632 if (!hdd_ctx->original_channels) {
3633 hddLog(VOS_TRACE_LEVEL_ERROR,
3634 "In %s, VOS_MALLOC_ERR", __func__);
3635 return -EINVAL;
3636 }
3637 hdd_ctx->original_channels->num_channels = num_chan;
3638 hdd_ctx->original_channels->channel_info =
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303639 vos_mem_malloc(num_chan *
3640 sizeof(struct hdd_cache_channel_info));
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303641 if (!hdd_ctx->original_channels->channel_info) {
3642 hddLog(VOS_TRACE_LEVEL_ERROR,
3643 "In %s, VOS_MALLOC_ERR", __func__);
3644 hdd_ctx->original_channels->num_channels = 0;
3645 vos_mem_free(hdd_ctx->original_channels);
3646 hdd_ctx->original_channels = NULL;
3647 return -ENOMEM;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303648 }
3649 return 0;
3650
3651}
3652
3653
3654int hdd_parse_disable_chan_cmd(hdd_adapter_t *adapter, tANI_U8 *ptr)
3655{
3656 v_PVOID_t pvosGCtx = vos_get_global_context(VOS_MODULE_ID_HDD, NULL);
3657 hdd_context_t *hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, pvosGCtx);
3658 tANI_U8 *param;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303659 int j, tempInt, ret = 0, i, num_channels;
3660 int parsed_channels[MAX_CHANNEL];
3661 bool is_command_repeated = false;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303662
3663 if (NULL == pvosGCtx) {
3664 hddLog(VOS_TRACE_LEVEL_FATAL,
3665 "VOS Global Context is NULL");
3666 return -EINVAL;
3667 }
3668
3669 if (NULL == hdd_ctx) {
3670 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
3671 return -EINVAL;
3672 }
3673
3674 param = strchr(ptr, ' ');
3675 /*no argument after the command*/
3676 if (NULL == param)
3677 return -EINVAL;
3678
3679 /*no space after the command*/
3680 else if (SPACE_ASCII_VALUE != *param)
3681 return -EINVAL;
3682
3683 param++;
3684
3685 /*removing empty spaces*/
3686 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3687 param++;
3688
3689 /*no argument followed by spaces*/
3690 if ('\0' == *param)
3691 return -EINVAL;
3692
3693 /*getting the first argument ie the number of channels*/
3694 if (sscanf(param, "%d ", &tempInt) != 1) {
3695 hddLog(VOS_TRACE_LEVEL_ERROR,
3696 "%s: Cannot get number of channels from input",
3697 __func__);
3698 return -EINVAL;
3699 }
3700
3701 if (tempInt < 0 || tempInt > MAX_CHANNEL) {
3702 hddLog(VOS_TRACE_LEVEL_ERROR,
3703 "%s: Invalid Number of channel received", __func__);
3704 return -EINVAL;
3705 }
3706
3707 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3708 "%s: Number of channel to disable are: %d",
3709 __func__, tempInt);
3710
3711 if (!tempInt) {
3712 if (!wlan_hdd_restore_channels(hdd_ctx)) {
3713 /*
3714 * Free the cache channels only when the command is
3715 * received with num channels as 0
3716 */
3717 wlan_hdd_free_cache_channels(hdd_ctx);
3718 }
3719 return 0;
3720 }
3721
3722 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303723 if (!hdd_ctx->original_channels) {
3724 if (hdd_alloc_chan_cache(hdd_ctx, tempInt)) {
3725 ret = -ENOMEM;
3726 goto mem_alloc_failed;
3727 }
3728 } else if (hdd_ctx->original_channels->num_channels != tempInt) {
3729 hddLog(VOS_TRACE_LEVEL_ERROR,
3730 "%s, Invalid No of channel provided in the list",
3731 __func__);
3732 ret = -EINVAL;
3733 is_command_repeated = true;
3734 goto parse_failed;
3735 } else {
3736 is_command_repeated = true;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303737 }
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303738
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303739 num_channels = tempInt;
3740
3741 for (j = 0; j < num_channels; j++) {
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303742 /*
3743 * param pointing to the beginning of first space
3744 * after number of channels
3745 */
3746 param = strpbrk(param, " ");
3747 /*no channel list after the number of channels argument*/
3748 if (NULL == param) {
3749 hddLog(VOS_TRACE_LEVEL_ERROR,
3750 "%s, Invalid No of channel provided in the list",
3751 __func__);
3752 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303753 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303754 }
3755
3756 param++;
3757
3758 /*removing empty space*/
3759 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3760 param++;
3761
3762 if ('\0' == *param) {
3763 hddLog(VOS_TRACE_LEVEL_ERROR,
3764 "%s, No channel is provided in the list",
3765 __func__);
3766 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303767 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303768
3769 }
3770
3771 if (sscanf(param, "%d ", &tempInt) != 1) {
3772 hddLog(VOS_TRACE_LEVEL_ERROR,
3773 "%s: Cannot read channel number",
3774 __func__);
3775 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303776 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303777
3778 }
3779
3780 if (!IS_CHANNEL_VALID(tempInt)) {
3781 hddLog(VOS_TRACE_LEVEL_ERROR,
3782 "%s: Invalid channel number received",
3783 __func__);
3784 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303785 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303786
3787 }
3788
3789 hddLog(VOS_TRACE_LEVEL_INFO, "%s: channel[%d] = %d", __func__,
3790 j, tempInt);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303791
3792 parsed_channels[j] = tempInt;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303793 }
3794
3795 /*extra arguments check*/
3796 param = strchr(param, ' ');
3797 if (NULL != param) {
3798 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3799 param++;
3800
3801 if ('\0' != *param) {
3802 hddLog(VOS_TRACE_LEVEL_ERROR,
3803 "%s: Invalid argument received", __func__);
3804 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303805 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303806 }
3807 }
3808
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303809 /*
3810 * If command is received first time, cache the channels to
3811 * be disabled else compare the channels received in the
3812 * command with the cached channels, if channel list matches
3813 * return success otherewise return failure.
3814 */
3815 if (!is_command_repeated)
3816 for (j = 0; j < num_channels; j++)
3817 hdd_ctx->original_channels->
3818 channel_info[j].channel_num =
3819 parsed_channels[j];
3820 else {
3821 for (i = 0; i < num_channels; i++) {
3822 for (j = 0; j < num_channels; j++)
3823 if (hdd_ctx->original_channels->
3824 channel_info[i].channel_num ==
3825 parsed_channels[j])
3826 break;
3827 if (j == num_channels) {
3828 ret = -EINVAL;
3829 goto parse_failed;
3830 }
3831 }
3832 ret = 0;
3833 }
3834
3835mem_alloc_failed:
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303836 mutex_unlock(&hdd_ctx->cache_channel_lock);
3837 EXIT();
3838
3839 return ret;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303840
3841parse_failed:
3842 mutex_unlock(&hdd_ctx->cache_channel_lock);
3843 if (!is_command_repeated)
3844 wlan_hdd_free_cache_channels(hdd_ctx);
3845 EXIT();
3846 return ret;
3847
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303848}
3849
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303850int hdd_get_disable_ch_list(hdd_context_t *hdd_ctx, tANI_U8 *buf,
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303851 uint32_t buf_len)
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303852{
3853 struct hdd_cache_channel_info *ch_list;
3854 unsigned char i, num_ch;
3855 int len = 0;
3856
3857 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303858 if (hdd_ctx->original_channels &&
3859 hdd_ctx->original_channels->num_channels &&
3860 hdd_ctx->original_channels->channel_info) {
3861 num_ch = hdd_ctx->original_channels->num_channels;
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303862
3863 len = scnprintf(buf, buf_len, "%s %hhu",
3864 "GET_DISABLE_CHANNEL_LIST", num_ch);
3865
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303866 ch_list = hdd_ctx->original_channels->channel_info;
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303867
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303868 for (i = 0; (i < num_ch) && (len < buf_len-1); i++) {
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303869 len += scnprintf(buf + len, buf_len - len,
3870 " %d", ch_list[i].channel_num);
3871 }
3872 }
3873 mutex_unlock(&hdd_ctx->cache_channel_lock);
3874
3875 return len;
3876}
3877
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003878static int hdd_driver_command(hdd_adapter_t *pAdapter,
3879 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07003880{
Jeff Johnson295189b2012-06-20 16:38:30 -07003881 hdd_priv_data_t priv_data;
3882 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303883 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3884 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003885 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303886 int status;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303887#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3888 struct cfg80211_mgmt_tx_params params;
3889#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303890
3891 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003892 /*
3893 * Note that valid pointers are provided by caller
3894 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003895
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003896 /* copy to local struct to avoid numerous changes to legacy code */
3897 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07003898
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003899 if (priv_data.total_len <= 0 ||
3900 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07003901 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003902 hddLog(VOS_TRACE_LEVEL_WARN,
3903 "%s:invalid priv_data.total_len(%d)!!!", __func__,
3904 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003905 ret = -EINVAL;
3906 goto exit;
3907 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05303908 status = wlan_hdd_validate_context(pHddCtx);
3909 if (0 != status)
3910 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303911 ret = -EINVAL;
3912 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303913 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003914 /* Allocate +1 for '\0' */
3915 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07003916 if (!command)
3917 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003918 hddLog(VOS_TRACE_LEVEL_ERROR,
3919 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003920 ret = -ENOMEM;
3921 goto exit;
3922 }
3923
3924 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
3925 {
3926 ret = -EFAULT;
3927 goto exit;
3928 }
3929
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003930 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003931 command[priv_data.total_len] = '\0';
3932
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003933 /* at one time the following block of code was conditional. braces
3934 * have been retained to avoid re-indenting the legacy code
3935 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003936 {
3937 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
3938
3939 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003940 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07003941
3942 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
3943 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303944 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3945 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
3946 pAdapter->sessionId, (unsigned)
3947 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
3948 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
3949 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
3950 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07003951 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
3952 sizeof(tSirMacAddr)))
3953 {
3954 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003955 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003956 ret = -EFAULT;
3957 }
3958 }
Amar Singhal0974e402013-02-12 14:27:46 -08003959 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07003960 {
Amar Singhal0974e402013-02-12 14:27:46 -08003961 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003962
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303963 ret = hdd_drv_cmd_validate(command, 7);
3964 if (ret)
3965 goto exit;
3966
Jeff Johnson295189b2012-06-20 16:38:30 -07003967 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003968
3969 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07003970 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07003971 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08003972 "%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 +05303973 if(VOS_FTM_MODE != hdd_get_conparam())
3974 {
3975 /* Change band request received */
3976 ret = hdd_setBand_helper(pAdapter->dev, ptr);
3977 if(ret < 0)
3978 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3979 "%s: failed to set band ret=%d", __func__, ret);
3980 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003981 }
Kiet Lamf040f472013-11-20 21:15:23 +05303982 else if(strncmp(command, "SETWMMPS", 8) == 0)
3983 {
3984 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303985
3986 ret = hdd_drv_cmd_validate(command, 8);
3987 if (ret)
3988 goto exit;
3989
Kiet Lamf040f472013-11-20 21:15:23 +05303990 ret = hdd_wmmps_helper(pAdapter, ptr);
3991 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05303992
3993 else if(strncmp(command, "TDLSSCAN", 8) == 0)
3994 {
3995 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303996
3997 ret = hdd_drv_cmd_validate(command, 8);
3998 if (ret)
3999 goto exit;
4000
Agarwal Ashishef54a182014-12-16 15:07:31 +05304001 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
4002 }
4003
Jeff Johnson32d95a32012-09-10 13:15:23 -07004004 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
4005 {
4006 char *country_code;
4007
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304008 ret = hdd_drv_cmd_validate(command, 7);
4009 if (ret)
4010 goto exit;
4011
Jeff Johnson32d95a32012-09-10 13:15:23 -07004012 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07004013
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004014 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07004015 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07004016#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05304017 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07004018#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004019 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
4020 (void *)(tSmeChangeCountryCallback)
4021 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05304022 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004023 if (eHAL_STATUS_SUCCESS == ret)
4024 {
4025 ret = wait_for_completion_interruptible_timeout(
4026 &pAdapter->change_country_code,
4027 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
4028 if (0 >= ret)
4029 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004030 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304031 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004032 }
4033 }
4034 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07004035 {
4036 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004037 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004038 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07004039 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004040
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004041 }
4042 /*
4043 command should be a string having format
4044 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
4045 */
Amar Singhal0974e402013-02-12 14:27:46 -08004046 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004047 {
Amar Singhal0974e402013-02-12 14:27:46 -08004048 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004049
4050 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004051 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004052
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08004053 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07004054 }
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +05304055
4056 else if (strncmp(command, "VOWIFIMODE", 10) == 0)
4057 {
4058 tANI_U8 *ptr;
4059
4060 ret = hdd_drv_cmd_validate(command, 10);
4061 if (ret)
4062 goto exit;
4063
4064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4065 "Received Command for VOWIFI mode in %s", __func__);
4066
4067 ptr = (tANI_U8*)command + 11;
4068 hdd_set_vowifi_mode(pHddCtx, *ptr - '0');
4069 }
4070
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004071 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
4072 {
4073 int suspend = 0;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304074 tANI_U8 *ptr;
4075
4076 ret = hdd_drv_cmd_validate(command, 14);
4077 if (ret)
4078 goto exit;
4079
4080 ptr = (tANI_U8*)command + 15;
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004081
4082 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304083 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4084 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
4085 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004086 hdd_set_wlan_suspend_mode(suspend);
4087 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004088#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
4089 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
4090 {
4091 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004092 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004093 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
4094 eHalStatus status = eHAL_STATUS_SUCCESS;
4095
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304096 ret = hdd_drv_cmd_validate(command, 14);
4097 if (ret)
4098 goto exit;
4099
Srinivas Girigowdade697412013-02-14 16:31:48 -08004100 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
4101 value = value + 15;
4102
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004103 /* Convert the value from ascii to integer */
4104 ret = kstrtos8(value, 10, &rssi);
4105 if (ret < 0)
4106 {
4107 /* If the input value is greater than max value of datatype, then also
4108 kstrtou8 fails */
4109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4110 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07004111 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004112 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
4113 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
4114 ret = -EINVAL;
4115 goto exit;
4116 }
4117
Srinivas Girigowdade697412013-02-14 16:31:48 -08004118 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004119
Srinivas Girigowdade697412013-02-14 16:31:48 -08004120 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
4121 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
4122 {
4123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4124 "Neighbor lookup threshold value %d is out of range"
4125 " (Min: %d Max: %d)", lookUpThreshold,
4126 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
4127 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
4128 ret = -EINVAL;
4129 goto exit;
4130 }
4131
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304132 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4133 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
4134 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4136 "%s: Received Command to Set Roam trigger"
4137 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
4138
4139 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
4140 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
4141 if (eHAL_STATUS_SUCCESS != status)
4142 {
4143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4144 "%s: Failed to set roam trigger, try again", __func__);
4145 ret = -EPERM;
4146 goto exit;
4147 }
4148
4149 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05304150 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004151 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
4152 }
4153 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
4154 {
4155 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
4156 int rssi = (-1) * lookUpThreshold;
4157 char extra[32];
4158 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304159 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4160 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
4161 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004162 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05304163 len = VOS_MIN(priv_data.total_len, len + 1);
4164 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004165 {
4166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4167 "%s: failed to copy data to user buffer", __func__);
4168 ret = -EFAULT;
4169 goto exit;
4170 }
4171 }
4172 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
4173 {
4174 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004175 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004176 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004177
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304178 ret = hdd_drv_cmd_validate(command, 17);
4179 if (ret)
4180 goto exit;
4181
Srinivas Girigowdade697412013-02-14 16:31:48 -08004182 /* input refresh period is in terms of seconds */
4183 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
4184 value = value + 18;
4185 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004186 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004187 if (ret < 0)
4188 {
4189 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004190 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08004191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004192 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08004193 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07004194 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
4195 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004196 ret = -EINVAL;
4197 goto exit;
4198 }
4199
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004200 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
4201 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004202 {
4203 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004204 "Roam scan period value %d is out of range"
4205 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07004206 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
4207 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004208 ret = -EINVAL;
4209 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304210 }
4211 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4212 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
4213 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004214 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004215
4216 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4217 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004218 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004219
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004220 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
4221 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004222 }
4223 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
4224 {
4225 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
4226 char extra[32];
4227 tANI_U8 len = 0;
4228
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304229 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4230 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
4231 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004232 len = scnprintf(extra, sizeof(extra), "%s %d",
4233 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004234 /* Returned value is in units of seconds */
Ratnam Rachuria72ba112015-07-17 13:27:03 +05304235 len = VOS_MIN(priv_data.total_len, len + 1);
4236 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004237 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4238 "%s: failed to copy data to user buffer", __func__);
4239 ret = -EFAULT;
4240 goto exit;
4241 }
4242 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004243 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
4244 {
4245 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004246 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004247 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004248
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304249 ret = hdd_drv_cmd_validate(command, 24);
4250 if (ret)
4251 goto exit;
4252
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004253 /* input refresh period is in terms of seconds */
4254 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
4255 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004256
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004257 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004258 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004259 if (ret < 0)
4260 {
4261 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004262 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004263 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004264 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004265 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004266 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
4267 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
4268 ret = -EINVAL;
4269 goto exit;
4270 }
4271
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004272 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
4273 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
4274 {
4275 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4276 "Neighbor scan results refresh period value %d is out of range"
4277 " (Min: %d Max: %d)", roamScanRefreshPeriod,
4278 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
4279 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
4280 ret = -EINVAL;
4281 goto exit;
4282 }
4283 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
4284
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004285 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4286 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004287 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004288
4289 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
4290 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
4291 }
4292 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
4293 {
4294 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
4295 char extra[32];
4296 tANI_U8 len = 0;
4297
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004298 len = scnprintf(extra, sizeof(extra), "%s %d",
4299 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004300 /* Returned value is in units of seconds */
Ratnam Rachuri2c9d6702015-07-17 13:25:16 +05304301 len = VOS_MIN(priv_data.total_len, len + 1);
4302 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4304 "%s: failed to copy data to user buffer", __func__);
4305 ret = -EFAULT;
4306 goto exit;
4307 }
4308 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004309#ifdef FEATURE_WLAN_LFR
4310 /* SETROAMMODE */
4311 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
4312 {
4313 tANI_U8 *value = command;
4314 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
4315
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05304316 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
4317 hddLog(LOGE,
4318 FL("Roaming is always disabled in STA + MON concurrency"));
4319 ret = -EINVAL;
4320 goto exit;
4321 }
4322
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304323 ret = hdd_drv_cmd_validate(command, SIZE_OF_SETROAMMODE);
4324 if (ret)
4325 goto exit;
4326
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004327 /* Move pointer to ahead of SETROAMMODE<delimiter> */
4328 value = value + SIZE_OF_SETROAMMODE + 1;
4329
4330 /* Convert the value from ascii to integer */
4331 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
4332 if (ret < 0)
4333 {
4334 /* If the input value is greater than max value of datatype, then also
4335 kstrtou8 fails */
4336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4337 "%s: kstrtou8 failed range [%d - %d]", __func__,
4338 CFG_LFR_FEATURE_ENABLED_MIN,
4339 CFG_LFR_FEATURE_ENABLED_MAX);
4340 ret = -EINVAL;
4341 goto exit;
4342 }
4343 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
4344 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
4345 {
4346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4347 "Roam Mode value %d is out of range"
4348 " (Min: %d Max: %d)", roamMode,
4349 CFG_LFR_FEATURE_ENABLED_MIN,
4350 CFG_LFR_FEATURE_ENABLED_MAX);
4351 ret = -EINVAL;
4352 goto exit;
4353 }
4354
4355 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4356 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
4357 /*
4358 * Note that
4359 * SETROAMMODE 0 is to enable LFR while
4360 * SETROAMMODE 1 is to disable LFR, but
4361 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
4362 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
4363 */
4364 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
4365 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
4366 else
4367 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
4368
4369 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
4370 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
4371 }
4372 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304373 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004374 {
4375 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4376 char extra[32];
4377 tANI_U8 len = 0;
4378
4379 /*
4380 * roamMode value shall be inverted because the sementics is different.
4381 */
4382 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
4383 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
4384 else
4385 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
4386
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004387 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Ratnam Rachuri28693eb2015-07-17 13:23:42 +05304388 len = VOS_MIN(priv_data.total_len, len + 1);
4389 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004390 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4391 "%s: failed to copy data to user buffer", __func__);
4392 ret = -EFAULT;
4393 goto exit;
4394 }
4395 }
4396#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08004397#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004398#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004399 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
4400 {
4401 tANI_U8 *value = command;
4402 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
4403
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304404 ret = hdd_drv_cmd_validate(command, 12);
4405 if (ret)
4406 goto exit;
4407
Srinivas Girigowdade697412013-02-14 16:31:48 -08004408 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
4409 value = value + 13;
4410 /* Convert the value from ascii to integer */
4411 ret = kstrtou8(value, 10, &roamRssiDiff);
4412 if (ret < 0)
4413 {
4414 /* If the input value is greater than max value of datatype, then also
4415 kstrtou8 fails */
4416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4417 "%s: kstrtou8 failed range [%d - %d]", __func__,
4418 CFG_ROAM_RSSI_DIFF_MIN,
4419 CFG_ROAM_RSSI_DIFF_MAX);
4420 ret = -EINVAL;
4421 goto exit;
4422 }
4423
4424 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
4425 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
4426 {
4427 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4428 "Roam rssi diff value %d is out of range"
4429 " (Min: %d Max: %d)", roamRssiDiff,
4430 CFG_ROAM_RSSI_DIFF_MIN,
4431 CFG_ROAM_RSSI_DIFF_MAX);
4432 ret = -EINVAL;
4433 goto exit;
4434 }
4435
4436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4437 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
4438
4439 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
4440 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
4441 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304442 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004443 {
4444 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
4445 char extra[32];
4446 tANI_U8 len = 0;
4447
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304448 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4449 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
4450 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004451 len = scnprintf(extra, sizeof(extra), "%s %d",
4452 command, roamRssiDiff);
Ratnam Rachuri22a3b402015-07-17 13:21:49 +05304453 len = VOS_MIN(priv_data.total_len, len + 1);
4454 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4456 "%s: failed to copy data to user buffer", __func__);
4457 ret = -EFAULT;
4458 goto exit;
4459 }
4460 }
4461#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004462#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004463 else if (strncmp(command, "GETBAND", 7) == 0)
4464 {
4465 int band = -1;
4466 char extra[32];
4467 tANI_U8 len = 0;
4468 hdd_getBand_helper(pHddCtx, &band);
4469
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304470 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4471 TRACE_CODE_HDD_GETBAND_IOCTL,
4472 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004473 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Ratnam Rachuri52139592015-07-17 13:17:29 +05304474 len = VOS_MIN(priv_data.total_len, len + 1);
4475 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004476 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4477 "%s: failed to copy data to user buffer", __func__);
4478 ret = -EFAULT;
4479 goto exit;
4480 }
4481 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004482 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
4483 {
4484 tANI_U8 *value = command;
4485 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4486 tANI_U8 numChannels = 0;
4487 eHalStatus status = eHAL_STATUS_SUCCESS;
4488
4489 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4490 if (eHAL_STATUS_SUCCESS != status)
4491 {
4492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4493 "%s: Failed to parse channel list information", __func__);
4494 ret = -EINVAL;
4495 goto exit;
4496 }
4497
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304498 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4499 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
4500 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004501 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4502 {
4503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4504 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4505 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4506 ret = -EINVAL;
4507 goto exit;
4508 }
4509 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
4510 numChannels);
4511 if (eHAL_STATUS_SUCCESS != status)
4512 {
4513 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4514 "%s: Failed to update channel list information", __func__);
4515 ret = -EINVAL;
4516 goto exit;
4517 }
4518 }
4519 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
4520 {
4521 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4522 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07004523 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004524 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07004525 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004526
4527 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
4528 ChannelList, &numChannels ))
4529 {
4530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4531 "%s: failed to get roam scan channel list", __func__);
4532 ret = -EFAULT;
4533 goto exit;
4534 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304535 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4536 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
4537 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004538 /* output channel list is of the format
4539 [Number of roam scan channels][Channel1][Channel2]... */
4540 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004541 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Sushant Kaushika08ca192015-09-16 15:52:04 +05304542 for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004543 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004544 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
4545 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004546 }
4547
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05304548 len = VOS_MIN(priv_data.total_len, len + 1);
4549 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004550 {
4551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4552 "%s: failed to copy data to user buffer", __func__);
4553 ret = -EFAULT;
4554 goto exit;
4555 }
4556 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004557 else if (strncmp(command, "GETCCXMODE", 10) == 0)
4558 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004559 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004560 char extra[32];
4561 tANI_U8 len = 0;
4562
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004563 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004564 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004565 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004566 hdd_is_okc_mode_enabled(pHddCtx) &&
4567 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4568 {
4569 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004570 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004571 " hence this operation is not permitted!", __func__);
4572 ret = -EPERM;
4573 goto exit;
4574 }
4575
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004576 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004577 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05304578 len = VOS_MIN(priv_data.total_len, len + 1);
4579 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004580 {
4581 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4582 "%s: failed to copy data to user buffer", __func__);
4583 ret = -EFAULT;
4584 goto exit;
4585 }
4586 }
4587 else if (strncmp(command, "GETOKCMODE", 10) == 0)
4588 {
4589 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
4590 char extra[32];
4591 tANI_U8 len = 0;
4592
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004593 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004594 then this operation is not permitted (return FAILURE) */
4595 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004596 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004597 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4598 {
4599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004600 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004601 " hence this operation is not permitted!", __func__);
4602 ret = -EPERM;
4603 goto exit;
4604 }
4605
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004606 len = scnprintf(extra, sizeof(extra), "%s %d",
4607 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05304608 len = VOS_MIN(priv_data.total_len, len + 1);
4609 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004610 {
4611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4612 "%s: failed to copy data to user buffer", __func__);
4613 ret = -EFAULT;
4614 goto exit;
4615 }
4616 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004617 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004618 {
4619 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4620 char extra[32];
4621 tANI_U8 len = 0;
4622
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004623 len = scnprintf(extra, sizeof(extra), "%s %d",
4624 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05304625 len = VOS_MIN(priv_data.total_len, len + 1);
4626 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004627 {
4628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4629 "%s: failed to copy data to user buffer", __func__);
4630 ret = -EFAULT;
4631 goto exit;
4632 }
4633 }
4634 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
4635 {
4636 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4637 char extra[32];
4638 tANI_U8 len = 0;
4639
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004640 len = scnprintf(extra, sizeof(extra), "%s %d",
4641 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05304642 len = VOS_MIN(priv_data.total_len, len + 1);
4643 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004644 {
4645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4646 "%s: failed to copy data to user buffer", __func__);
4647 ret = -EFAULT;
4648 goto exit;
4649 }
4650 }
4651 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
4652 {
4653 tANI_U8 *value = command;
4654 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
4655
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304656 ret = hdd_drv_cmd_validate(command, 25);
4657 if (ret)
4658 goto exit;
4659
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004660 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
4661 value = value + 26;
4662 /* Convert the value from ascii to integer */
4663 ret = kstrtou8(value, 10, &minTime);
4664 if (ret < 0)
4665 {
4666 /* If the input value is greater than max value of datatype, then also
4667 kstrtou8 fails */
4668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4669 "%s: kstrtou8 failed range [%d - %d]", __func__,
4670 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
4671 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
4672 ret = -EINVAL;
4673 goto exit;
4674 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004675 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
4676 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
4677 {
4678 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4679 "scan min channel time value %d is out of range"
4680 " (Min: %d Max: %d)", minTime,
4681 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
4682 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
4683 ret = -EINVAL;
4684 goto exit;
4685 }
4686
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304687 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4688 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
4689 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4691 "%s: Received Command to change channel min time = %d", __func__, minTime);
4692
4693 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
4694 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
4695 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004696 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
4697 {
4698 tANI_U8 *value = command;
4699 tANI_U8 channel = 0;
4700 tANI_U8 dwellTime = 0;
4701 tANI_U8 bufLen = 0;
4702 tANI_U8 *buf = NULL;
4703 tSirMacAddr targetApBssid;
4704 eHalStatus status = eHAL_STATUS_SUCCESS;
4705 struct ieee80211_channel chan;
4706 tANI_U8 finalLen = 0;
4707 tANI_U8 *finalBuf = NULL;
4708 tANI_U8 temp = 0;
4709 u64 cookie;
4710 hdd_station_ctx_t *pHddStaCtx = NULL;
4711 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4712
4713 /* if not associated, no need to send action frame */
4714 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4715 {
4716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
4717 ret = -EINVAL;
4718 goto exit;
4719 }
4720
4721 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
4722 &dwellTime, &buf, &bufLen);
4723 if (eHAL_STATUS_SUCCESS != status)
4724 {
4725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4726 "%s: Failed to parse send action frame data", __func__);
4727 ret = -EINVAL;
4728 goto exit;
4729 }
4730
4731 /* if the target bssid is different from currently associated AP,
4732 then no need to send action frame */
4733 if (VOS_TRUE != vos_mem_compare(targetApBssid,
4734 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
4735 {
4736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
4737 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004738 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004739 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004740 goto exit;
4741 }
4742
4743 /* if the channel number is different from operating channel then
4744 no need to send action frame */
4745 if (channel != pHddStaCtx->conn_info.operationChannel)
4746 {
4747 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4748 "%s: channel(%d) is different from operating channel(%d)",
4749 __func__, channel, pHddStaCtx->conn_info.operationChannel);
4750 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004751 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004752 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004753 goto exit;
4754 }
4755 chan.center_freq = sme_ChnToFreq(channel);
4756
4757 finalLen = bufLen + 24;
4758 finalBuf = vos_mem_malloc(finalLen);
4759 if (NULL == finalBuf)
4760 {
4761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
4762 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07004763 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004764 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004765 goto exit;
4766 }
4767 vos_mem_zero(finalBuf, finalLen);
4768
4769 /* Fill subtype */
4770 temp = SIR_MAC_MGMT_ACTION << 4;
4771 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
4772
4773 /* Fill type */
4774 temp = SIR_MAC_MGMT_FRAME;
4775 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
4776
4777 /* Fill destination address (bssid of the AP) */
4778 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
4779
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004780 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004781 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
4782
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004783 /* Fill BSSID (AP mac address) */
4784 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004785
4786 /* Fill received buffer from 24th address */
4787 vos_mem_copy(finalBuf + 24, buf, bufLen);
4788
Jeff Johnson11c33152013-04-16 17:52:40 -07004789 /* done with the parsed buffer */
4790 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004791 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004792
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304793#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
4794 params.chan = &chan;
4795 params.offchan = 0;
4796 params.wait = dwellTime;
4797 params.buf = finalBuf;
4798 params.len = finalLen;
4799 params.no_cck = 1;
4800 params.dont_wait_for_ack = 1;
4801 ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
4802#else
DARAM SUDHA39eede62014-02-12 11:16:40 +05304803 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07004804#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4805 &(pAdapter->wdev),
4806#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004807 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07004808#endif
4809 &chan, 0,
4810#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4811 NL80211_CHAN_HT20, 1,
4812#endif
4813 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004814 1, &cookie );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304815#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004816 vos_mem_free(finalBuf);
4817 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004818 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
4819 {
4820 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
4821 char extra[32];
4822 tANI_U8 len = 0;
4823
4824 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004825 len = scnprintf(extra, sizeof(extra), "%s %d",
4826 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304827 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4828 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
4829 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05304830 len = VOS_MIN(priv_data.total_len, len + 1);
4831 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004832 {
4833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4834 "%s: failed to copy data to user buffer", __func__);
4835 ret = -EFAULT;
4836 goto exit;
4837 }
4838 }
4839 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
4840 {
4841 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004842 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004843
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304844 ret = hdd_drv_cmd_validate(command, 18);
4845 if (ret)
4846 goto exit;
4847
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004848 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
4849 value = value + 19;
4850 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004851 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004852 if (ret < 0)
4853 {
4854 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004855 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004857 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004858 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4859 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4860 ret = -EINVAL;
4861 goto exit;
4862 }
4863
4864 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
4865 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
4866 {
4867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4868 "lfr mode value %d is out of range"
4869 " (Min: %d Max: %d)", maxTime,
4870 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4871 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4872 ret = -EINVAL;
4873 goto exit;
4874 }
4875
4876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4877 "%s: Received Command to change channel max time = %d", __func__, maxTime);
4878
4879 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
4880 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
4881 }
4882 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
4883 {
4884 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
4885 char extra[32];
4886 tANI_U8 len = 0;
4887
4888 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004889 len = scnprintf(extra, sizeof(extra), "%s %d",
4890 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05304891 len = VOS_MIN(priv_data.total_len, len + 1);
4892 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004893 {
4894 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4895 "%s: failed to copy data to user buffer", __func__);
4896 ret = -EFAULT;
4897 goto exit;
4898 }
4899 }
4900 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
4901 {
4902 tANI_U8 *value = command;
4903 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
4904
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304905 ret = hdd_drv_cmd_validate(command, 15);
4906 if (ret)
4907 goto exit;
4908
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004909 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
4910 value = value + 16;
4911 /* Convert the value from ascii to integer */
4912 ret = kstrtou16(value, 10, &val);
4913 if (ret < 0)
4914 {
4915 /* If the input value is greater than max value of datatype, then also
4916 kstrtou16 fails */
4917 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4918 "%s: kstrtou16 failed range [%d - %d]", __func__,
4919 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4920 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4921 ret = -EINVAL;
4922 goto exit;
4923 }
4924
4925 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
4926 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
4927 {
4928 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4929 "scan home time value %d is out of range"
4930 " (Min: %d Max: %d)", val,
4931 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4932 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4933 ret = -EINVAL;
4934 goto exit;
4935 }
4936
4937 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4938 "%s: Received Command to change scan home time = %d", __func__, val);
4939
4940 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
4941 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
4942 }
4943 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
4944 {
4945 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
4946 char extra[32];
4947 tANI_U8 len = 0;
4948
4949 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004950 len = scnprintf(extra, sizeof(extra), "%s %d",
4951 "GETSCANHOMETIME", val);
Ratheesh S P728d7c62015-07-16 15:38:58 +05304952 len = VOS_MIN(priv_data.total_len, len + 1);
4953 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004954 {
4955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4956 "%s: failed to copy data to user buffer", __func__);
4957 ret = -EFAULT;
4958 goto exit;
4959 }
4960 }
4961 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
4962 {
4963 tANI_U8 *value = command;
4964 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
4965
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304966 ret = hdd_drv_cmd_validate(command, 16);
4967 if (ret)
4968 goto exit;
4969
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004970 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
4971 value = value + 17;
4972 /* Convert the value from ascii to integer */
4973 ret = kstrtou8(value, 10, &val);
4974 if (ret < 0)
4975 {
4976 /* If the input value is greater than max value of datatype, then also
4977 kstrtou8 fails */
4978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4979 "%s: kstrtou8 failed range [%d - %d]", __func__,
4980 CFG_ROAM_INTRA_BAND_MIN,
4981 CFG_ROAM_INTRA_BAND_MAX);
4982 ret = -EINVAL;
4983 goto exit;
4984 }
4985
4986 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
4987 (val > CFG_ROAM_INTRA_BAND_MAX))
4988 {
4989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4990 "intra band mode value %d is out of range"
4991 " (Min: %d Max: %d)", val,
4992 CFG_ROAM_INTRA_BAND_MIN,
4993 CFG_ROAM_INTRA_BAND_MAX);
4994 ret = -EINVAL;
4995 goto exit;
4996 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004997 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4998 "%s: Received Command to change intra band = %d", __func__, val);
4999
5000 pHddCtx->cfg_ini->nRoamIntraBand = val;
5001 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
5002 }
5003 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
5004 {
5005 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
5006 char extra[32];
5007 tANI_U8 len = 0;
5008
5009 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005010 len = scnprintf(extra, sizeof(extra), "%s %d",
5011 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +05305012 len = VOS_MIN(priv_data.total_len, len + 1);
5013 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005014 {
5015 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5016 "%s: failed to copy data to user buffer", __func__);
5017 ret = -EFAULT;
5018 goto exit;
5019 }
5020 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005021 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
5022 {
5023 tANI_U8 *value = command;
5024 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
5025
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305026 ret = hdd_drv_cmd_validate(command, 14);
5027 if (ret)
5028 goto exit;
5029
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005030 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
5031 value = value + 15;
5032 /* Convert the value from ascii to integer */
5033 ret = kstrtou8(value, 10, &nProbes);
5034 if (ret < 0)
5035 {
5036 /* If the input value is greater than max value of datatype, then also
5037 kstrtou8 fails */
5038 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5039 "%s: kstrtou8 failed range [%d - %d]", __func__,
5040 CFG_ROAM_SCAN_N_PROBES_MIN,
5041 CFG_ROAM_SCAN_N_PROBES_MAX);
5042 ret = -EINVAL;
5043 goto exit;
5044 }
5045
5046 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
5047 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
5048 {
5049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5050 "NProbes value %d is out of range"
5051 " (Min: %d Max: %d)", nProbes,
5052 CFG_ROAM_SCAN_N_PROBES_MIN,
5053 CFG_ROAM_SCAN_N_PROBES_MAX);
5054 ret = -EINVAL;
5055 goto exit;
5056 }
5057
5058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5059 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
5060
5061 pHddCtx->cfg_ini->nProbes = nProbes;
5062 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
5063 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305064 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005065 {
5066 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
5067 char extra[32];
5068 tANI_U8 len = 0;
5069
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005070 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri6da525d2015-08-07 13:55:54 +05305071 len = VOS_MIN(priv_data.total_len, len + 1);
5072 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5074 "%s: failed to copy data to user buffer", __func__);
5075 ret = -EFAULT;
5076 goto exit;
5077 }
5078 }
5079 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
5080 {
5081 tANI_U8 *value = command;
5082 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
5083
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305084 ret = hdd_drv_cmd_validate(command, 19);
5085 if (ret)
5086 goto exit;
5087
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005088 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
5089 /* input value is in units of msec */
5090 value = value + 20;
5091 /* Convert the value from ascii to integer */
5092 ret = kstrtou16(value, 10, &homeAwayTime);
5093 if (ret < 0)
5094 {
5095 /* If the input value is greater than max value of datatype, then also
5096 kstrtou8 fails */
5097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5098 "%s: kstrtou8 failed range [%d - %d]", __func__,
5099 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
5100 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
5101 ret = -EINVAL;
5102 goto exit;
5103 }
5104
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005105 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
5106 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
5107 {
5108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5109 "homeAwayTime value %d is out of range"
5110 " (Min: %d Max: %d)", homeAwayTime,
5111 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
5112 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
5113 ret = -EINVAL;
5114 goto exit;
5115 }
5116
5117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5118 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07005119 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
5120 {
5121 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
5122 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
5123 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005124 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305125 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005126 {
5127 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
5128 char extra[32];
5129 tANI_U8 len = 0;
5130
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005131 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri51a5ad12015-08-07 14:06:37 +05305132 len = VOS_MIN(priv_data.total_len, len + 1);
5133 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005134 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5135 "%s: failed to copy data to user buffer", __func__);
5136 ret = -EFAULT;
5137 goto exit;
5138 }
5139 }
5140 else if (strncmp(command, "REASSOC", 7) == 0)
5141 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305142 ret = hdd_drv_cmd_validate(command, 7);
5143 if (ret)
5144 goto exit;
5145
5146 ret = hdd_parse_reassoc(pAdapter, command, priv_data.total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05305147 if (!ret)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005148 goto exit;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005149 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005150 else if (strncmp(command, "SETWESMODE", 10) == 0)
5151 {
5152 tANI_U8 *value = command;
5153 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
5154
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305155 ret = hdd_drv_cmd_validate(command, 10);
5156 if (ret)
5157 goto exit;
5158
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005159 /* Move pointer to ahead of SETWESMODE<delimiter> */
5160 value = value + 11;
5161 /* Convert the value from ascii to integer */
5162 ret = kstrtou8(value, 10, &wesMode);
5163 if (ret < 0)
5164 {
5165 /* If the input value is greater than max value of datatype, then also
5166 kstrtou8 fails */
5167 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5168 "%s: kstrtou8 failed range [%d - %d]", __func__,
5169 CFG_ENABLE_WES_MODE_NAME_MIN,
5170 CFG_ENABLE_WES_MODE_NAME_MAX);
5171 ret = -EINVAL;
5172 goto exit;
5173 }
5174
5175 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
5176 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
5177 {
5178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5179 "WES Mode value %d is out of range"
5180 " (Min: %d Max: %d)", wesMode,
5181 CFG_ENABLE_WES_MODE_NAME_MIN,
5182 CFG_ENABLE_WES_MODE_NAME_MAX);
5183 ret = -EINVAL;
5184 goto exit;
5185 }
5186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5187 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
5188
5189 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
5190 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
5191 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305192 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005193 {
5194 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
5195 char extra[32];
5196 tANI_U8 len = 0;
5197
Arif Hussain826d9412013-11-12 16:44:54 -08005198 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05305199 len = VOS_MIN(priv_data.total_len, len + 1);
5200 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5202 "%s: failed to copy data to user buffer", __func__);
5203 ret = -EFAULT;
5204 goto exit;
5205 }
5206 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005207#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005208#ifdef FEATURE_WLAN_LFR
5209 else if (strncmp(command, "SETFASTROAM", 11) == 0)
5210 {
5211 tANI_U8 *value = command;
5212 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
5213
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05305214 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
5215 hddLog(LOGE,
5216 FL("Roaming is always disabled in STA + MON concurrency"));
5217 ret = -EINVAL;
5218 goto exit;
5219 }
5220
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305221 ret = hdd_drv_cmd_validate(command, 11);
5222 if (ret)
5223 goto exit;
5224
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005225 /* Move pointer to ahead of SETFASTROAM<delimiter> */
5226 value = value + 12;
5227 /* Convert the value from ascii to integer */
5228 ret = kstrtou8(value, 10, &lfrMode);
5229 if (ret < 0)
5230 {
5231 /* If the input value is greater than max value of datatype, then also
5232 kstrtou8 fails */
5233 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5234 "%s: kstrtou8 failed range [%d - %d]", __func__,
5235 CFG_LFR_FEATURE_ENABLED_MIN,
5236 CFG_LFR_FEATURE_ENABLED_MAX);
5237 ret = -EINVAL;
5238 goto exit;
5239 }
5240
5241 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
5242 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
5243 {
5244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5245 "lfr mode value %d is out of range"
5246 " (Min: %d Max: %d)", lfrMode,
5247 CFG_LFR_FEATURE_ENABLED_MIN,
5248 CFG_LFR_FEATURE_ENABLED_MAX);
5249 ret = -EINVAL;
5250 goto exit;
5251 }
5252
5253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5254 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
5255
5256 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
5257 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
5258 }
5259#endif
5260#ifdef WLAN_FEATURE_VOWIFI_11R
5261 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
5262 {
5263 tANI_U8 *value = command;
5264 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
5265
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305266 ret = hdd_drv_cmd_validate(command, 17);
5267 if (ret)
5268 goto exit;
5269
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005270 /* Move pointer to ahead of SETFASTROAM<delimiter> */
5271 value = value + 18;
5272 /* Convert the value from ascii to integer */
5273 ret = kstrtou8(value, 10, &ft);
5274 if (ret < 0)
5275 {
5276 /* If the input value is greater than max value of datatype, then also
5277 kstrtou8 fails */
5278 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5279 "%s: kstrtou8 failed range [%d - %d]", __func__,
5280 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
5281 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
5282 ret = -EINVAL;
5283 goto exit;
5284 }
5285
5286 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
5287 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
5288 {
5289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5290 "ft mode value %d is out of range"
5291 " (Min: %d Max: %d)", ft,
5292 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
5293 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
5294 ret = -EINVAL;
5295 goto exit;
5296 }
5297
5298 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5299 "%s: Received Command to change ft mode = %d", __func__, ft);
5300
5301 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
5302 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
5303 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305304 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
5305 {
5306 tANI_U8 *value = command;
5307 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305308
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305309 ret = hdd_drv_cmd_validate(command, 14);
5310 if (ret)
5311 goto exit;
5312
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305313 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
5314 value = value + 15;
5315 /* Convert the value from ascii to integer */
5316 ret = kstrtou8(value, 10, &dfsScanMode);
5317 if (ret < 0)
5318 {
5319 /* If the input value is greater than max value of
5320 datatype, then also kstrtou8 fails
5321 */
5322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5323 "%s: kstrtou8 failed range [%d - %d]", __func__,
5324 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
5325 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
5326 ret = -EINVAL;
5327 goto exit;
5328 }
5329
5330 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
5331 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
5332 {
5333 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5334 "dfsScanMode value %d is out of range"
5335 " (Min: %d Max: %d)", dfsScanMode,
5336 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
5337 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
5338 ret = -EINVAL;
5339 goto exit;
5340 }
5341 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5342 "%s: Received Command to Set DFS Scan Mode = %d",
5343 __func__, dfsScanMode);
5344
5345 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
5346 }
5347 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
5348 {
5349 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
5350 char extra[32];
5351 tANI_U8 len = 0;
5352
5353 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05305354 len = VOS_MIN(priv_data.total_len, len + 1);
5355 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305356 {
5357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5358 "%s: failed to copy data to user buffer", __func__);
5359 ret = -EFAULT;
5360 goto exit;
5361 }
5362 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305363 else if (strncmp(command, "FASTREASSOC", 11) == 0)
5364 {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05305365 ret = wlan_hdd_handle_fastreassoc(pAdapter, command);
5366 if (!ret)
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305367 goto exit;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305368 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005369#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005370#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005371 else if (strncmp(command, "SETCCXMODE", 10) == 0)
5372 {
5373 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005374 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005375
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305376 ret = hdd_drv_cmd_validate(command, 10);
5377 if (ret)
5378 goto exit;
5379
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005380 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005381 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005382 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005383 hdd_is_okc_mode_enabled(pHddCtx) &&
5384 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
5385 {
5386 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005387 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005388 " hence this operation is not permitted!", __func__);
5389 ret = -EPERM;
5390 goto exit;
5391 }
5392
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005393 /* Move pointer to ahead of SETCCXMODE<delimiter> */
5394 value = value + 11;
5395 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005396 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005397 if (ret < 0)
5398 {
5399 /* If the input value is greater than max value of datatype, then also
5400 kstrtou8 fails */
5401 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5402 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005403 CFG_ESE_FEATURE_ENABLED_MIN,
5404 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005405 ret = -EINVAL;
5406 goto exit;
5407 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005408 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
5409 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005410 {
5411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005412 "Ese mode value %d is out of range"
5413 " (Min: %d Max: %d)", eseMode,
5414 CFG_ESE_FEATURE_ENABLED_MIN,
5415 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005416 ret = -EINVAL;
5417 goto exit;
5418 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005419 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005420 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005421
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005422 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
5423 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005424 }
5425#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005426 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
5427 {
5428 tANI_U8 *value = command;
5429 tANI_BOOLEAN roamScanControl = 0;
5430
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305431 ret = hdd_drv_cmd_validate(command, 18);
5432 if (ret)
5433 goto exit;
5434
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005435 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
5436 value = value + 19;
5437 /* Convert the value from ascii to integer */
5438 ret = kstrtou8(value, 10, &roamScanControl);
5439 if (ret < 0)
5440 {
5441 /* If the input value is greater than max value of datatype, then also
5442 kstrtou8 fails */
5443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5444 "%s: kstrtou8 failed ", __func__);
5445 ret = -EINVAL;
5446 goto exit;
5447 }
5448
5449 if (0 != roamScanControl)
5450 {
5451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5452 "roam scan control invalid value = %d",
5453 roamScanControl);
5454 ret = -EINVAL;
5455 goto exit;
5456 }
5457 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5458 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
5459
5460 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
5461 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005462#ifdef FEATURE_WLAN_OKC
5463 else if (strncmp(command, "SETOKCMODE", 10) == 0)
5464 {
5465 tANI_U8 *value = command;
5466 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
5467
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305468 ret = hdd_drv_cmd_validate(command, 10);
5469 if (ret)
5470 goto exit;
5471
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005472 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005473 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005474 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005475 hdd_is_okc_mode_enabled(pHddCtx) &&
5476 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
5477 {
5478 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005479 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005480 " hence this operation is not permitted!", __func__);
5481 ret = -EPERM;
5482 goto exit;
5483 }
5484
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005485 /* Move pointer to ahead of SETOKCMODE<delimiter> */
5486 value = value + 11;
5487 /* Convert the value from ascii to integer */
5488 ret = kstrtou8(value, 10, &okcMode);
5489 if (ret < 0)
5490 {
5491 /* If the input value is greater than max value of datatype, then also
5492 kstrtou8 fails */
5493 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5494 "%s: kstrtou8 failed range [%d - %d]", __func__,
5495 CFG_OKC_FEATURE_ENABLED_MIN,
5496 CFG_OKC_FEATURE_ENABLED_MAX);
5497 ret = -EINVAL;
5498 goto exit;
5499 }
5500
5501 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
5502 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
5503 {
5504 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5505 "Okc mode value %d is out of range"
5506 " (Min: %d Max: %d)", okcMode,
5507 CFG_OKC_FEATURE_ENABLED_MIN,
5508 CFG_OKC_FEATURE_ENABLED_MAX);
5509 ret = -EINVAL;
5510 goto exit;
5511 }
5512
5513 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5514 "%s: Received Command to change okc mode = %d", __func__, okcMode);
5515
5516 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
5517 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005518#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305519 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005520 {
5521 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
5522 char extra[32];
5523 tANI_U8 len = 0;
5524
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005525 len = scnprintf(extra, sizeof(extra), "%s %d",
5526 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05305527 len = VOS_MIN(priv_data.total_len, len + 1);
5528 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5530 "%s: failed to copy data to user buffer", __func__);
5531 ret = -EFAULT;
5532 goto exit;
5533 }
5534 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05305535#ifdef WLAN_FEATURE_PACKET_FILTERING
5536 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
5537 {
5538 tANI_U8 filterType = 0;
5539 tANI_U8 *value = command;
5540
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305541 ret = hdd_drv_cmd_validate(command, 21);
5542 if (ret)
5543 goto exit;
5544
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05305545 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
5546 value = value + 22;
5547
5548 /* Convert the value from ascii to integer */
5549 ret = kstrtou8(value, 10, &filterType);
5550 if (ret < 0)
5551 {
5552 /* If the input value is greater than max value of datatype,
5553 * then also kstrtou8 fails
5554 */
5555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5556 "%s: kstrtou8 failed range ", __func__);
5557 ret = -EINVAL;
5558 goto exit;
5559 }
5560
5561 if (filterType != 0 && filterType != 1)
5562 {
5563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5564 "%s: Accepted Values are 0 and 1 ", __func__);
5565 ret = -EINVAL;
5566 goto exit;
5567 }
5568 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
5569 pAdapter->sessionId);
5570 }
5571#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305572 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
5573 {
Kiet Lamad161252014-07-22 11:23:32 -07005574 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05305575 int ret;
5576
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305577 ret = hdd_drv_cmd_validate(command, 10);
5578 if (ret)
5579 goto exit;
5580
Kiet Lamad161252014-07-22 11:23:32 -07005581 dhcpPhase = command + 11;
5582 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305583 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05305584 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07005585 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05305586
5587 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07005588
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05305589 ret = wlan_hdd_scan_abort(pAdapter);
5590 if (ret < 0)
5591 {
5592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5593 FL("failed to abort existing scan %d"), ret);
5594 }
5595
Kiet Lamad161252014-07-22 11:23:32 -07005596 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
5597 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305598 }
Kiet Lamad161252014-07-22 11:23:32 -07005599 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305600 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05305601 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07005602 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05305603
5604 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07005605
5606 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
5607 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305608 }
5609 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005610 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
5611 {
Abhishek Singh58749d62016-02-03 15:27:20 +05305612 hddLog(LOG1,
5613 FL("making default scan to ACTIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05305614 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005615 }
5616 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
5617 {
Abhishek Singh58749d62016-02-03 15:27:20 +05305618 hddLog(LOG1,
5619 FL("making default scan to PASSIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05305620 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005621 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305622 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
5623 {
5624 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5625 char extra[32];
5626 tANI_U8 len = 0;
5627
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05305628 memset(extra, 0, sizeof(extra));
5629 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05305630 len = VOS_MIN(priv_data.total_len, len + 1);
5631 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305632 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5633 "%s: failed to copy data to user buffer", __func__);
5634 ret = -EFAULT;
5635 goto exit;
5636 }
5637 ret = len;
5638 }
5639 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
5640 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05305641 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305642 }
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05305643 else if (strncmp(command, "BTCGETDWELLTIME", 15) == 0)
5644 {
5645 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5646 char extra[32];
5647 tANI_U8 len = 0;
5648
5649 if (hdd_drv_cmd_validate(command, 15)) {
5650 hddLog(LOGE, FL("Invalid driver command"));
5651 return -EINVAL;
5652 }
5653
5654 memset(extra, 0, sizeof(extra));
5655 ret = hdd_btc_get_dwell_time(pCfg, command, extra,
5656 sizeof(extra), &len);
5657 len = VOS_MIN(priv_data.total_len, len + 1);
5658 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
5659 hddLog(LOGE, FL("Failed to copy data to user buffer"));
5660 ret = -EFAULT;
5661 goto exit;
5662 }
5663 ret = len;
5664 }
5665 else if (strncmp(command, "BTCSETDWELLTIME", 15) == 0)
5666 {
5667 if (hdd_drv_cmd_validate(command, 15)) {
5668 hddLog(LOGE, FL("Invalid driver command"));
5669 return -EINVAL;
5670 }
5671 ret = hdd_btc_set_dwell_time(pAdapter, command);
5672 }
5673#ifdef WLAN_AP_STA_CONCURRENCY
5674 else if (strncmp(command, "CONCGETDWELLTIME", 16) == 0)
5675 {
5676 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5677 char extra[32];
5678 tANI_U8 len = 0;
5679
5680 if (hdd_drv_cmd_validate(command, 16)) {
5681 hddLog(LOGE, FL("Invalid driver command"));
5682 return -EINVAL;
5683 }
5684
5685 memset(extra, 0, sizeof(extra));
5686 ret = hdd_conc_get_dwell_time(pCfg, command, extra,
5687 sizeof(extra), &len);
5688 len = VOS_MIN(priv_data.total_len, len + 1);
5689 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
5690 hddLog(LOGE, FL("Failed to copy data to user buffer"));
5691 ret = -EFAULT;
5692 goto exit;
5693 }
5694 ret = len;
5695 }
5696 else if (strncmp(command, "CONCSETDWELLTIME", 16) == 0)
5697 {
5698 if (hdd_drv_cmd_validate(command, 16)) {
5699 hddLog(LOGE, FL("Invalid driver command"));
5700 return -EINVAL;
5701 }
5702 ret = hdd_conc_set_dwell_time(pAdapter, command);
5703 }
5704#endif
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005705 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
5706 {
5707 tANI_U8 filterType = 0;
5708 tANI_U8 *value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305709
5710 ret = hdd_drv_cmd_validate(command, 8);
5711 if (ret)
5712 goto exit;
5713
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005714 value = command + 9;
5715
5716 /* Convert the value from ascii to integer */
5717 ret = kstrtou8(value, 10, &filterType);
5718 if (ret < 0)
5719 {
5720 /* If the input value is greater than max value of datatype,
5721 * then also kstrtou8 fails
5722 */
5723 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5724 "%s: kstrtou8 failed range ", __func__);
5725 ret = -EINVAL;
5726 goto exit;
5727 }
5728 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
5729 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
5730 {
5731 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5732 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
5733 " 2-Sink ", __func__);
5734 ret = -EINVAL;
5735 goto exit;
5736 }
5737 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
5738 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05305739 pScanInfo = &pHddCtx->scan_info;
5740 if (filterType && pScanInfo != NULL &&
5741 pHddCtx->scan_info.mScanPending)
5742 {
5743 /*Miracast Session started. Abort Scan */
5744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5745 "%s, Aborting Scan For Miracast",__func__);
5746 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
5747 eCSR_SCAN_ABORT_DEFAULT);
5748 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005749 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05305750 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005751 }
Leo Chang614d2072013-08-22 14:59:44 -07005752 else if (strncmp(command, "SETMCRATE", 9) == 0)
5753 {
Leo Chang614d2072013-08-22 14:59:44 -07005754 tANI_U8 *value = command;
5755 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07005756 tSirRateUpdateInd *rateUpdate;
5757 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07005758
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305759 ret = hdd_drv_cmd_validate(command, 9);
5760 if (ret)
5761 goto exit;
5762
Leo Chang614d2072013-08-22 14:59:44 -07005763 /* Only valid for SAP mode */
5764 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
5765 {
5766 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5767 "%s: SAP mode is not running", __func__);
5768 ret = -EFAULT;
5769 goto exit;
5770 }
5771
5772 /* Move pointer to ahead of SETMCRATE<delimiter> */
5773 /* input value is in units of hundred kbps */
5774 value = value + 10;
5775 /* Convert the value from ascii to integer, decimal base */
5776 ret = kstrtouint(value, 10, &targetRate);
5777
Leo Chang1f98cbd2013-10-17 15:03:52 -07005778 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
5779 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07005780 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07005781 hddLog(VOS_TRACE_LEVEL_ERROR,
5782 "%s: SETMCRATE indication alloc fail", __func__);
5783 ret = -EFAULT;
5784 goto exit;
5785 }
5786 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
5787
5788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5789 "MC Target rate %d", targetRate);
5790 /* Ignore unicast */
5791 rateUpdate->ucastDataRate = -1;
5792 rateUpdate->mcastDataRate24GHz = targetRate;
5793 rateUpdate->mcastDataRate5GHz = targetRate;
5794 rateUpdate->mcastDataRate24GHzTxFlag = 0;
5795 rateUpdate->mcastDataRate5GHzTxFlag = 0;
5796 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
5797 if (eHAL_STATUS_SUCCESS != status)
5798 {
5799 hddLog(VOS_TRACE_LEVEL_ERROR,
5800 "%s: SET_MC_RATE failed", __func__);
5801 vos_mem_free(rateUpdate);
5802 ret = -EFAULT;
5803 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07005804 }
5805 }
jge35567202017-06-21 16:39:38 +08005806 else if (strncmp(command, "MAXTXPOWER", 10) == 0)
5807 {
5808 int status;
5809 int txPower;
5810 eHalStatus smeStatus;
5811 tANI_U8 *value = command;
5812 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5813 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5814
5815 status = hdd_parse_setmaxtxpower_command(value, &txPower);
5816 if (status)
5817 {
5818 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5819 "Invalid MAXTXPOWER command ");
5820 ret = -EINVAL;
5821 goto exit;
5822 }
5823
5824 hddLog(VOS_TRACE_LEVEL_INFO, "max tx power %d selfMac: "
5825 MAC_ADDRESS_STR " bssId: " MAC_ADDRESS_STR " ",
5826 txPower, MAC_ADDR_ARRAY(selfMac),
5827 MAC_ADDR_ARRAY(bssid));
5828 smeStatus = sme_SetMaxTxPower((tHalHandle)(pHddCtx->hHal),
5829 bssid, selfMac, txPower) ;
5830 if( smeStatus != eHAL_STATUS_SUCCESS )
5831 {
5832 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:Set max tx power failed",
5833 __func__);
5834 ret = -EINVAL;
5835 goto exit;
5836 }
5837
5838 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Set max tx power success",
5839 __func__);
5840 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305841#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08005842 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05305843 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08005844 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05305845 }
5846#endif
Abhishek Singh00b71972016-01-07 10:51:04 +05305847#ifdef WLAN_FEATURE_RMC
5848 else if ((strncasecmp(command, "SETIBSSBEACONOUIDATA", 20) == 0) &&
5849 (WLAN_HDD_IBSS == pAdapter->device_mode))
5850 {
5851 int i = 0;
5852 tANI_U8 *ibss_ie;
5853 tANI_U32 command_len;
5854 tANI_U8 *value = command;
5855 tHalHandle hHal = pHddCtx->hHal;
5856 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5857 tANI_U32 ibss_ie_length;
5858 tANI_U32 len, present;
5859 tANI_U8 *addIE;
5860 tANI_U8 *addIEData;
5861
5862 hddLog(LOG1,
5863 FL(" received command %s"),((char *) value));
5864 /* validate argument of command */
5865 if (strlen(value) <= 21)
5866 {
5867 hddLog(LOGE,
5868 FL("No arguements in command length %zu"), strlen(value));
5869 ret = -EFAULT;
5870 goto exit;
5871 }
5872
5873 /* moving to arguments of commands */
5874 value = value + 21;
5875 command_len = strlen(value);
5876
5877 /* oui_data can't be less than 3 bytes */
5878 if (command_len <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH))
5879 {
5880 hddLog(LOGE,
5881 FL("Invalid SETIBSSBEACONOUIDATA command length %d"),
5882 command_len);
5883 ret = -EFAULT;
5884 goto exit;
5885 }
5886 ibss_ie = vos_mem_malloc(command_len);
5887 if (!ibss_ie) {
5888 hddLog(LOGE,
5889 FL("Could not allocate memory for command length %d"),
5890 command_len);
5891 ret = -ENOMEM;
5892 goto exit;
5893 }
5894 vos_mem_zero(ibss_ie, command_len);
5895
5896 ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie,
5897 command_len);
5898 if (ibss_ie_length < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
5899 hddLog(LOGE, FL("Could not parse command %s return length %d"),
5900 value, ibss_ie_length);
5901 ret = -EFAULT;
5902 vos_mem_free(ibss_ie);
5903 goto exit;
5904 }
5905
5906 hddLog(LOG1, FL("ibss_ie length %d ibss_ie:"), ibss_ie_length);
5907 while (i < ibss_ie_length)
5908 hddLog(LOG1, FL("0x%x"), ibss_ie[i++]);
5909
5910 /* Populate Vendor IE in Beacon */
5911 if ((ccmCfgGetInt(hHal,
5912 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
5913 &present)) != eHAL_STATUS_SUCCESS)
5914 {
5915 hddLog(LOGE,
5916 FL("unable to ftch WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
5917 ret = -EFAULT;
5918 vos_mem_free(ibss_ie);
5919 goto exit;
5920 }
5921
5922 addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5923 if (!addIE) {
5924 hddLog(LOGE,
5925 FL("Could not allocate memory for command length %d"),
5926 command_len);
5927 vos_mem_free(ibss_ie);
5928 ret = -ENOMEM;
5929 goto exit;
5930 }
5931 vos_mem_zero(addIE, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5932
5933 if (present)
5934 {
5935 if ((wlan_cfgGetStrLen(pMac,
5936 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &len)) != eSIR_SUCCESS)
5937 {
5938 hddLog(LOGE,
5939 FL("unable to fetch WNI_CFG_PROBE_RSP_BCN_ADDNIE_LEN"));
5940 ret = -EFAULT;
5941 vos_mem_free(ibss_ie);
5942 vos_mem_free(addIE);
5943 goto exit;
5944 }
5945
5946 if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
5947 ((len + ibss_ie_length) <=
5948 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN))
5949 {
5950 if ((ccmCfgGetStr(hHal,
5951 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, &len))
5952 != eHAL_STATUS_SUCCESS)
5953 {
5954 hddLog(LOGE,
5955 FL("unable to fetch WNI_PROBE_RSP_BCN_ADDNIE_DATA"));
5956 ret = -EFAULT;
5957 vos_mem_free(ibss_ie);
5958 vos_mem_free(addIE);
5959 goto exit;
5960 }
5961 else
5962 {
5963 /* Curruntly only WPA IE is added before Vendor IE
5964 * so we can blindly place the Vendor IE after WPA
5965 * IE. If no WPA IE found replace all with Vendor IE.
5966 */
5967 len = hdd_find_ibss_wpa_ie_pos(addIE, len);
5968 }
5969 }
5970 else
5971 {
5972 hddLog(LOGE,
5973 FL("IE len exceed limit len %d,ibss_ie_length %d "),
5974 len, ibss_ie_length);
5975 ret = -EFAULT;
5976 vos_mem_free(addIE);
5977 vos_mem_free(ibss_ie);
5978 goto exit;
5979 }
5980 }
5981 else {
5982 len = 0;
5983 }
5984
5985 vos_mem_copy (addIE + len , ibss_ie, ibss_ie_length);
5986 len += ibss_ie_length;
5987
5988 if (ccmCfgSetStr(hHal,
5989 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, len, NULL,
5990 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
5991 {
5992 hddLog(LOGE,
5993 FL("unable to set WNI_CFG_PRBE_RSP_BCN_ADDNIE_DATA"));
5994 ret = -EFAULT;
5995 vos_mem_free(ibss_ie);
5996 vos_mem_free(addIE);
5997 goto exit;
5998 }
5999 vos_mem_free(addIE);
6000 if (ccmCfgSetInt(hHal,
6001 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6002 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
6003 {
6004 hddLog(LOGE,
6005 FL("unble to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
6006 ret = -EFAULT;
6007 vos_mem_free(ibss_ie);
6008 goto exit;
6009 }
6010
6011 /* Populate Vendor IE in probe resp */
6012 if ((ccmCfgGetInt(hHal,
6013 WNI_CFG_PROBE_RSP_ADDNIE_FLAG,
6014 &present)) != eHAL_STATUS_SUCCESS)
6015 {
6016 hddLog(LOGE,
6017 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
6018 ret = -EFAULT;
6019 vos_mem_free(ibss_ie);
6020 goto exit;
6021 }
6022
6023 addIEData = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
6024 if (!addIEData) {
6025 hddLog(LOGE,
6026 FL("Could not allocate memory for command length %d"),
6027 command_len);
6028 vos_mem_free(ibss_ie);
6029 ret = -ENOMEM;
6030 goto exit;
6031 }
6032 vos_mem_zero(addIEData, WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
6033
6034 if (present) {
6035 if (eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
6036 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &len)) {
6037 hddLog(LOGE,
6038 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6039 ret = -EFAULT;
6040 vos_mem_free(ibss_ie);
6041 vos_mem_free(addIEData);
6042 goto exit;
6043 }
6044 if (len < WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && len &&
6045 (ibss_ie_length + len) <=
6046 WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN) {
6047
6048 if ((ccmCfgGetStr(hHal,
6049 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, addIEData, &len))
6050 != eHAL_STATUS_SUCCESS) {
6051 hddLog(LOGE,
6052 FL("unable fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6053 ret = -EFAULT;
6054 vos_mem_free(ibss_ie);
6055 vos_mem_free(addIEData);
6056 goto exit;
6057 }
6058 else {
6059 /* Curruntly only WPA IE is added before Vendor IE
6060 * so we can blindly place the Vendor IE after WPA
6061 * IE. If no WPA IE found replace all with Vendor IE.
6062 */
6063 len = hdd_find_ibss_wpa_ie_pos(addIEData, len);
6064 }
6065 }
6066 else
6067 {
6068 hddLog(LOGE,
6069 FL("IE len exceed limit len %d,ibss_ie_length %d "),
6070 len, ibss_ie_length);
6071 ret = -EFAULT;
6072 vos_mem_free(addIEData);
6073 vos_mem_free(ibss_ie);
6074 goto exit;
6075 }
6076 } /* probe rsp ADD IE present */
6077 else {
6078 /* probe rsp add IE is not present */
6079 len = 0;
6080 }
6081
6082 vos_mem_copy(addIEData +len , ibss_ie, ibss_ie_length);
6083 len += ibss_ie_length;
6084
6085 vos_mem_free(ibss_ie);
6086
6087 if (ccmCfgSetStr(hHal,
6088 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6089 (tANI_U8*)(addIEData),
6090 len, NULL,
6091 eANI_BOOLEAN_FALSE)
6092 == eHAL_STATUS_FAILURE) {
6093 hddLog(LOGE,
6094 FL("unable to copy to WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6095 ret = -EFAULT;
6096 vos_mem_free(addIEData);
6097 goto exit;
6098 }
6099 vos_mem_free(addIEData);
6100 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6101 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6102 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6103 {
6104 hddLog(LOGE,
6105 FL("unable to copy WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
6106 ret = -EFAULT;
6107 goto exit;
6108 }
6109 }
6110 else if (strncasecmp(command, "SETRMCENABLE", 12) == 0)
6111 {
6112 tANI_U8 *value = command;
6113 tANI_U8 ucRmcEnable = 0;
6114 int status;
6115
6116 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6117 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6118 {
6119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6120 "Received SETRMCENABLE command in invalid mode %d "
6121 "SETRMCENABLE command is only allowed in IBSS or SOFTAP mode",
6122 pAdapter->device_mode);
6123 ret = -EINVAL;
6124 goto exit;
6125 }
6126
6127 status = hdd_parse_setrmcenable_command(value, &ucRmcEnable);
6128 if (status)
6129 {
6130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6131 "Invalid SETRMCENABLE command ");
6132 ret = -EINVAL;
6133 goto exit;
6134 }
6135
6136 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6137 "%s: ucRmcEnable %d ", __func__, ucRmcEnable);
6138
6139 if (TRUE == ucRmcEnable)
6140 {
6141 status = sme_EnableRMC( (tHalHandle)(pHddCtx->hHal),
6142 pAdapter->sessionId );
6143 }
6144 else if(FALSE == ucRmcEnable)
6145 {
6146 status = sme_DisableRMC( (tHalHandle)(pHddCtx->hHal),
6147 pAdapter->sessionId );
6148 }
6149 else
6150 {
6151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6152 "Invalid SETRMCENABLE command %d", ucRmcEnable);
6153 ret = -EINVAL;
6154 goto exit;
6155 }
6156
6157 if (VOS_STATUS_SUCCESS != status)
6158 {
6159 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6160 "%s: SETRMC %d failed status %d", __func__, ucRmcEnable,
6161 status);
6162 ret = -EINVAL;
6163 goto exit;
6164 }
6165 }
6166 else if (strncasecmp(command, "SETRMCACTIONPERIOD", 18) == 0)
6167 {
6168 tANI_U8 *value = command;
6169 tANI_U32 uActionPeriod = 0;
6170 int status;
6171
6172 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6173 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6174 {
6175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6176 "Received SETRMC command in invalid mode %d "
6177 "SETRMC command is only allowed in IBSS or SOFTAP mode",
6178 pAdapter->device_mode);
6179 ret = -EINVAL;
6180 goto exit;
6181 }
6182
6183 status = hdd_parse_setrmcactionperiod_command(value, &uActionPeriod);
6184 if (status)
6185 {
6186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6187 "Invalid SETRMCACTIONPERIOD command ");
6188 ret = -EINVAL;
6189 goto exit;
6190 }
6191
6192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6193 "%s: uActionPeriod %d ", __func__, uActionPeriod);
6194
6195 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
6196 uActionPeriod, NULL, eANI_BOOLEAN_FALSE))
6197 {
6198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6199 "%s: Could not set SETRMCACTIONPERIOD %d", __func__, uActionPeriod);
6200 ret = -EINVAL;
6201 goto exit;
6202 }
6203
6204 }
6205 else if (strncasecmp(command, "GETIBSSPEERINFOALL", 18) == 0)
6206 {
6207 /* Peer Info All Command */
6208 int status = eHAL_STATUS_SUCCESS;
6209 hdd_station_ctx_t *pHddStaCtx = NULL;
6210 char *extra = NULL;
6211 int idx = 0, length = 0;
6212 v_MACADDR_t *macAddr;
6213 v_U32_t txRateMbps = 0, numOfBytestoPrint = 0;
6214
6215 if (WLAN_HDD_IBSS == pAdapter->device_mode)
6216 {
6217 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6218 }
6219 else
6220 {
6221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6222 "%s: pAdapter is not valid for this device mode",
6223 __func__);
6224 ret = -EINVAL;
6225 goto exit;
6226 }
6227
6228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6229 "%s: Received GETIBSSPEERINFOALL Command", __func__);
6230
6231
6232 /* Handle the command */
6233 status = hdd_cfg80211_get_ibss_peer_info_all(pAdapter);
6234 if (VOS_STATUS_SUCCESS == status)
6235 {
6236 /* The variable extra needed to be allocated on the heap since
6237 * amount of memory required to copy the data for 32 devices
6238 * exceeds the size of 1024 bytes of default stack size. On
6239 * 64 bit devices, the default max stack size of 2048 bytes
6240 */
6241 extra = kmalloc(WLAN_MAX_BUF_SIZE, GFP_KERNEL);
6242
6243 if (NULL == extra)
6244 {
6245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6246 "%s:kmalloc failed", __func__);
6247 ret = -EINVAL;
6248 goto exit;
6249 }
6250
6251 /* Copy number of stations */
6252 length = scnprintf( extra, WLAN_MAX_BUF_SIZE, "%d ",
6253 pHddStaCtx->ibss_peer_info.numIBSSPeers);
6254 numOfBytestoPrint = length;
6255 for (idx = 0; idx < pHddStaCtx->ibss_peer_info.numIBSSPeers; idx++)
6256 {
6257 macAddr =
6258 hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
6259 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
6260 if (NULL != macAddr)
6261 {
6262 txRateMbps =
6263 ((pHddStaCtx->ibss_peer_info.ibssPeerList[idx].txRate)*500*1000)/1000000;
6264
6265 length += scnprintf( (extra + length), WLAN_MAX_BUF_SIZE - length,
6266 "%02x:%02x:%02x:%02x:%02x:%02x %d %d ",
6267 macAddr->bytes[0], macAddr->bytes[1], macAddr->bytes[2],
6268 macAddr->bytes[3], macAddr->bytes[4], macAddr->bytes[5],
6269 (int)txRateMbps,
6270 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[idx].rssi);
6271 }
6272 else
6273 {
6274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6275 "%s: MAC ADDR is NULL for staIdx: %d", __func__,
6276 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
6277 }
6278
6279 /*
6280 * VOS_TRACE() macro has limitation of 512 bytes for the print
6281 * buffer. Hence printing the data in two chunks. The first chunk
6282 * will have the data for 16 devices and the second chunk will
6283 * have the rest.
6284 */
6285 if (idx < NUM_OF_STA_DATA_TO_PRINT)
6286 {
6287 numOfBytestoPrint = length;
6288 }
6289 }
6290
6291 /*
6292 * Copy the data back into buffer, if the data to copy is
6293 * morethan 512 bytes than we will split the data and do
6294 * it in two shots
6295 */
6296 if (copy_to_user(priv_data.buf, extra, numOfBytestoPrint))
6297 {
6298 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6299 "%s: Copy into user data buffer failed ", __func__);
6300 ret = -EFAULT;
6301 kfree(extra);
6302 goto exit;
6303 }
6304 priv_data.buf[numOfBytestoPrint] = '\0';
6305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6306 "%s", priv_data.buf);
6307
6308 if (length > numOfBytestoPrint)
6309 {
6310 if (copy_to_user(priv_data.buf + numOfBytestoPrint,
6311 extra + numOfBytestoPrint,
6312 length - numOfBytestoPrint + 1))
6313 {
6314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6315 "%s: Copy into user data buffer failed ", __func__);
6316 ret = -EFAULT;
6317 kfree(extra);
6318 goto exit;
6319 }
6320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6321 "%s", &priv_data.buf[numOfBytestoPrint]);
6322 }
6323
6324 /* Free temporary buffer */
6325 kfree(extra);
6326 }
6327
6328 else
6329 {
6330 /* Command failed, log error */
6331 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6332 "%s: GETIBSSPEERINFOALL command failed with status code %d",
6333 __func__, status);
6334 ret = -EINVAL;
6335 goto exit;
6336 }
6337 ret = 0;
6338 }
6339 else if(strncasecmp(command, "GETIBSSPEERINFO", 15) == 0)
6340 {
6341 /* Peer Info <Peer Addr> command */
6342 tANI_U8 *value = command;
6343 VOS_STATUS status;
6344 hdd_station_ctx_t *pHddStaCtx = NULL;
6345 char extra[128] = { 0 };
6346 v_U32_t length = 0;
6347 v_U8_t staIdx = 0;
6348 v_U32_t txRateMbps = 0;
6349 v_MACADDR_t peerMacAddr;
6350
6351 if (WLAN_HDD_IBSS == pAdapter->device_mode)
6352 {
6353 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6354 }
6355 else
6356 {
6357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6358 "%s: pAdapter is not valid for this device mode",
6359 __func__);
6360 ret = -EINVAL;
6361 goto exit;
6362 }
6363
6364 /* if there are no peers, no need to continue with the command */
6365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6366 "%s: Received GETIBSSPEERINFO Command", __func__);
6367
6368 if (eConnectionState_IbssConnected != pHddStaCtx->conn_info.connState)
6369 {
6370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6371 "%s:No IBSS Peers coalesced", __func__);
6372 ret = -EINVAL;
6373 goto exit;
6374 }
6375
6376 /* Parse the incoming command buffer */
6377 status = hdd_parse_get_ibss_peer_info(value, &peerMacAddr);
6378 if (VOS_STATUS_SUCCESS != status)
6379 {
6380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6381 "%s: Invalid GETIBSSPEERINFO command", __func__);
6382 ret = -EINVAL;
6383 goto exit;
6384 }
6385
6386 /* Get station index for the peer mac address */
6387 hdd_Ibss_GetStaId(pHddStaCtx, &peerMacAddr, &staIdx);
6388
6389 if (staIdx > HDD_MAX_NUM_IBSS_STA)
6390 {
6391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6392 "%s: Invalid StaIdx %d returned", __func__, staIdx);
6393 ret = -EINVAL;
6394 goto exit;
6395 }
6396
6397 /* Handle the command */
6398 status = hdd_cfg80211_get_ibss_peer_info(pAdapter, staIdx);
6399 if (VOS_STATUS_SUCCESS == status)
6400 {
6401 v_U32_t txRate = pHddStaCtx->ibss_peer_info.ibssPeerList[0].txRate;
6402 txRateMbps = (txRate * 500 * 1000)/1000000;
6403
6404 length = scnprintf( extra, sizeof(extra), "%d %d", (int)txRateMbps,
6405 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[0].rssi);
6406
6407 /* Copy the data back into buffer */
6408 if (copy_to_user(priv_data.buf, &extra, length+ 1))
6409 {
6410 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6411 "%s: copy data to user buffer failed GETIBSSPEERINFO command",
6412 __func__);
6413 ret = -EFAULT;
6414 goto exit;
6415 }
6416 }
6417 else
6418 {
6419 /* Command failed, log error */
6420 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6421 "%s: GETIBSSPEERINFO command failed with status code %d",
6422 __func__, status);
6423 ret = -EINVAL;
6424 goto exit;
6425 }
6426
6427 /* Success ! */
6428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6429 "%s", priv_data.buf);
6430 ret = 0;
6431 }
6432 else if (strncasecmp(command, "SETRMCTXRATE", 12) == 0)
6433 {
6434 tANI_U8 *value = command;
6435 tANI_U32 uRate = 0;
6436 tTxrateinfoflags txFlags = 0;
6437 tSirRateUpdateInd *rateUpdateParams;
6438 int status;
6439
6440 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6441 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6442 {
6443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6444 "Received SETRMCTXRATE command in invalid mode %d "
6445 "SETRMC command is only allowed in IBSS or SOFTAP mode",
6446 pAdapter->device_mode);
6447 ret = -EINVAL;
6448 goto exit;
6449 }
6450
6451 status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags);
6452 if (status)
6453 {
6454 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6455 "Invalid SETRMCTXRATE command ");
6456 ret = -EINVAL;
6457 goto exit;
6458 }
6459
6460 rateUpdateParams = vos_mem_malloc(sizeof(tSirRateUpdateInd));
6461 if (NULL == rateUpdateParams)
6462 {
6463 ret = -EINVAL;
6464 goto exit;
6465 }
6466
6467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6468 "%s: uRate %d ", __func__, uRate);
6469
6470 vos_mem_zero(rateUpdateParams, sizeof(tSirRateUpdateInd ));
6471
6472 /* -1 implies ignore this param */
6473 rateUpdateParams->ucastDataRate = -1;
6474
6475 /*
6476 * Fill the user specifieed RMC rate param
6477 * and the derived tx flags.
6478 */
6479 rateUpdateParams->rmcDataRate = uRate;
6480 rateUpdateParams->rmcDataRateTxFlag = txFlags;
6481
6482 status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), rateUpdateParams);
6483 }
6484 else if (strncasecmp(command, "SETIBSSTXFAILEVENT", 18) == 0 )
6485 {
6486 char *value;
6487 tANI_U8 tx_fail_count = 0;
6488 tANI_U16 pid = 0;
6489
6490 value = command;
6491
6492 ret = hdd_ParseIBSSTXFailEventParams(value, &tx_fail_count, &pid);
6493
6494 if (0 != ret)
6495 {
6496 hddLog(VOS_TRACE_LEVEL_INFO,
6497 "%s: Failed to parse SETIBSSTXFAILEVENT arguments",
6498 __func__);
6499 goto exit;
6500 }
6501
6502 hddLog(VOS_TRACE_LEVEL_INFO, "%s: tx_fail_cnt=%hhu, pid=%hu",
6503 __func__, tx_fail_count, pid);
6504
6505 if (0 == tx_fail_count)
6506 {
6507 // Disable TX Fail Indication
6508 if (eHAL_STATUS_SUCCESS ==
6509 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
6510 tx_fail_count,
6511 NULL))
6512 {
6513 cesium_pid = 0;
6514 }
6515 else
6516 {
6517 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6518 "%s: failed to disable TX Fail Event ", __func__);
6519 ret = -EINVAL;
6520 }
6521 }
6522 else
6523 {
6524 if (eHAL_STATUS_SUCCESS ==
6525 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
6526 tx_fail_count,
6527 (void*)hdd_tx_fail_ind_callback))
6528 {
6529 cesium_pid = pid;
6530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6531 "%s: Registered Cesium pid %u", __func__,
6532 cesium_pid);
6533 }
6534 else
6535 {
6536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6537 "%s: Failed to enable TX Fail Monitoring", __func__);
6538 ret = -EINVAL;
6539 }
6540 }
6541 }
6542
6543#endif /* WLAN_FEATURE_RMC */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006544#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006545 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
6546 {
6547 tANI_U8 *value = command;
6548 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
6549 tANI_U8 numChannels = 0;
6550 eHalStatus status = eHAL_STATUS_SUCCESS;
6551
6552 status = hdd_parse_channellist(value, ChannelList, &numChannels);
6553 if (eHAL_STATUS_SUCCESS != status)
6554 {
6555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6556 "%s: Failed to parse channel list information", __func__);
6557 ret = -EINVAL;
6558 goto exit;
6559 }
6560
6561 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
6562 {
6563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6564 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
6565 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
6566 ret = -EINVAL;
6567 goto exit;
6568 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006569 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006570 ChannelList,
6571 numChannels);
6572 if (eHAL_STATUS_SUCCESS != status)
6573 {
6574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6575 "%s: Failed to update channel list information", __func__);
6576 ret = -EINVAL;
6577 goto exit;
6578 }
6579 }
6580 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
6581 {
6582 tANI_U8 *value = command;
6583 char extra[128] = {0};
6584 int len = 0;
6585 tANI_U8 tid = 0;
6586 hdd_station_ctx_t *pHddStaCtx = NULL;
6587 tAniTrafStrmMetrics tsmMetrics;
6588 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6589
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306590 ret = hdd_drv_cmd_validate(command, 11);
6591 if (ret)
6592 goto exit;
6593
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006594 /* if not associated, return error */
6595 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6596 {
6597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
6598 ret = -EINVAL;
6599 goto exit;
6600 }
6601
6602 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
6603 value = value + 12;
6604 /* Convert the value from ascii to integer */
6605 ret = kstrtou8(value, 10, &tid);
6606 if (ret < 0)
6607 {
6608 /* If the input value is greater than max value of datatype, then also
6609 kstrtou8 fails */
6610 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6611 "%s: kstrtou8 failed range [%d - %d]", __func__,
6612 TID_MIN_VALUE,
6613 TID_MAX_VALUE);
6614 ret = -EINVAL;
6615 goto exit;
6616 }
6617
6618 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
6619 {
6620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6621 "tid value %d is out of range"
6622 " (Min: %d Max: %d)", tid,
6623 TID_MIN_VALUE,
6624 TID_MAX_VALUE);
6625 ret = -EINVAL;
6626 goto exit;
6627 }
6628
6629 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6630 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
6631
6632 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
6633 {
6634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6635 "%s: failed to get tsm stats", __func__);
6636 ret = -EFAULT;
6637 goto exit;
6638 }
6639
6640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6641 "UplinkPktQueueDly(%d)\n"
6642 "UplinkPktQueueDlyHist[0](%d)\n"
6643 "UplinkPktQueueDlyHist[1](%d)\n"
6644 "UplinkPktQueueDlyHist[2](%d)\n"
6645 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05306646 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006647 "UplinkPktLoss(%d)\n"
6648 "UplinkPktCount(%d)\n"
6649 "RoamingCount(%d)\n"
6650 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
6651 tsmMetrics.UplinkPktQueueDlyHist[0],
6652 tsmMetrics.UplinkPktQueueDlyHist[1],
6653 tsmMetrics.UplinkPktQueueDlyHist[2],
6654 tsmMetrics.UplinkPktQueueDlyHist[3],
6655 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
6656 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
6657
6658 /* Output TSM stats is of the format
6659 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
6660 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006661 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006662 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
6663 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
6664 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
6665 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
6666 tsmMetrics.RoamingDly);
6667
Ratnam Rachurid53009c2015-08-07 13:59:00 +05306668 len = VOS_MIN(priv_data.total_len, len + 1);
6669 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006670 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6671 "%s: failed to copy data to user buffer", __func__);
6672 ret = -EFAULT;
6673 goto exit;
6674 }
6675 }
6676 else if (strncmp(command, "SETCCKMIE", 9) == 0)
6677 {
6678 tANI_U8 *value = command;
6679 tANI_U8 *cckmIe = NULL;
6680 tANI_U8 cckmIeLen = 0;
6681 eHalStatus status = eHAL_STATUS_SUCCESS;
6682
6683 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
6684 if (eHAL_STATUS_SUCCESS != status)
6685 {
6686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6687 "%s: Failed to parse cckm ie data", __func__);
6688 ret = -EINVAL;
6689 goto exit;
6690 }
6691
6692 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
6693 {
6694 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6695 "%s: CCKM Ie input length is more than max[%d]", __func__,
6696 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006697 vos_mem_free(cckmIe);
6698 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006699 ret = -EINVAL;
6700 goto exit;
6701 }
6702 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006703 vos_mem_free(cckmIe);
6704 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006705 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006706 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
6707 {
6708 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006709 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006710 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07006711
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006712 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006713 if (eHAL_STATUS_SUCCESS != status)
6714 {
6715 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006716 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006717 ret = -EINVAL;
6718 goto exit;
6719 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07006720 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6721 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
6722 hdd_indicateEseBcnReportNoResults (pAdapter,
6723 eseBcnReq.bcnReq[0].measurementToken,
6724 0x02, //BIT(1) set for measurement done
6725 0); // no BSS
6726 goto exit;
6727 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006728
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006729 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
6730 if (eHAL_STATUS_SUCCESS != status)
6731 {
6732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6733 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
6734 ret = -EINVAL;
6735 goto exit;
6736 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006737 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006738#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05306739 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
6740 {
6741 eHalStatus status;
6742 char buf[32], len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306743 void *cookie;
6744 struct hdd_request *request;
6745 struct bcn_miss_rate_priv *priv;
6746 static const struct hdd_request_params params = {
6747 .priv_size = sizeof(*priv),
6748 .timeout_ms = WLAN_WAIT_TIME_STATS,
6749 };
c_hpothu92367912014-05-01 15:18:17 +05306750
6751 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6752
6753 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6754 {
6755 hddLog(VOS_TRACE_LEVEL_WARN,
6756 FL("GETBCNMISSRATE: STA is not in connected state"));
6757 ret = -1;
6758 goto exit;
6759 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306760 request = hdd_request_alloc(&params);
6761 if (!request) {
6762 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6763 ret = -ENOMEM;
6764 goto exit;
6765 }
6766 cookie = hdd_request_cookie(request);
6767 priv = hdd_request_priv(request);
6768 priv->bcn_miss_rate = -1;
c_hpothu92367912014-05-01 15:18:17 +05306769
6770 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
6771 pAdapter->sessionId,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306772 (void *)get_bcn_miss_rate_cb,
6773 cookie);
c_hpothu92367912014-05-01 15:18:17 +05306774 if( eHAL_STATUS_SUCCESS != status)
6775 {
6776 hddLog(VOS_TRACE_LEVEL_INFO,
6777 FL("GETBCNMISSRATE: fail to post WDA cmd"));
6778 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306779 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306780 }
6781
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306782 ret = hdd_request_wait_for_response(request);
6783 if(ret)
c_hpothu92367912014-05-01 15:18:17 +05306784 {
6785 hddLog(VOS_TRACE_LEVEL_ERROR,
6786 FL("failed to wait on bcnMissRateComp %d"), ret);
6787
c_hpothu92367912014-05-01 15:18:17 +05306788 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306789 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306790 }
6791
6792 hddLog(VOS_TRACE_LEVEL_INFO,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306793 FL("GETBCNMISSRATE: bcnMissRate: %d"), priv->bcn_miss_rate);
c_hpothu92367912014-05-01 15:18:17 +05306794
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306795 if (priv->bcn_miss_rate == -1) {
6796 ret = -EFAULT;
6797 goto free_bcn_miss_rate_req;
6798 }
6799
6800 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d",
6801 priv->bcn_miss_rate);
c_hpothu92367912014-05-01 15:18:17 +05306802 if (copy_to_user(priv_data.buf, &buf, len + 1))
6803 {
6804 hddLog(VOS_TRACE_LEVEL_ERROR,
6805 "%s: failed to copy data to user buffer", __func__);
6806 ret = -EFAULT;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306807 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306808 }
6809 ret = len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306810
6811free_bcn_miss_rate_req:
6812 hdd_request_put(request);
c_hpothu92367912014-05-01 15:18:17 +05306813 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306814#ifdef FEATURE_WLAN_TDLS
6815 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
6816 tANI_U8 *value = command;
6817 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306818
6819 ret = hdd_drv_cmd_validate(command, 26);
6820 if (ret)
6821 goto exit;
6822
Atul Mittal87ec2422014-09-24 13:12:50 +05306823 /* Move pointer to ahead of TDLSOFFCH*/
6824 value += 26;
c_manjeebbc40212015-12-08 13:52:59 +05306825 if (!(sscanf(value, "%d", &set_value))) {
6826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6827 FL("No input identified"));
6828 ret = -EINVAL;
6829 goto exit;
6830 }
6831
Atul Mittal87ec2422014-09-24 13:12:50 +05306832 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6833 "%s: Tdls offchannel offset:%d",
6834 __func__, set_value);
6835 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
6836 if (ret < 0)
6837 {
6838 ret = -EINVAL;
6839 goto exit;
6840 }
6841
6842 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
6843 tANI_U8 *value = command;
6844 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306845
6846 ret = hdd_drv_cmd_validate(command, 18);
6847 if (ret)
6848 goto exit;
6849
Atul Mittal87ec2422014-09-24 13:12:50 +05306850 /* Move pointer to ahead of tdlsoffchnmode*/
6851 value += 18;
c_manjee82323892015-12-08 12:40:34 +05306852 ret = sscanf(value, "%d", &set_value);
6853 if (ret != 1) {
6854 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6855 FL("No input identified"));
6856 ret = -EINVAL;
6857 goto exit;
6858 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6860 "%s: Tdls offchannel mode:%d",
6861 __func__, set_value);
6862 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
6863 if (ret < 0)
6864 {
6865 ret = -EINVAL;
6866 goto exit;
6867 }
6868 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
6869 tANI_U8 *value = command;
6870 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306871
6872 ret = hdd_drv_cmd_validate(command, 14);
6873 if (ret)
6874 goto exit;
6875
Atul Mittal87ec2422014-09-24 13:12:50 +05306876 /* Move pointer to ahead of TDLSOFFCH*/
6877 value += 14;
c_manjeef6ccaf52015-12-08 11:52:11 +05306878 ret = sscanf(value, "%d", &set_value);
6879 if (ret != 1) {
6880 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6881 "Wrong value is given for hdd_set_tdls_offchannel");
6882 ret = -EINVAL;
6883 goto exit;
6884 }
6885
Atul Mittal87ec2422014-09-24 13:12:50 +05306886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6887 "%s: Tdls offchannel num: %d",
6888 __func__, set_value);
6889 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
6890 if (ret < 0)
6891 {
6892 ret = -EINVAL;
6893 goto exit;
6894 }
6895 }
6896#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05306897 else if (strncmp(command, "GETFWSTATS", 10) == 0)
6898 {
6899 eHalStatus status;
6900 char *buf = NULL;
6901 char len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306902 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp),
6903 *fw_stats_result;
Satyanarayana Dash72806012014-12-02 14:30:08 +05306904 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306905 int stats;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306906 void *cookie;
6907 struct hdd_request *request;
6908 struct fw_stats_priv *priv;
6909 static const struct hdd_request_params params = {
6910 .priv_size = sizeof(*priv),
6911 .timeout_ms = WLAN_WAIT_TIME_STATS,
6912 };
Satyanarayana Dash72806012014-12-02 14:30:08 +05306913
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306914 ret = hdd_drv_cmd_validate(command, 10);
6915 if (ret)
6916 goto exit;
6917
6918 stats = *(ptr + 11) - '0';
Satyanarayana Dash72806012014-12-02 14:30:08 +05306919 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
6920 if (!IS_FEATURE_FW_STATS_ENABLE)
6921 {
6922 hddLog(VOS_TRACE_LEVEL_INFO,
6923 FL("Get Firmware stats feature not supported"));
6924 ret = -EINVAL;
6925 goto exit;
6926 }
6927
6928 if (FW_STATS_MAX <= stats || 0 >= stats)
6929 {
6930 hddLog(VOS_TRACE_LEVEL_INFO,
6931 FL(" stats %d not supported"),stats);
6932 ret = -EINVAL;
6933 goto exit;
6934 }
6935
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306936 request = hdd_request_alloc(&params);
6937 if (!request) {
6938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6939 ret = -ENOMEM;
6940 goto exit;
6941 }
6942 cookie = hdd_request_cookie(request);
6943
Satyanarayana Dash72806012014-12-02 14:30:08 +05306944 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306945 cookie, hdd_fw_stats_cb);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306946 if (eHAL_STATUS_SUCCESS != status)
6947 {
6948 hddLog(VOS_TRACE_LEVEL_ERROR,
6949 FL(" fail to post WDA cmd status = %d"), status);
6950 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306951 hdd_request_put(request);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306952 goto exit;
6953 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306954 ret = hdd_request_wait_for_response(request);
6955 if (ret)
Satyanarayana Dash72806012014-12-02 14:30:08 +05306956 {
6957 hddLog(VOS_TRACE_LEVEL_ERROR,
6958 FL("failed to wait on GwtFwstats"));
Satyanarayana Dash72806012014-12-02 14:30:08 +05306959 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306960 hdd_request_put(request);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306961 goto exit;
6962 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306963
6964 priv = hdd_request_priv(request);
6965 fw_stats_result = priv->fw_stats;
6966 fwStatsRsp->type = 0;
6967 if (NULL != fw_stats_result)
6968 {
6969 switch (fw_stats_result->type )
6970 {
6971 case FW_UBSP_STATS:
6972 {
6973 tSirUbspFwStats *stats =
6974 &fwStatsRsp->fwStatsData.ubspStats;
6975 memcpy(fwStatsRsp, fw_stats_result,
6976 sizeof(tSirFwStatsResult));
6977 hddLog(VOS_TRACE_LEVEL_INFO,
6978 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
6979 stats->ubsp_enter_cnt,
6980 stats->ubsp_jump_ddr_cnt);
6981 }
6982 break;
6983
6984 default:
6985 {
6986 hddLog(VOS_TRACE_LEVEL_ERROR,
6987 FL("No handling for stats type %d"),
6988 fw_stats_result->type);
6989 }
6990 }
6991 }
6992 hdd_request_put(request);
6993
Satyanarayana Dash72806012014-12-02 14:30:08 +05306994 if (fwStatsRsp->type)
6995 {
6996 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
6997 if (!buf)
6998 {
6999 hddLog(VOS_TRACE_LEVEL_ERROR,
7000 FL(" failed to allocate memory"));
7001 ret = -ENOMEM;
7002 goto exit;
7003 }
7004 switch( fwStatsRsp->type )
7005 {
7006 case FW_UBSP_STATS:
7007 {
7008 len = snprintf(buf, FW_STATE_RSP_LEN,
7009 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05307010 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
7011 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05307012 }
7013 break;
7014 default:
7015 {
7016 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
7017 ret = -EFAULT;
7018 kfree(buf);
7019 goto exit;
7020 }
7021 }
7022 if (copy_to_user(priv_data.buf, buf, len + 1))
7023 {
7024 hddLog(VOS_TRACE_LEVEL_ERROR,
7025 FL(" failed to copy data to user buffer"));
7026 ret = -EFAULT;
7027 kfree(buf);
7028 goto exit;
7029 }
7030 ret = len;
7031 kfree(buf);
7032 }
7033 else
7034 {
7035 hddLog(VOS_TRACE_LEVEL_ERROR,
7036 FL("failed to fetch the stats"));
7037 ret = -EFAULT;
7038 goto exit;
7039 }
Satyanarayana Dash72806012014-12-02 14:30:08 +05307040 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05307041 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
7042 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05307043 ret = hdd_drv_cmd_validate(command, 15);
7044 if (ret)
7045 goto exit;
7046
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05307047 /*
7048 * this command wld be called by user-space when it detects WLAN
7049 * ON after airplane mode is set. When APM is set, WLAN turns off.
7050 * But it can be turned back on. Otherwise; when APM is turned back
7051 * off, WLAN wld turn back on. So at that point the command is
7052 * expected to come down. 0 means disable, 1 means enable. The
7053 * constraint is removed when parameter 1 is set or different
7054 * country code is set
7055 */
7056 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
7057 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05307058 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
7059 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05307060 ret = hdd_drv_cmd_validate(command, 16);
7061 if (ret)
7062 goto exit;
7063
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05307064 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
7065 }
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05307066 /*
7067 * command should be a string having format
7068 * SET_DISABLE_CHANNEL_LIST <num of channels>
7069 * <channels separated by spaces>
7070 */
7071 else if (strncmp(command, "SET_DISABLE_CHANNEL_LIST", 24) == 0) {
7072 tANI_U8 *ptr = command;
7073 ret = hdd_drv_cmd_validate(command, 24);
7074 if (ret)
7075 goto exit;
7076
7077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7078 " Received Command to disable Channels %s",
7079 __func__);
7080 ret = hdd_parse_disable_chan_cmd(pAdapter, ptr);
7081 if (ret)
7082 goto exit;
7083 }
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307084 else if (strncmp(command, "GET_DISABLE_CHANNEL_LIST", 24) == 0) {
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307085 char extra[512] = {0};
7086 int max_len, copied_length;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05307087
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307089 " Received Command to get disable Channels list %s",
7090 __func__);
7091
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307092 max_len = VOS_MIN(priv_data.total_len, sizeof(extra));
7093 copied_length = hdd_get_disable_ch_list(pHddCtx, extra, max_len);
7094 if (copied_length == 0) {
7095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307096 FL("disable channel list are not yet programed"));
7097 ret = -EINVAL;
7098 goto exit;
7099 }
7100
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307101 if (copy_to_user(priv_data.buf, &extra, copied_length + 1)) {
7102 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7103 "%s: failed to copy data to user buffer", __func__);
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307104 ret = -EFAULT;
7105 goto exit;
7106 }
7107
7108 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7109 FL("data:%s"), extra);
7110 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07007111 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307112 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7113 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
7114 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05307115 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
7116 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07007117 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007118 }
7119exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307120 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007121 if (command)
7122 {
7123 kfree(command);
7124 }
7125 return ret;
7126}
7127
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007128#ifdef CONFIG_COMPAT
7129static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7130{
7131 struct {
7132 compat_uptr_t buf;
7133 int used_len;
7134 int total_len;
7135 } compat_priv_data;
7136 hdd_priv_data_t priv_data;
7137 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007138
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007139 /*
7140 * Note that pAdapter and ifr have already been verified by caller,
7141 * and HDD context has also been validated
7142 */
7143 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
7144 sizeof(compat_priv_data))) {
7145 ret = -EFAULT;
7146 goto exit;
7147 }
7148 priv_data.buf = compat_ptr(compat_priv_data.buf);
7149 priv_data.used_len = compat_priv_data.used_len;
7150 priv_data.total_len = compat_priv_data.total_len;
7151 ret = hdd_driver_command(pAdapter, &priv_data);
7152 exit:
7153 return ret;
7154}
7155#else /* CONFIG_COMPAT */
7156static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7157{
7158 /* will never be invoked */
7159 return 0;
7160}
7161#endif /* CONFIG_COMPAT */
7162
7163static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7164{
7165 hdd_priv_data_t priv_data;
7166 int ret = 0;
7167
7168 /*
7169 * Note that pAdapter and ifr have already been verified by caller,
7170 * and HDD context has also been validated
7171 */
7172 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
7173 ret = -EFAULT;
7174 } else {
7175 ret = hdd_driver_command(pAdapter, &priv_data);
7176 }
7177 return ret;
7178}
7179
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307180int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007181{
7182 hdd_adapter_t *pAdapter;
7183 hdd_context_t *pHddCtx;
7184 int ret;
7185
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307186 ENTER();
7187
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007188 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7189 if (NULL == pAdapter) {
7190 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7191 "%s: HDD adapter context is Null", __func__);
7192 ret = -ENODEV;
7193 goto exit;
7194 }
7195 if (dev != pAdapter->dev) {
7196 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7197 "%s: HDD adapter/dev inconsistency", __func__);
7198 ret = -ENODEV;
7199 goto exit;
7200 }
7201
7202 if ((!ifr) || (!ifr->ifr_data)) {
7203 ret = -EINVAL;
7204 goto exit;
7205 }
7206
7207 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7208 ret = wlan_hdd_validate_context(pHddCtx);
7209 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007210 ret = -EBUSY;
7211 goto exit;
7212 }
7213
7214 switch (cmd) {
7215 case (SIOCDEVPRIVATE + 1):
7216 if (is_compat_task())
7217 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
7218 else
7219 ret = hdd_driver_ioctl(pAdapter, ifr);
7220 break;
7221 default:
7222 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
7223 __func__, cmd);
7224 ret = -EINVAL;
7225 break;
7226 }
7227 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307228 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007229 return ret;
7230}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007231
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307232int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7233{
7234 int ret;
7235
7236 vos_ssr_protect(__func__);
7237 ret = __hdd_ioctl(dev, ifr, cmd);
7238 vos_ssr_unprotect(__func__);
7239
7240 return ret;
7241}
7242
Katya Nigame7b69a82015-04-28 15:24:06 +05307243int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7244{
7245 return 0;
7246}
7247
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007248#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007249/**---------------------------------------------------------------------------
7250
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007251 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007252
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007253 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007254 CCXBEACONREQ<space><Number of fields><space><Measurement token>
7255 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
7256 <space>Scan Mode N<space>Meas Duration N
7257 if the Number of bcn req fields (N) does not match with the actual number of fields passed
7258 then take N.
7259 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
7260 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
7261 This function does not take care of removing duplicate channels from the list
7262
7263 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007264 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007265
7266 \return - 0 for success non-zero for failure
7267
7268 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007269static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
7270 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007271{
7272 tANI_U8 *inPtr = pValue;
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307273 uint8_t input = 0;
7274 uint32_t tempInt = 0;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007275 int j = 0, i = 0, v = 0;
7276 char buf[32];
7277
7278 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7279 /*no argument after the command*/
7280 if (NULL == inPtr)
7281 {
7282 return -EINVAL;
7283 }
7284 /*no space after the command*/
7285 else if (SPACE_ASCII_VALUE != *inPtr)
7286 {
7287 return -EINVAL;
7288 }
7289
7290 /*removing empty spaces*/
7291 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
7292
7293 /*no argument followed by spaces*/
7294 if ('\0' == *inPtr) return -EINVAL;
7295
7296 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007297 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007298 if (1 != v) return -EINVAL;
7299
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307300 v = kstrtos8(buf, 10, &input);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007301 if ( v < 0) return -EINVAL;
7302
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307303 input = VOS_MIN(input, SIR_ESE_MAX_MEAS_IE_REQS);
7304 pEseBcnReq->numBcnReqIe = input;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007305
Srinivas Girigowda725a88e2016-03-31 19:24:25 +05307306 hddLog(LOG1, "Number of Bcn Req Ie fields: %d", pEseBcnReq->numBcnReqIe);
7307
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007308
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007309 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007310 {
7311 for (i = 0; i < 4; i++)
7312 {
7313 /*inPtr pointing to the beginning of first space after number of ie fields*/
7314 inPtr = strpbrk( inPtr, " " );
7315 /*no ie data after the number of ie fields argument*/
7316 if (NULL == inPtr) return -EINVAL;
7317
7318 /*removing empty space*/
7319 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
7320
7321 /*no ie data after the number of ie fields argument and spaces*/
7322 if ( '\0' == *inPtr ) return -EINVAL;
7323
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007324 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007325 if (1 != v) return -EINVAL;
7326
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307327 v = kstrtou32(buf, 10, &tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007328 if (v < 0) return -EINVAL;
7329
7330 switch (i)
7331 {
7332 case 0: /* Measurement token */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307333 if (!tempInt)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007334 {
7335 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307336 "Invalid Measurement Token: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007337 return -EINVAL;
7338 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007339 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007340 break;
7341
7342 case 1: /* Channel number */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307343 if ((!tempInt) ||
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007344 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7345 {
7346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307347 "Invalid Channel Number: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007348 return -EINVAL;
7349 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007350 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007351 break;
7352
7353 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08007354 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007355 {
7356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307357 "Invalid Scan Mode(%u) Expected{0|1|2}", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007358 return -EINVAL;
7359 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007360 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007361 break;
7362
7363 case 3: /* Measurement duration */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307364 if (((!tempInt) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
7365 ((pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007366 {
7367 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307368 "Invalid Measurement Duration: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007369 return -EINVAL;
7370 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007371 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007372 break;
7373 }
7374 }
7375 }
7376
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007377 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007378 {
7379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05307380 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007381 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007382 pEseBcnReq->bcnReq[j].measurementToken,
7383 pEseBcnReq->bcnReq[j].channel,
7384 pEseBcnReq->bcnReq[j].scanMode,
7385 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007386 }
7387
7388 return VOS_STATUS_SUCCESS;
7389}
7390
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307391struct tsm_priv {
7392 tAniTrafStrmMetrics tsm_metrics;
7393};
7394
7395static void hdd_get_tsm_stats_cb(tAniTrafStrmMetrics tsm_metrics,
7396 const tANI_U32 sta_id, void *context )
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007397{
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307398 struct hdd_request *request;
7399 struct tsm_priv *priv;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007400
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307401 ENTER();
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007402
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307403 request = hdd_request_get(context);
7404 if (!request) {
7405 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
7406 return;
7407 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007408
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307409 priv = hdd_request_priv(request);
7410 priv->tsm_metrics = tsm_metrics;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007411
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307412 hdd_request_complete(request);
7413 hdd_request_put(request);
Jeff Johnson72a40512013-12-19 10:14:15 -08007414
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307415 EXIT();
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007416}
7417
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007418static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
7419 tAniTrafStrmMetrics* pTsmMetrics)
7420{
7421 hdd_station_ctx_t *pHddStaCtx = NULL;
7422 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08007423 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007424 hdd_context_t *pHddCtx = NULL;
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307425 int ret;
7426 void *cookie;
7427 struct hdd_request *request;
7428 struct tsm_priv *priv;
7429 static const struct hdd_request_params params = {
7430 .priv_size = sizeof(*priv),
7431 .timeout_ms = WLAN_WAIT_TIME_STATS,
7432 };
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007433
7434 if (NULL == pAdapter)
7435 {
7436 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
7437 return VOS_STATUS_E_FAULT;
7438 }
7439
7440 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7441 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7442
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307443 request = hdd_request_alloc(&params);
7444 if (!request) {
7445 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
7446 return VOS_STATUS_E_NOMEM;
7447 }
7448 cookie = hdd_request_cookie(request);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007449
7450 /* query tsm stats */
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307451 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_get_tsm_stats_cb,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007452 pHddStaCtx->conn_info.staId[ 0 ],
7453 pHddStaCtx->conn_info.bssId,
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307454 cookie, pHddCtx->pvosContext, tid);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007455
7456 if (eHAL_STATUS_SUCCESS != hstatus)
7457 {
Jeff Johnson72a40512013-12-19 10:14:15 -08007458 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
7459 __func__);
7460 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007461 }
7462 else
7463 {
7464 /* request was sent -- wait for the response */
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307465 ret = hdd_request_wait_for_response(request);
7466 if (ret) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007467 hddLog(VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307468 "SME timeout while retrieving statistics");
Jeff Johnson72a40512013-12-19 10:14:15 -08007469 vstatus = VOS_STATUS_E_TIMEOUT;
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307470 } else {
7471 priv = hdd_request_priv(request);
7472 *pTsmMetrics = priv->tsm_metrics;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007473 }
7474 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007475
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307476 hdd_request_put(request);
Jeff Johnson72a40512013-12-19 10:14:15 -08007477
Jeff Johnson72a40512013-12-19 10:14:15 -08007478 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007479}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007480#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007481
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007482#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08007483void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
7484{
7485 eCsrBand band = -1;
7486 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
7487 switch (band)
7488 {
7489 case eCSR_BAND_ALL:
7490 *pBand = WLAN_HDD_UI_BAND_AUTO;
7491 break;
7492
7493 case eCSR_BAND_24:
7494 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
7495 break;
7496
7497 case eCSR_BAND_5G:
7498 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
7499 break;
7500
7501 default:
7502 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
7503 *pBand = -1;
7504 break;
7505 }
7506}
7507
7508/**---------------------------------------------------------------------------
7509
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007510 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
7511
7512 This function parses the send action frame data passed in the format
7513 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
7514
Srinivas Girigowda56076852013-08-20 14:00:50 -07007515 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007516 \param - pTargetApBssid Pointer to target Ap bssid
7517 \param - pChannel Pointer to the Target AP channel
7518 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
7519 \param - pBuf Pointer to data
7520 \param - pBufLen Pointer to data length
7521
7522 \return - 0 for success non-zero for failure
7523
7524 --------------------------------------------------------------------------*/
7525VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
7526 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
7527{
7528 tANI_U8 *inPtr = pValue;
7529 tANI_U8 *dataEnd;
7530 int tempInt;
7531 int j = 0;
7532 int i = 0;
7533 int v = 0;
7534 tANI_U8 tempBuf[32];
7535 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007536 /* 12 hexa decimal digits, 5 ':' and '\0' */
7537 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007538
7539 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7540 /*no argument after the command*/
7541 if (NULL == inPtr)
7542 {
7543 return -EINVAL;
7544 }
7545
7546 /*no space after the command*/
7547 else if (SPACE_ASCII_VALUE != *inPtr)
7548 {
7549 return -EINVAL;
7550 }
7551
7552 /*removing empty spaces*/
7553 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7554
7555 /*no argument followed by spaces*/
7556 if ('\0' == *inPtr)
7557 {
7558 return -EINVAL;
7559 }
7560
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007561 v = sscanf(inPtr, "%17s", macAddress);
7562 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007563 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7565 "Invalid MAC address or All hex inputs are not read (%d)", v);
7566 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007567 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007568
7569 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7570 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7571 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7572 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7573 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7574 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007575
7576 /* point to the next argument */
7577 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7578 /*no argument after the command*/
7579 if (NULL == inPtr) return -EINVAL;
7580
7581 /*removing empty spaces*/
7582 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7583
7584 /*no argument followed by spaces*/
7585 if ('\0' == *inPtr)
7586 {
7587 return -EINVAL;
7588 }
7589
7590 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007591 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007592 if (1 != v) return -EINVAL;
7593
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007594 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05307595 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05307596 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007597
7598 *pChannel = tempInt;
7599
7600 /* point to the next argument */
7601 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7602 /*no argument after the command*/
7603 if (NULL == inPtr) return -EINVAL;
7604 /*removing empty spaces*/
7605 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7606
7607 /*no argument followed by spaces*/
7608 if ('\0' == *inPtr)
7609 {
7610 return -EINVAL;
7611 }
7612
7613 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007614 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007615 if (1 != v) return -EINVAL;
7616
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007617 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08007618 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007619
7620 *pDwellTime = tempInt;
7621
7622 /* point to the next argument */
7623 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7624 /*no argument after the command*/
7625 if (NULL == inPtr) return -EINVAL;
7626 /*removing empty spaces*/
7627 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7628
7629 /*no argument followed by spaces*/
7630 if ('\0' == *inPtr)
7631 {
7632 return -EINVAL;
7633 }
7634
7635 /* find the length of data */
7636 dataEnd = inPtr;
7637 while(('\0' != *dataEnd) )
7638 {
7639 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007640 }
Kiet Lambe150c22013-11-21 16:30:32 +05307641 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007642 if ( *pBufLen <= 0) return -EINVAL;
7643
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07007644 /* Allocate the number of bytes based on the number of input characters
7645 whether it is even or odd.
7646 if the number of input characters are even, then we need N/2 byte.
7647 if the number of input characters are odd, then we need do (N+1)/2 to
7648 compensate rounding off.
7649 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7650 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7651 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007652 if (NULL == *pBuf)
7653 {
7654 hddLog(VOS_TRACE_LEVEL_FATAL,
7655 "%s: vos_mem_alloc failed ", __func__);
7656 return -EINVAL;
7657 }
7658
7659 /* the buffer received from the upper layer is character buffer,
7660 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7661 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7662 and f0 in 3rd location */
7663 for (i = 0, j = 0; j < *pBufLen; j += 2)
7664 {
Kiet Lambe150c22013-11-21 16:30:32 +05307665 if( j+1 == *pBufLen)
7666 {
7667 tempByte = hdd_parse_hex(inPtr[j]);
7668 }
7669 else
7670 {
7671 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
7672 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007673 (*pBuf)[i++] = tempByte;
7674 }
7675 *pBufLen = i;
7676 return VOS_STATUS_SUCCESS;
7677}
7678
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007679/**---------------------------------------------------------------------------
7680
Srinivas Girigowdade697412013-02-14 16:31:48 -08007681 \brief hdd_parse_channellist() - HDD Parse channel list
7682
7683 This function parses the channel list passed in the format
7684 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007685 if the Number of channels (N) does not match with the actual number of channels passed
7686 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
7687 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
7688 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
7689 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08007690
7691 \param - pValue Pointer to input channel list
7692 \param - ChannelList Pointer to local output array to record channel list
7693 \param - pNumChannels Pointer to number of roam scan channels
7694
7695 \return - 0 for success non-zero for failure
7696
7697 --------------------------------------------------------------------------*/
7698VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
7699{
7700 tANI_U8 *inPtr = pValue;
7701 int tempInt;
7702 int j = 0;
7703 int v = 0;
7704 char buf[32];
7705
7706 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7707 /*no argument after the command*/
7708 if (NULL == inPtr)
7709 {
7710 return -EINVAL;
7711 }
7712
7713 /*no space after the command*/
7714 else if (SPACE_ASCII_VALUE != *inPtr)
7715 {
7716 return -EINVAL;
7717 }
7718
7719 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007720 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08007721
7722 /*no argument followed by spaces*/
7723 if ('\0' == *inPtr)
7724 {
7725 return -EINVAL;
7726 }
7727
7728 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007729 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007730 if (1 != v) return -EINVAL;
7731
Srinivas Girigowdade697412013-02-14 16:31:48 -08007732 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007733 if ((v < 0) ||
7734 (tempInt <= 0) ||
7735 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
7736 {
7737 return -EINVAL;
7738 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007739
7740 *pNumChannels = tempInt;
7741
7742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7743 "Number of channels are: %d", *pNumChannels);
7744
7745 for (j = 0; j < (*pNumChannels); j++)
7746 {
7747 /*inPtr pointing to the beginning of first space after number of channels*/
7748 inPtr = strpbrk( inPtr, " " );
7749 /*no channel list after the number of channels argument*/
7750 if (NULL == inPtr)
7751 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007752 if (0 != j)
7753 {
7754 *pNumChannels = j;
7755 return VOS_STATUS_SUCCESS;
7756 }
7757 else
7758 {
7759 return -EINVAL;
7760 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007761 }
7762
7763 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007764 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08007765
7766 /*no channel list after the number of channels argument and spaces*/
7767 if ( '\0' == *inPtr )
7768 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007769 if (0 != j)
7770 {
7771 *pNumChannels = j;
7772 return VOS_STATUS_SUCCESS;
7773 }
7774 else
7775 {
7776 return -EINVAL;
7777 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007778 }
7779
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007780 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007781 if (1 != v) return -EINVAL;
7782
Srinivas Girigowdade697412013-02-14 16:31:48 -08007783 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007784 if ((v < 0) ||
7785 (tempInt <= 0) ||
7786 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7787 {
7788 return -EINVAL;
7789 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007790 pChannelList[j] = tempInt;
7791
7792 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7793 "Channel %d added to preferred channel list",
7794 pChannelList[j] );
7795 }
7796
Srinivas Girigowdade697412013-02-14 16:31:48 -08007797 return VOS_STATUS_SUCCESS;
7798}
7799
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007800
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05307801/**
7802 * hdd_parse_reassoc_command_v1_data() - HDD Parse reassoc command data
7803 * This function parses the reasoc command data passed in the format
7804 * REASSOC<space><bssid><space><channel>
7805 *
7806 * @pValue: Pointer to input data (its a NUL terminated string)
7807 * @pTargetApBssid: Pointer to target Ap bssid
7808 * @pChannel: Pointer to the Target AP channel
7809 *
7810 * Return: 0 for success non-zero for failure
7811 */
7812static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
7813 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007814{
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05307815 const tANI_U8 *inPtr = pValue;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007816 int tempInt;
7817 int v = 0;
7818 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08007819 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007820 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007821
7822 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7823 /*no argument after the command*/
7824 if (NULL == inPtr)
7825 {
7826 return -EINVAL;
7827 }
7828
7829 /*no space after the command*/
7830 else if (SPACE_ASCII_VALUE != *inPtr)
7831 {
7832 return -EINVAL;
7833 }
7834
7835 /*removing empty spaces*/
7836 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7837
7838 /*no argument followed by spaces*/
7839 if ('\0' == *inPtr)
7840 {
7841 return -EINVAL;
7842 }
7843
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007844 v = sscanf(inPtr, "%17s", macAddress);
7845 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007846 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7848 "Invalid MAC address or All hex inputs are not read (%d)", v);
7849 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007850 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007851
7852 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7853 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7854 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7855 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7856 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7857 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007858
7859 /* point to the next argument */
7860 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7861 /*no argument after the command*/
7862 if (NULL == inPtr) return -EINVAL;
7863
7864 /*removing empty spaces*/
7865 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7866
7867 /*no argument followed by spaces*/
7868 if ('\0' == *inPtr)
7869 {
7870 return -EINVAL;
7871 }
7872
7873 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007874 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007875 if (1 != v) return -EINVAL;
7876
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007877 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007878 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05307879 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007880 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7881 {
7882 return -EINVAL;
7883 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007884
7885 *pChannel = tempInt;
7886 return VOS_STATUS_SUCCESS;
7887}
7888
7889#endif
7890
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007891#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007892/**---------------------------------------------------------------------------
7893
7894 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
7895
7896 This function parses the SETCCKM IE command
7897 SETCCKMIE<space><ie data>
7898
7899 \param - pValue Pointer to input data
7900 \param - pCckmIe Pointer to output cckm Ie
7901 \param - pCckmIeLen Pointer to output cckm ie length
7902
7903 \return - 0 for success non-zero for failure
7904
7905 --------------------------------------------------------------------------*/
7906VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
7907 tANI_U8 *pCckmIeLen)
7908{
7909 tANI_U8 *inPtr = pValue;
7910 tANI_U8 *dataEnd;
7911 int j = 0;
7912 int i = 0;
7913 tANI_U8 tempByte = 0;
7914
7915 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7916 /*no argument after the command*/
7917 if (NULL == inPtr)
7918 {
7919 return -EINVAL;
7920 }
7921
7922 /*no space after the command*/
7923 else if (SPACE_ASCII_VALUE != *inPtr)
7924 {
7925 return -EINVAL;
7926 }
7927
7928 /*removing empty spaces*/
7929 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7930
7931 /*no argument followed by spaces*/
7932 if ('\0' == *inPtr)
7933 {
7934 return -EINVAL;
7935 }
7936
7937 /* find the length of data */
7938 dataEnd = inPtr;
7939 while(('\0' != *dataEnd) )
7940 {
7941 dataEnd++;
7942 ++(*pCckmIeLen);
7943 }
7944 if ( *pCckmIeLen <= 0) return -EINVAL;
7945
7946 /* Allocate the number of bytes based on the number of input characters
7947 whether it is even or odd.
7948 if the number of input characters are even, then we need N/2 byte.
7949 if the number of input characters are odd, then we need do (N+1)/2 to
7950 compensate rounding off.
7951 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7952 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7953 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
7954 if (NULL == *pCckmIe)
7955 {
7956 hddLog(VOS_TRACE_LEVEL_FATAL,
7957 "%s: vos_mem_alloc failed ", __func__);
7958 return -EINVAL;
7959 }
7960 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
7961 /* the buffer received from the upper layer is character buffer,
7962 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7963 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7964 and f0 in 3rd location */
7965 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
7966 {
7967 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
7968 (*pCckmIe)[i++] = tempByte;
7969 }
7970 *pCckmIeLen = i;
7971
7972 return VOS_STATUS_SUCCESS;
7973}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007974#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007975
Jeff Johnson295189b2012-06-20 16:38:30 -07007976/**---------------------------------------------------------------------------
7977
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007978 \brief hdd_is_valid_mac_address() - Validate MAC address
7979
7980 This function validates whether the given MAC address is valid or not
7981 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
7982 where X is the hexa decimal digit character and separated by ':'
7983 This algorithm works even if MAC address is not separated by ':'
7984
7985 This code checks given input string mac contains exactly 12 hexadecimal digits.
7986 and a separator colon : appears in the input string only after
7987 an even number of hex digits.
7988
7989 \param - pMacAddr pointer to the input MAC address
7990 \return - 1 for valid and 0 for invalid
7991
7992 --------------------------------------------------------------------------*/
7993
7994v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
7995{
7996 int xdigit = 0;
7997 int separator = 0;
7998 while (*pMacAddr)
7999 {
8000 if (isxdigit(*pMacAddr))
8001 {
8002 xdigit++;
8003 }
8004 else if (':' == *pMacAddr)
8005 {
8006 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
8007 break;
8008
8009 ++separator;
8010 }
8011 else
8012 {
8013 separator = -1;
8014 /* Invalid MAC found */
8015 return 0;
8016 }
8017 ++pMacAddr;
8018 }
8019 return (xdigit == 12 && (separator == 5 || separator == 0));
8020}
8021
8022/**---------------------------------------------------------------------------
8023
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308024 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07008025
8026 \param - dev Pointer to net_device structure
8027
8028 \return - 0 for success non-zero for failure
8029
8030 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308031int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008032{
8033 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8034 hdd_context_t *pHddCtx;
8035 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8036 VOS_STATUS status;
8037 v_BOOL_t in_standby = TRUE;
8038
8039 if (NULL == pAdapter)
8040 {
8041 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05308042 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008043 return -ENODEV;
8044 }
8045
8046 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308047 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
8048 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07008049 if (NULL == pHddCtx)
8050 {
8051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008052 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008053 return -ENODEV;
8054 }
8055
8056 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8057 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
8058 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008059 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
8060 {
8061 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308062 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008063 in_standby = FALSE;
8064 break;
8065 }
8066 else
8067 {
8068 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8069 pAdapterNode = pNext;
8070 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008071 }
8072
8073 if (TRUE == in_standby)
8074 {
8075 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
8076 {
8077 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
8078 "wlan out of power save", __func__);
8079 return -EINVAL;
8080 }
8081 }
8082
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008083 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07008084 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8085 {
8086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008087 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008088 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308089 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008090 netif_tx_start_all_queues(dev);
8091 }
8092
8093 return 0;
8094}
8095
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308096/**---------------------------------------------------------------------------
8097
8098 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
8099
8100 This is called in response to ifconfig up
8101
8102 \param - dev Pointer to net_device structure
8103
8104 \return - 0 for success non-zero for failure
8105
8106 --------------------------------------------------------------------------*/
8107int hdd_open(struct net_device *dev)
8108{
8109 int ret;
8110
8111 vos_ssr_protect(__func__);
8112 ret = __hdd_open(dev);
8113 vos_ssr_unprotect(__func__);
8114
8115 return ret;
8116}
8117
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308118int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008119{
8120 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308121 hdd_adapter_t *sta_adapter;
8122 hdd_context_t *hdd_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008123
8124 if(pAdapter == NULL) {
8125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008126 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008127 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008128 }
8129
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308130 if (vos_get_concurrency_mode() != VOS_STA_MON)
8131 return 0;
8132
8133 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8134 if (wlan_hdd_validate_context(hdd_ctx))
8135 return -EINVAL;
8136
8137 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
8138 if (!sta_adapter) {
8139 hddLog(LOGE, FL("No valid STA interface"));
8140 return -EINVAL;
8141 }
8142
8143 if (!test_bit(DEVICE_IFACE_OPENED, &sta_adapter->event_flags)) {
8144 hddLog(LOGE, FL("STA Interface is not OPENED"));
8145 return -EINVAL;
8146 }
8147
8148 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
8149
Jeff Johnson295189b2012-06-20 16:38:30 -07008150 return 0;
8151}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308152
8153int hdd_mon_open (struct net_device *dev)
8154{
8155 int ret;
8156
8157 vos_ssr_protect(__func__);
8158 ret = __hdd_mon_open(dev);
8159 vos_ssr_unprotect(__func__);
8160
8161 return ret;
8162}
8163
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308164int __hdd_mon_stop (struct net_device *dev)
8165{
8166 hdd_adapter_t *mon_adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8167 hdd_context_t *hdd_ctx;
8168
8169 if (vos_get_concurrency_mode() != VOS_STA_MON)
8170 return 0;
8171
8172 if(!mon_adapter) {
8173 hddLog(LOGE, FL("HDD adapter is Null"));
8174 return -EINVAL;
8175 }
8176
8177 hdd_ctx = WLAN_HDD_GET_CTX(mon_adapter);
8178 if (wlan_hdd_validate_context(hdd_ctx))
8179 return -EINVAL;
8180
8181 if (!test_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags)) {
8182 hddLog(LOGE, FL("NETDEV Interface is not OPENED"));
8183 return -ENODEV;
8184 }
8185
8186 clear_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags);
8187 hdd_stop_adapter(hdd_ctx, mon_adapter, VOS_FALSE);
8188
8189 return 0;
8190}
8191
Katya Nigame7b69a82015-04-28 15:24:06 +05308192int hdd_mon_stop(struct net_device *dev)
8193{
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308194 int ret;
8195
8196 vos_ssr_protect(__func__);
8197 ret = __hdd_mon_stop(dev);
8198 vos_ssr_unprotect(__func__);
8199
8200 return ret;
Katya Nigame7b69a82015-04-28 15:24:06 +05308201}
8202
Jeff Johnson295189b2012-06-20 16:38:30 -07008203/**---------------------------------------------------------------------------
8204
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308205 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07008206
8207 \param - dev Pointer to net_device structure
8208
8209 \return - 0 for success non-zero for failure
8210
8211 --------------------------------------------------------------------------*/
8212
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308213int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008214{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308215 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008216 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8217 hdd_context_t *pHddCtx;
8218 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8219 VOS_STATUS status;
8220 v_BOOL_t enter_standby = TRUE;
8221
8222 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008223 if (NULL == pAdapter)
8224 {
8225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05308226 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008227 return -ENODEV;
8228 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05308229 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308230 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308231
8232 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8233 ret = wlan_hdd_validate_context(pHddCtx);
8234 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07008235 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308236 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008237 }
8238
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308239 /* Nothing to be done if the interface is not opened */
8240 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
8241 {
8242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8243 "%s: NETDEV Interface is not OPENED", __func__);
8244 return -ENODEV;
8245 }
8246
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308247 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308248 /*
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05308249 * In STA + Monitor mode concurrency, no point in running
8250 * capture on monitor interface, when STA interface is stopped
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308251 */
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05308252 wlan_hdd_stop_mon(pHddCtx, true);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308253 }
8254
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308255 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008256 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07008257 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308258
8259 /* Disable TX on the interface, after this hard_start_xmit() will not
8260 * be called on that interface
8261 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308262 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008263 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308264
8265 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07008266 netif_carrier_off(pAdapter->dev);
8267
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308268 /* The interface is marked as down for outside world (aka kernel)
8269 * But the driver is pretty much alive inside. The driver needs to
8270 * tear down the existing connection on the netdev (session)
8271 * cleanup the data pipes and wait until the control plane is stabilized
8272 * for this interface. The call also needs to wait until the above
8273 * mentioned actions are completed before returning to the caller.
8274 * Notice that the hdd_stop_adapter is requested not to close the session
8275 * That is intentional to be able to scan if it is a STA/P2P interface
8276 */
8277 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308278#ifdef FEATURE_WLAN_TDLS
8279 mutex_lock(&pHddCtx->tdls_lock);
8280#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308281 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05308282 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308283#ifdef FEATURE_WLAN_TDLS
8284 mutex_unlock(&pHddCtx->tdls_lock);
8285#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008286 /* SoftAP ifaces should never go in power save mode
8287 making sure same here. */
8288 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07008289 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07008290 )
8291 {
8292 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8294 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008295 EXIT();
8296 return 0;
8297 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308298 /* Find if any iface is up. If any iface is up then can't put device to
8299 * sleep/power save mode
8300 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008301 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8302 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
8303 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008304 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
8305 {
8306 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308307 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008308 enter_standby = FALSE;
8309 break;
8310 }
8311 else
8312 {
8313 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8314 pAdapterNode = pNext;
8315 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008316 }
8317
8318 if (TRUE == enter_standby)
8319 {
8320 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
8321 "entering standby", __func__);
8322 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
8323 {
8324 /*log and return success*/
8325 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
8326 "wlan in power save", __func__);
8327 }
8328 }
Hanumanth Reddy Pothula972e1df2018-06-14 13:33:47 +05308329
8330 /*
8331 * Upon wifi turn off, DUT has to flush the scan results so if
8332 * this is the last cli iface, flush the scan database.
8333 */
8334 if (!hdd_is_cli_iface_up(pHddCtx))
8335 sme_ScanFlushResult(pHddCtx->hHal, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07008336
8337 EXIT();
8338 return 0;
8339}
8340
8341/**---------------------------------------------------------------------------
8342
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308343 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07008344
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308345 This is called in response to ifconfig down
8346
8347 \param - dev Pointer to net_device structure
8348
8349 \return - 0 for success non-zero for failure
8350-----------------------------------------------------------------------------*/
8351int hdd_stop (struct net_device *dev)
8352{
8353 int ret;
8354
8355 vos_ssr_protect(__func__);
8356 ret = __hdd_stop(dev);
8357 vos_ssr_unprotect(__func__);
8358
8359 return ret;
8360}
8361
8362/**---------------------------------------------------------------------------
8363
8364 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07008365
8366 \param - dev Pointer to net_device structure
8367
8368 \return - void
8369
8370 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308371static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008372{
8373 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308374 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008375 ENTER();
8376
8377 do
8378 {
8379 if (NULL == pAdapter)
8380 {
8381 hddLog(VOS_TRACE_LEVEL_FATAL,
8382 "%s: NULL pAdapter", __func__);
8383 break;
8384 }
8385
8386 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8387 {
8388 hddLog(VOS_TRACE_LEVEL_FATAL,
8389 "%s: Invalid magic", __func__);
8390 break;
8391 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308392 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8393 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07008394 {
8395 hddLog(VOS_TRACE_LEVEL_FATAL,
8396 "%s: NULL pHddCtx", __func__);
8397 break;
8398 }
8399
8400 if (dev != pAdapter->dev)
8401 {
8402 hddLog(VOS_TRACE_LEVEL_FATAL,
8403 "%s: Invalid device reference", __func__);
8404 /* we haven't validated all cases so let this go for now */
8405 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308406#ifdef FEATURE_WLAN_TDLS
8407 mutex_lock(&pHddCtx->tdls_lock);
8408#endif
c_hpothu002231a2015-02-05 14:58:51 +05308409 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308410#ifdef FEATURE_WLAN_TDLS
8411 mutex_unlock(&pHddCtx->tdls_lock);
8412#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008413
8414 /* after uninit our adapter structure will no longer be valid */
8415 pAdapter->dev = NULL;
8416 pAdapter->magic = 0;
Manjeet Singh47ee8472016-04-11 11:57:18 +05308417 pAdapter->pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008418 } while (0);
8419
8420 EXIT();
8421}
8422
8423/**---------------------------------------------------------------------------
8424
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308425 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
8426
8427 This is called during the netdev unregister to uninitialize all data
8428associated with the device
8429
8430 \param - dev Pointer to net_device structure
8431
8432 \return - void
8433
8434 --------------------------------------------------------------------------*/
8435static void hdd_uninit (struct net_device *dev)
8436{
8437 vos_ssr_protect(__func__);
8438 __hdd_uninit(dev);
8439 vos_ssr_unprotect(__func__);
8440}
8441
8442/**---------------------------------------------------------------------------
8443
Jeff Johnson295189b2012-06-20 16:38:30 -07008444 \brief hdd_release_firmware() -
8445
8446 This function calls the release firmware API to free the firmware buffer.
8447
8448 \param - pFileName Pointer to the File Name.
8449 pCtx - Pointer to the adapter .
8450
8451
8452 \return - 0 for success, non zero for failure
8453
8454 --------------------------------------------------------------------------*/
8455
8456VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
8457{
8458 VOS_STATUS status = VOS_STATUS_SUCCESS;
8459 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8460 ENTER();
8461
8462
8463 if (!strcmp(WLAN_FW_FILE, pFileName)) {
8464
8465 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
8466
8467 if(pHddCtx->fw) {
8468 release_firmware(pHddCtx->fw);
8469 pHddCtx->fw = NULL;
8470 }
8471 else
8472 status = VOS_STATUS_E_FAILURE;
8473 }
8474 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
8475 if(pHddCtx->nv) {
8476 release_firmware(pHddCtx->nv);
8477 pHddCtx->nv = NULL;
8478 }
8479 else
8480 status = VOS_STATUS_E_FAILURE;
8481
8482 }
8483
8484 EXIT();
8485 return status;
8486}
8487
8488/**---------------------------------------------------------------------------
8489
8490 \brief hdd_request_firmware() -
8491
8492 This function reads the firmware file using the request firmware
8493 API and returns the the firmware data and the firmware file size.
8494
8495 \param - pfileName - Pointer to the file name.
8496 - pCtx - Pointer to the adapter .
8497 - ppfw_data - Pointer to the pointer of the firmware data.
8498 - pSize - Pointer to the file size.
8499
8500 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
8501
8502 --------------------------------------------------------------------------*/
8503
8504
8505VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
8506{
8507 int status;
8508 VOS_STATUS retval = VOS_STATUS_SUCCESS;
8509 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8510 ENTER();
8511
8512 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
8513
8514 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
8515
8516 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8517 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
8518 __func__, pfileName);
8519 retval = VOS_STATUS_E_FAILURE;
8520 }
8521
8522 else {
8523 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
8524 *pSize = pHddCtx->fw->size;
8525 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
8526 __func__, *pSize);
8527 }
8528 }
8529 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
8530
8531 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
8532
8533 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
8534 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
8535 __func__, pfileName);
8536 retval = VOS_STATUS_E_FAILURE;
8537 }
8538
8539 else {
8540 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
8541 *pSize = pHddCtx->nv->size;
8542 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
8543 __func__, *pSize);
8544 }
8545 }
8546
8547 EXIT();
8548 return retval;
8549}
8550/**---------------------------------------------------------------------------
8551 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
8552
8553 This is the function invoked by SME to inform the result of a full power
8554 request issued by HDD
8555
8556 \param - callbackcontext - Pointer to cookie
8557 status - result of request
8558
8559 \return - None
8560
8561--------------------------------------------------------------------------*/
8562void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
8563{
8564 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
8565
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008566 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008567 if(&pHddCtx->full_pwr_comp_var)
8568 {
8569 complete(&pHddCtx->full_pwr_comp_var);
8570 }
8571}
8572
Abhishek Singh00b71972016-01-07 10:51:04 +05308573#ifdef WLAN_FEATURE_RMC
8574static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo)
8575{
8576 int payload_len;
8577 struct sk_buff *skb;
8578 struct nlmsghdr *nlh;
8579 v_U8_t *data;
8580
8581 payload_len = ETH_ALEN;
8582
8583 if (0 == cesium_pid)
8584 {
8585 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: cesium process not registered",
8586 __func__);
8587 return;
8588 }
8589
8590 if ((skb = nlmsg_new(payload_len,GFP_ATOMIC)) == NULL)
8591 {
8592 hddLog(VOS_TRACE_LEVEL_ERROR,
8593 "%s: nlmsg_new() failed for msg size[%d]",
8594 __func__, NLMSG_SPACE(payload_len));
8595 return;
8596 }
8597
8598 nlh = nlmsg_put(skb, cesium_pid, seqNo, 0, payload_len, NLM_F_REQUEST);
8599
8600 if (NULL == nlh)
8601 {
8602 hddLog(VOS_TRACE_LEVEL_ERROR,
8603 "%s: nlmsg_put() failed for msg size[%d]",
8604 __func__, NLMSG_SPACE(payload_len));
8605
8606 kfree_skb(skb);
8607 return;
8608 }
8609
8610 data = nlmsg_data(nlh);
8611 memcpy(data, MacAddr, ETH_ALEN);
8612
8613 if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0)
8614 {
8615 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_unicast() failed for msg size[%d]",
8616 __func__, NLMSG_SPACE(payload_len));
8617 }
8618
8619 return;
8620}
8621
8622/**---------------------------------------------------------------------------
8623 \brief hdd_ParseuserParams - return a pointer to the next argument
8624
8625 \return - status
8626
8627--------------------------------------------------------------------------*/
8628static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg)
8629{
8630 tANI_U8 *pVal;
8631
8632 pVal = strchr(pValue, ' ');
8633
8634 if (NULL == pVal)
8635 {
8636 /* no argument remains */
8637 return -EINVAL;
8638 }
8639 else if (SPACE_ASCII_VALUE != *pVal)
8640 {
8641 /* no space after the current argument */
8642 return -EINVAL;
8643 }
8644
8645 pVal++;
8646
8647 /* remove empty spaces */
8648 while ((SPACE_ASCII_VALUE == *pVal) && ('\0' != *pVal))
8649 {
8650 pVal++;
8651 }
8652
8653 /* no argument followed by spaces */
8654 if ('\0' == *pVal)
8655 {
8656 return -EINVAL;
8657 }
8658
8659 *ppArg = pVal;
8660
8661 return 0;
8662}
8663
8664/**----------------------------------------------------------------------------
8665 \brief hdd_ParseIBSSTXFailEventParams - Parse params for SETIBSSTXFAILEVENT
8666
8667 \return - status
8668
8669------------------------------------------------------------------------------*/
8670static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
8671 tANI_U8 *tx_fail_count,
8672 tANI_U16 *pid)
8673{
8674 tANI_U8 *param = NULL;
8675 int ret;
8676
8677 ret = hdd_ParseUserParams(pValue, &param);
8678
8679 if (0 == ret && NULL != param)
8680 {
8681 if (1 != sscanf(param, "%hhu", tx_fail_count))
8682 {
8683 ret = -EINVAL;
8684 goto done;
8685 }
8686 }
8687 else
8688 {
8689 goto done;
8690 }
8691
8692 if (0 == *tx_fail_count)
8693 {
8694 *pid = 0;
8695 goto done;
8696 }
8697
8698 pValue = param;
8699 pValue++;
8700
8701 ret = hdd_ParseUserParams(pValue, &param);
8702
8703 if (0 == ret)
8704 {
8705 if (1 != sscanf(param, "%hu", pid))
8706 {
8707 ret = -EINVAL;
8708 goto done;
8709 }
8710 }
8711 else
8712 {
8713 goto done;
8714 }
8715
8716done:
8717 return ret;
8718}
8719
8720static int hdd_open_cesium_nl_sock()
8721{
8722#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8723 struct netlink_kernel_cfg cfg = {
8724 .groups = WLAN_NLINK_MCAST_GRP_ID,
8725 .input = NULL
8726 };
8727#endif
8728 int ret = 0;
8729
8730#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8731 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
8732#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
8733 THIS_MODULE,
8734#endif
8735 &cfg);
8736#else
8737 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
8738 WLAN_NLINK_MCAST_GRP_ID, NULL, NULL, THIS_MODULE);
8739#endif
8740
8741 if (cesium_nl_srv_sock == NULL)
8742 {
8743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8744 "NLINK: cesium netlink_kernel_create failed");
8745 ret = -ECONNREFUSED;
8746 }
8747
8748 return ret;
8749}
8750
8751static void hdd_close_cesium_nl_sock()
8752{
8753 if (NULL != cesium_nl_srv_sock)
8754 {
8755 netlink_kernel_release(cesium_nl_srv_sock);
8756 cesium_nl_srv_sock = NULL;
8757 }
8758}
8759#endif /* WLAN_FEATURE_RMC */
Jeff Johnson295189b2012-06-20 16:38:30 -07008760/**---------------------------------------------------------------------------
8761
8762 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
8763
8764 This is the function invoked by SME to inform the result of BMPS
8765 request issued by HDD
8766
8767 \param - callbackcontext - Pointer to cookie
8768 status - result of request
8769
8770 \return - None
8771
8772--------------------------------------------------------------------------*/
8773void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
8774{
8775
8776 struct completion *completion_var = (struct completion*) callbackContext;
8777
Arif Hussain6d2a3322013-11-17 19:50:10 -08008778 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008779 if(completion_var != NULL)
8780 {
8781 complete(completion_var);
8782 }
8783}
8784
8785/**---------------------------------------------------------------------------
8786
8787 \brief hdd_get_cfg_file_size() -
8788
8789 This function reads the configuration file using the request firmware
8790 API and returns the configuration file size.
8791
8792 \param - pCtx - Pointer to the adapter .
8793 - pFileName - Pointer to the file name.
8794 - pBufSize - Pointer to the buffer size.
8795
8796 \return - 0 for success, non zero for failure
8797
8798 --------------------------------------------------------------------------*/
8799
8800VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
8801{
8802 int status;
8803 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8804
8805 ENTER();
8806
8807 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
8808
8809 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8810 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
8811 status = VOS_STATUS_E_FAILURE;
8812 }
8813 else {
8814 *pBufSize = pHddCtx->fw->size;
8815 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
8816 release_firmware(pHddCtx->fw);
8817 pHddCtx->fw = NULL;
8818 }
8819
8820 EXIT();
8821 return VOS_STATUS_SUCCESS;
8822}
8823
8824/**---------------------------------------------------------------------------
8825
8826 \brief hdd_read_cfg_file() -
8827
8828 This function reads the configuration file using the request firmware
8829 API and returns the cfg data and the buffer size of the configuration file.
8830
8831 \param - pCtx - Pointer to the adapter .
8832 - pFileName - Pointer to the file name.
8833 - pBuffer - Pointer to the data buffer.
8834 - pBufSize - Pointer to the buffer size.
8835
8836 \return - 0 for success, non zero for failure
8837
8838 --------------------------------------------------------------------------*/
8839
8840VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
8841 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
8842{
8843 int status;
8844 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8845
8846 ENTER();
8847
8848 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
8849
8850 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8851 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
8852 return VOS_STATUS_E_FAILURE;
8853 }
8854 else {
8855 if(*pBufSize != pHddCtx->fw->size) {
8856 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
8857 "file size", __func__);
8858 release_firmware(pHddCtx->fw);
8859 pHddCtx->fw = NULL;
8860 return VOS_STATUS_E_FAILURE;
8861 }
8862 else {
8863 if(pBuffer) {
8864 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
8865 }
8866 release_firmware(pHddCtx->fw);
8867 pHddCtx->fw = NULL;
8868 }
8869 }
8870
8871 EXIT();
8872
8873 return VOS_STATUS_SUCCESS;
8874}
8875
8876/**---------------------------------------------------------------------------
8877
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308878 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008879
8880 This function sets the user specified mac address using
8881 the command ifconfig wlanX hw ether <mac adress>.
8882
8883 \param - dev - Pointer to the net device.
8884 - addr - Pointer to the sockaddr.
8885 \return - 0 for success, non zero for failure
8886
8887 --------------------------------------------------------------------------*/
8888
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308889static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07008890{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308891 hdd_adapter_t *pAdapter;
8892 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008893 struct sockaddr *psta_mac_addr = addr;
8894 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308895 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008896
8897 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308898 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8899 if (NULL == pAdapter)
8900 {
8901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8902 "%s: Adapter is NULL",__func__);
8903 return -EINVAL;
8904 }
8905 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8906 ret = wlan_hdd_validate_context(pHddCtx);
8907 if (0 != ret)
8908 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308909 return ret;
8910 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008911
8912 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07008913 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
8914
8915 EXIT();
8916 return halStatus;
8917}
8918
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308919/**---------------------------------------------------------------------------
8920
8921 \brief hdd_set_mac_address() -
8922
8923 Wrapper function to protect __hdd_set_mac_address() function from ssr
8924
8925 \param - dev - Pointer to the net device.
8926 - addr - Pointer to the sockaddr.
8927 \return - 0 for success, non zero for failure
8928
8929 --------------------------------------------------------------------------*/
8930static int hdd_set_mac_address(struct net_device *dev, void *addr)
8931{
8932 int ret;
8933
8934 vos_ssr_protect(__func__);
8935 ret = __hdd_set_mac_address(dev, addr);
8936 vos_ssr_unprotect(__func__);
8937
8938 return ret;
8939}
8940
Jeff Johnson295189b2012-06-20 16:38:30 -07008941tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
8942{
8943 int i;
8944 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8945 {
Abhishek Singheb183782014-02-06 13:37:21 +05308946 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008947 break;
8948 }
8949
8950 if( VOS_MAX_CONCURRENCY_PERSONA == i)
8951 return NULL;
8952
8953 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
8954 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
8955}
8956
8957void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
8958{
8959 int i;
8960 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8961 {
8962 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
8963 {
8964 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
8965 break;
8966 }
8967 }
8968 return;
8969}
8970
8971#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
8972 static struct net_device_ops wlan_drv_ops = {
8973 .ndo_open = hdd_open,
8974 .ndo_stop = hdd_stop,
8975 .ndo_uninit = hdd_uninit,
8976 .ndo_start_xmit = hdd_hard_start_xmit,
8977 .ndo_tx_timeout = hdd_tx_timeout,
8978 .ndo_get_stats = hdd_stats,
8979 .ndo_do_ioctl = hdd_ioctl,
8980 .ndo_set_mac_address = hdd_set_mac_address,
8981 .ndo_select_queue = hdd_select_queue,
8982#ifdef WLAN_FEATURE_PACKET_FILTERING
8983#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
8984 .ndo_set_rx_mode = hdd_set_multicast_list,
8985#else
8986 .ndo_set_multicast_list = hdd_set_multicast_list,
8987#endif //LINUX_VERSION_CODE
8988#endif
8989 };
Jeff Johnson295189b2012-06-20 16:38:30 -07008990 static struct net_device_ops wlan_mon_drv_ops = {
8991 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05308992 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07008993 .ndo_uninit = hdd_uninit,
8994 .ndo_start_xmit = hdd_mon_hard_start_xmit,
8995 .ndo_tx_timeout = hdd_tx_timeout,
8996 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05308997 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07008998 .ndo_set_mac_address = hdd_set_mac_address,
8999 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05309000
Jeff Johnson295189b2012-06-20 16:38:30 -07009001#endif
9002
9003void hdd_set_station_ops( struct net_device *pWlanDev )
9004{
9005#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07009006 pWlanDev->netdev_ops = &wlan_drv_ops;
9007#else
9008 pWlanDev->open = hdd_open;
9009 pWlanDev->stop = hdd_stop;
9010 pWlanDev->uninit = hdd_uninit;
9011 pWlanDev->hard_start_xmit = NULL;
9012 pWlanDev->tx_timeout = hdd_tx_timeout;
9013 pWlanDev->get_stats = hdd_stats;
9014 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07009015 pWlanDev->set_mac_address = hdd_set_mac_address;
9016#endif
9017}
9018
Katya Nigam1fd24402015-02-16 14:52:19 +05309019void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
9020{
9021 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
9022 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
9023 #else
9024 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
9025 #endif
9026}
9027
Jeff Johnsoneed415b2013-01-18 16:11:20 -08009028static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07009029{
9030 struct net_device *pWlanDev = NULL;
9031 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009032 /*
9033 * cfg80211 initialization and registration....
9034 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05309035 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
9036#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
9037 NET_NAME_UNKNOWN,
9038#endif
9039 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07009040 if(pWlanDev != NULL)
9041 {
9042
9043 //Save the pointer to the net_device in the HDD adapter
9044 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
9045
Jeff Johnson295189b2012-06-20 16:38:30 -07009046 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
9047
9048 pAdapter->dev = pWlanDev;
9049 pAdapter->pHddCtx = pHddCtx;
9050 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05309051 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07009052
Rajeev79dbe4c2013-10-05 11:03:42 +05309053#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05309054 pAdapter->pBatchScanRsp = NULL;
9055 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07009056 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08009057 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05309058 mutex_init(&pAdapter->hdd_batch_scan_lock);
9059#endif
9060
Jeff Johnson295189b2012-06-20 16:38:30 -07009061 pAdapter->isLinkUpSvcNeeded = FALSE;
9062 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
9063 //Init the net_device structure
9064 strlcpy(pWlanDev->name, name, IFNAMSIZ);
9065
9066 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
9067 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
9068 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
Alok Kumar84458542018-05-14 15:03:08 +05309069
9070 pWlanDev->needed_headroom = LIBRA_HW_NEEDED_HEADROOM;
Jeff Johnson295189b2012-06-20 16:38:30 -07009071
9072 hdd_set_station_ops( pAdapter->dev );
9073
9074 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009075 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
9076 pAdapter->wdev.wiphy = pHddCtx->wiphy;
9077 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009078 /* set pWlanDev's parent to underlying device */
9079 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07009080
9081 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009082 }
9083
9084 return pAdapter;
9085}
9086
9087VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
9088{
9089 struct net_device *pWlanDev = pAdapter->dev;
9090 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
9091 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9092 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
9093
9094 if( rtnl_lock_held )
9095 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08009096 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07009097 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
9098 {
9099 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
9100 return VOS_STATUS_E_FAILURE;
9101 }
9102 }
9103 if (register_netdevice(pWlanDev))
9104 {
9105 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
9106 return VOS_STATUS_E_FAILURE;
9107 }
9108 }
9109 else
9110 {
9111 if(register_netdev(pWlanDev))
9112 {
9113 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
9114 return VOS_STATUS_E_FAILURE;
9115 }
9116 }
9117 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
9118
9119 return VOS_STATUS_SUCCESS;
9120}
9121
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009122static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07009123{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009124 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009125
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009126 if (NULL == pAdapter)
9127 {
9128 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
9129 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07009130 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009131
9132 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
9133 {
9134 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
9135 return eHAL_STATUS_NOT_INITIALIZED;
9136 }
9137
9138 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
9139
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009140#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009141 /* need to make sure all of our scheduled work has completed.
9142 * This callback is called from MC thread context, so it is safe to
9143 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009144 *
9145 * Even though this is called from MC thread context, if there is a faulty
9146 * work item in the system, that can hang this call forever. So flushing
9147 * this global work queue is not safe; and now we make sure that
9148 * individual work queues are stopped correctly. But the cancel work queue
9149 * is a GPL only API, so the proprietary version of the driver would still
9150 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009151 */
9152 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009153#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009154
9155 /* We can be blocked while waiting for scheduled work to be
9156 * flushed, and the adapter structure can potentially be freed, in
9157 * which case the magic will have been reset. So make sure the
9158 * magic is still good, and hence the adapter structure is still
9159 * valid, before signaling completion */
9160 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
9161 {
9162 complete(&pAdapter->session_close_comp_var);
9163 }
9164
Jeff Johnson295189b2012-06-20 16:38:30 -07009165 return eHAL_STATUS_SUCCESS;
9166}
Manjeet Singh47ee8472016-04-11 11:57:18 +05309167/**
9168 * hdd_close_tx_queues() - close tx queues
9169 * @hdd_ctx: hdd global context
9170 *
9171 * Return: None
9172 */
9173static void hdd_close_tx_queues(hdd_context_t *hdd_ctx)
9174{
9175 VOS_STATUS status;
9176 hdd_adapter_t *adapter;
9177 hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter = NULL;
9178 /* Not validating hdd_ctx as it's already done by the caller */
9179 ENTER();
9180 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
9181 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
9182 adapter = adapter_node->pAdapter;
9183 if (adapter && adapter->dev) {
9184 netif_tx_disable (adapter->dev);
9185 netif_carrier_off(adapter->dev);
9186 }
9187 status = hdd_get_next_adapter(hdd_ctx, adapter_node,
9188 &next_adapter);
9189 adapter_node = next_adapter;
9190 }
9191 EXIT();
9192}
Jeff Johnson295189b2012-06-20 16:38:30 -07009193
9194VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
9195{
9196 struct net_device *pWlanDev = pAdapter->dev;
9197 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
9198 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9199 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
9200 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309201 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009202
Nirav Shah7e3c8132015-06-22 23:51:42 +05309203 spin_lock_init( &pAdapter->sta_hash_lock);
9204 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
9205
Jeff Johnson295189b2012-06-20 16:38:30 -07009206 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07009207 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009208 //Open a SME session for future operation
9209 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07009210 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009211 if ( !HAL_STATUS_SUCCESS( halStatus ) )
9212 {
9213 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009214 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009215 halStatus, halStatus );
9216 status = VOS_STATUS_E_FAILURE;
9217 goto error_sme_open;
9218 }
9219
9220 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05309221 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009222 &pAdapter->session_open_comp_var,
9223 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309224 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009225 {
9226 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309227 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07009228 status = VOS_STATUS_E_FAILURE;
9229 goto error_sme_open;
9230 }
9231
9232 // Register wireless extensions
9233 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
9234 {
9235 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009236 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009237 halStatus, halStatus );
9238 status = VOS_STATUS_E_FAILURE;
9239 goto error_register_wext;
9240 }
Katya Nigam1fd24402015-02-16 14:52:19 +05309241
Jeff Johnson295189b2012-06-20 16:38:30 -07009242 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05309243 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
9244 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
9245 #else
9246 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
9247 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009248
9249 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05309250 hddLog(VOS_TRACE_LEVEL_INFO,
9251 "%s: Set HDD connState to eConnectionState_NotConnected",
9252 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009253 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
9254
9255 //Set the default operation channel
9256 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
9257
9258 /* Make the default Auth Type as OPEN*/
9259 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9260
9261 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
9262 {
9263 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009264 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009265 status, status );
9266 goto error_init_txrx;
9267 }
9268
9269 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9270
9271 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
9272 {
9273 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009274 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009275 status, status );
9276 goto error_wmm_init;
9277 }
9278
9279 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9280
9281 return VOS_STATUS_SUCCESS;
9282
9283error_wmm_init:
9284 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9285 hdd_deinit_tx_rx(pAdapter);
9286error_init_txrx:
9287 hdd_UnregisterWext(pWlanDev);
9288error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009289 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009290 {
9291 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009292 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05309293 pAdapter->sessionId, FALSE, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009294 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07009295 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309296 unsigned long rc;
9297
Jeff Johnson295189b2012-06-20 16:38:30 -07009298 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309299 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009300 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009301 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309302 if (rc <= 0)
9303 hddLog(VOS_TRACE_LEVEL_ERROR,
9304 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009305 }
9306}
9307error_sme_open:
9308 return status;
9309}
9310
Jeff Johnson295189b2012-06-20 16:38:30 -07009311void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
9312{
9313 hdd_cfg80211_state_t *cfgState;
9314
9315 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
9316
9317 if( NULL != cfgState->buf )
9318 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309319 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07009320 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
9321 rc = wait_for_completion_interruptible_timeout(
9322 &pAdapter->tx_action_cnf_event,
9323 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309324 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009325 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05309326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9327 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
9328 , __func__, rc);
9329
9330 // Inform tx status as FAILURE to upper layer and free cfgState->buf
9331 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009332 }
9333 }
9334 return;
9335}
Jeff Johnson295189b2012-06-20 16:38:30 -07009336
c_hpothu002231a2015-02-05 14:58:51 +05309337void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07009338{
9339 ENTER();
9340 switch ( pAdapter->device_mode )
9341 {
Katya Nigam1fd24402015-02-16 14:52:19 +05309342 case WLAN_HDD_IBSS:
9343 {
9344 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9345 {
9346 hdd_ibss_deinit_tx_rx( pAdapter );
9347 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9348 }
9349 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009350 case WLAN_HDD_INFRA_STATION:
9351 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009352 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009353 {
9354 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9355 {
9356 hdd_deinit_tx_rx( pAdapter );
9357 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9358 }
9359
9360 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9361 {
9362 hdd_wmm_adapter_close( pAdapter );
9363 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9364 }
9365
Jeff Johnson295189b2012-06-20 16:38:30 -07009366 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009367 break;
9368 }
9369
9370 case WLAN_HDD_SOFTAP:
9371 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009372 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05309373
9374 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9375 {
9376 hdd_wmm_adapter_close( pAdapter );
9377 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9378 }
9379
Jeff Johnson295189b2012-06-20 16:38:30 -07009380 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009381
c_hpothu002231a2015-02-05 14:58:51 +05309382 hdd_unregister_hostapd(pAdapter, rtnl_held);
Agrawal Ashisha0584d42016-09-29 13:03:45 +05309383 /* set con_mode to STA only when no SAP concurrency mode */
9384 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
9385 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07009386 break;
9387 }
9388
9389 case WLAN_HDD_MONITOR:
9390 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009391 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9392 {
9393 hdd_deinit_tx_rx( pAdapter );
9394 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9395 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009396 break;
9397 }
9398
9399
9400 default:
9401 break;
9402 }
9403
9404 EXIT();
9405}
9406
9407void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
9408{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08009409 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309410
9411 ENTER();
9412 if (NULL == pAdapter)
9413 {
9414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9415 "%s: HDD adapter is Null", __func__);
9416 return;
9417 }
9418
9419 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009420
Rajeev79dbe4c2013-10-05 11:03:42 +05309421#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309422 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
9423 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08009424 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309425 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
9426 )
9427 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08009428 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05309429 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08009430 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
9431 {
9432 hdd_deinit_batch_scan(pAdapter);
9433 }
Rajeev79dbe4c2013-10-05 11:03:42 +05309434 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08009435 }
Rajeev79dbe4c2013-10-05 11:03:42 +05309436#endif
9437
Jeff Johnson295189b2012-06-20 16:38:30 -07009438 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
9439 if( rtnl_held )
9440 {
9441 unregister_netdevice(pWlanDev);
9442 }
9443 else
9444 {
9445 unregister_netdev(pWlanDev);
9446 }
9447 // note that the pAdapter is no longer valid at this point
9448 // since the memory has been reclaimed
9449 }
9450
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309451 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009452}
9453
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009454void hdd_set_pwrparams(hdd_context_t *pHddCtx)
9455{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309456 VOS_STATUS status;
9457 hdd_adapter_t *pAdapter = NULL;
9458 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009459
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309460 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009461
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309462 /*loop through all adapters.*/
9463 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009464 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309465 pAdapter = pAdapterNode->pAdapter;
9466 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
9467 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009468
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309469 { // we skip this registration for modes other than STA and P2P client modes.
9470 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9471 pAdapterNode = pNext;
9472 continue;
9473 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009474
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309475 //Apply Dynamic DTIM For P2P
9476 //Only if ignoreDynamicDtimInP2pMode is not set in ini
9477 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
9478 pHddCtx->cfg_ini->enableModulatedDTIM) &&
9479 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9480 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
9481 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
9482 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
9483 (eConnectionState_Associated ==
9484 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
9485 (pHddCtx->cfg_ini->fIsBmpsEnabled))
9486 {
9487 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009488
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309489 powerRequest.uIgnoreDTIM = 1;
9490 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
9491
9492 if (pHddCtx->cfg_ini->enableModulatedDTIM)
9493 {
9494 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
9495 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
9496 }
9497 else
9498 {
9499 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
9500 }
9501
9502 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
9503 * specified during Enter/Exit BMPS when LCD off*/
9504 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
9505 NULL, eANI_BOOLEAN_FALSE);
9506 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
9507 NULL, eANI_BOOLEAN_FALSE);
9508
9509 /* switch to the DTIM specified in cfg.ini */
9510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05309511 "Switch to DTIM %d Listen interval %d",
9512 powerRequest.uDTIMPeriod,
9513 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309514 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
9515 break;
9516
9517 }
9518
9519 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9520 pAdapterNode = pNext;
9521 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009522}
9523
9524void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
9525{
9526 /*Switch back to DTIM 1*/
9527 tSirSetPowerParamsReq powerRequest = { 0 };
9528
9529 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
9530 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07009531 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009532
9533 /* Update ignoreDTIM and ListedInterval in CFG with default values */
9534 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
9535 NULL, eANI_BOOLEAN_FALSE);
9536 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
9537 NULL, eANI_BOOLEAN_FALSE);
9538
9539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9540 "Switch to DTIM%d",powerRequest.uListenInterval);
9541 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
9542
9543}
9544
Jeff Johnson295189b2012-06-20 16:38:30 -07009545VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
9546{
9547 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05309548 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
9549 {
9550 hddLog( LOGE, FL("Wlan Unload in progress"));
9551 return VOS_STATUS_E_PERM;
9552 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309553
9554 if (wlan_hdd_check_monitor_state(pHddCtx)) {
9555 hddLog(LOG1, FL("Monitor mode is started, cannot enable BMPS"));
9556 return VOS_STATUS_SUCCESS;
9557 }
9558
Jeff Johnson295189b2012-06-20 16:38:30 -07009559 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
9560 {
9561 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
9562 }
9563
9564 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
9565 {
9566 sme_StartAutoBmpsTimer(pHddCtx->hHal);
9567 }
9568
9569 if (pHddCtx->cfg_ini->fIsImpsEnabled)
9570 {
9571 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
9572 }
9573
9574 return status;
9575}
9576
9577VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
9578{
9579 hdd_adapter_t *pAdapter = NULL;
9580 eHalStatus halStatus;
9581 VOS_STATUS status = VOS_STATUS_E_INVAL;
9582 v_BOOL_t disableBmps = FALSE;
9583 v_BOOL_t disableImps = FALSE;
9584
9585 switch(session_type)
9586 {
9587 case WLAN_HDD_INFRA_STATION:
9588 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07009589 case WLAN_HDD_P2P_CLIENT:
9590 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009591 //Exit BMPS -> Is Sta/P2P Client is already connected
9592 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
9593 if((NULL != pAdapter)&&
9594 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9595 {
9596 disableBmps = TRUE;
9597 }
9598
9599 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
9600 if((NULL != pAdapter)&&
9601 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9602 {
9603 disableBmps = TRUE;
9604 }
9605
9606 //Exit both Bmps and Imps incase of Go/SAP Mode
9607 if((WLAN_HDD_SOFTAP == session_type) ||
9608 (WLAN_HDD_P2P_GO == session_type))
9609 {
9610 disableBmps = TRUE;
9611 disableImps = TRUE;
9612 }
9613
9614 if(TRUE == disableImps)
9615 {
9616 if (pHddCtx->cfg_ini->fIsImpsEnabled)
9617 {
9618 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
9619 }
9620 }
9621
9622 if(TRUE == disableBmps)
9623 {
9624 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
9625 {
9626 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
9627
9628 if(eHAL_STATUS_SUCCESS != halStatus)
9629 {
9630 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009631 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009632 VOS_ASSERT(0);
9633 return status;
9634 }
9635 }
9636
9637 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
9638 {
9639 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
9640
9641 if(eHAL_STATUS_SUCCESS != halStatus)
9642 {
9643 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009644 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009645 VOS_ASSERT(0);
9646 return status;
9647 }
9648 }
9649 }
9650
9651 if((TRUE == disableBmps) ||
9652 (TRUE == disableImps))
9653 {
9654 /* Now, get the chip into Full Power now */
9655 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
9656 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
9657 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
9658
9659 if(halStatus != eHAL_STATUS_SUCCESS)
9660 {
9661 if(halStatus == eHAL_STATUS_PMC_PENDING)
9662 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309663 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009664 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309665 ret = wait_for_completion_interruptible_timeout(
9666 &pHddCtx->full_pwr_comp_var,
9667 msecs_to_jiffies(1000));
9668 if (ret <= 0)
9669 {
9670 hddLog(VOS_TRACE_LEVEL_ERROR,
9671 "%s: wait on full_pwr_comp_var failed %ld",
9672 __func__, ret);
9673 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009674 }
9675 else
9676 {
9677 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009678 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009679 VOS_ASSERT(0);
9680 return status;
9681 }
9682 }
9683
9684 status = VOS_STATUS_SUCCESS;
9685 }
9686
9687 break;
9688 }
9689 return status;
9690}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309691
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309692void hdd_mon_post_msg_cb(void *context)
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309693{
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309694 struct hdd_request *request;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309695
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309696 request = hdd_request_get(context);
9697 if (!request) {
9698 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
9699 return;
9700 }
9701
9702 hdd_request_complete(request);
9703 hdd_request_put(request);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309704}
9705
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309706
Katya Nigame7b69a82015-04-28 15:24:06 +05309707void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
9708 {
9709 hdd_mon_ctx_t *pMonCtx = NULL;
Katya Nigame7b69a82015-04-28 15:24:06 +05309710
Rajeev Kumar Sirasanagandla54447612018-03-06 15:49:56 +05309711 spin_lock_init(&pAdapter->sta_hash_lock);
9712 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
9713
9714 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
Katya Nigame7b69a82015-04-28 15:24:06 +05309715 pMonCtx->state = 0;
9716 pMonCtx->ChannelNo = 1;
9717 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05309718 pMonCtx->crcCheckEnabled = 1;
9719 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
9720 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05309721 pMonCtx->numOfMacFilters = 0;
9722 }
9723
Jeff Johnson295189b2012-06-20 16:38:30 -07009724
9725hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08009726 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07009727 tANI_U8 rtnl_held )
9728{
9729 hdd_adapter_t *pAdapter = NULL;
9730 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
9731 VOS_STATUS status = VOS_STATUS_E_FAILURE;
9732 VOS_STATUS exitbmpsStatus;
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309733 v_CONTEXT_t pVosContext = NULL;
9734
9735 /* No need to check for NULL, reaching this step
9736 * means vos context is initialized
9737 */
9738 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009739
Arif Hussain6d2a3322013-11-17 19:50:10 -08009740 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009741
Nirav Shah436658f2014-02-28 17:05:45 +05309742 if(macAddr == NULL)
9743 {
9744 /* Not received valid macAddr */
9745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9746 "%s:Unable to add virtual intf: Not able to get"
9747 "valid mac address",__func__);
9748 return NULL;
9749 }
9750
Jeff Johnson295189b2012-06-20 16:38:30 -07009751 //Disable BMPS incase of Concurrency
9752 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
9753
9754 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
9755 {
9756 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309757 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009758 VOS_ASSERT(0);
9759 return NULL;
9760 }
9761
9762 switch(session_type)
9763 {
9764 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07009765 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009766 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009767 {
9768 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9769
9770 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309771 {
9772 hddLog(VOS_TRACE_LEVEL_FATAL,
9773 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009774 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309775 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009776
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309777#ifdef FEATURE_WLAN_TDLS
9778 /* A Mutex Lock is introduced while changing/initializing the mode to
9779 * protect the concurrent access for the Adapters by TDLS module.
9780 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309781 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309782#endif
9783
Jeff Johnsone7245742012-09-05 17:12:55 -07009784 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
9785 NL80211_IFTYPE_P2P_CLIENT:
9786 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07009787
Jeff Johnson295189b2012-06-20 16:38:30 -07009788 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309789#ifdef FEATURE_WLAN_TDLS
9790 mutex_unlock(&pHddCtx->tdls_lock);
9791#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05309792
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309793 hdd_initialize_adapter_common(pAdapter);
Sunil Dutt66485cb2013-12-19 19:05:03 +05309794 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009795 if( VOS_STATUS_SUCCESS != status )
9796 goto err_free_netdev;
9797
9798 status = hdd_register_interface( pAdapter, rtnl_held );
9799 if( VOS_STATUS_SUCCESS != status )
9800 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05309801#ifdef FEATURE_WLAN_TDLS
9802 mutex_lock(&pHddCtx->tdls_lock);
9803#endif
c_hpothu002231a2015-02-05 14:58:51 +05309804 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05309805#ifdef FEATURE_WLAN_TDLS
9806 mutex_unlock(&pHddCtx->tdls_lock);
9807#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009808 goto err_free_netdev;
9809 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309810
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05309811 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309812 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05309813
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309814#ifdef WLAN_NS_OFFLOAD
9815 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309816 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309817#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009818 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309819 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009820 netif_tx_disable(pAdapter->dev);
9821 //netif_tx_disable(pWlanDev);
9822 netif_carrier_off(pAdapter->dev);
9823
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309824 if (WLAN_HDD_P2P_CLIENT == session_type ||
9825 WLAN_HDD_P2P_DEVICE == session_type)
9826 {
9827 /* Initialize the work queue to defer the
9828 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309829 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309830 hdd_p2p_roc_work_queue);
9831 }
9832
Jeff Johnson295189b2012-06-20 16:38:30 -07009833 break;
9834 }
9835
Jeff Johnson295189b2012-06-20 16:38:30 -07009836 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009837 case WLAN_HDD_SOFTAP:
9838 {
9839 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
9840 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309841 {
9842 hddLog(VOS_TRACE_LEVEL_FATAL,
9843 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009844 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309845 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009846
Jeff Johnson295189b2012-06-20 16:38:30 -07009847 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
9848 NL80211_IFTYPE_AP:
9849 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009850 pAdapter->device_mode = session_type;
9851
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309852 hdd_initialize_adapter_common(pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +05309853 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -07009854 if( VOS_STATUS_SUCCESS != status )
9855 goto err_free_netdev;
9856
Nirav Shah7e3c8132015-06-22 23:51:42 +05309857 status = hdd_sta_id_hash_attach(pAdapter);
9858 if (VOS_STATUS_SUCCESS != status)
9859 {
9860 hddLog(VOS_TRACE_LEVEL_FATAL,
9861 FL("failed to attach hash for session %d"), session_type);
9862 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
9863 goto err_free_netdev;
9864 }
9865
Jeff Johnson295189b2012-06-20 16:38:30 -07009866 status = hdd_register_hostapd( pAdapter, rtnl_held );
9867 if( VOS_STATUS_SUCCESS != status )
9868 {
c_hpothu002231a2015-02-05 14:58:51 +05309869 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07009870 goto err_free_netdev;
9871 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309872 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009873 netif_tx_disable(pAdapter->dev);
9874 netif_carrier_off(pAdapter->dev);
9875
9876 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309877
Hanumanth Reddy Pothulab4537b82018-03-02 12:20:38 +05309878 // Workqueue which gets scheduled in IPv4 notification callback.
9879 vos_init_work(&pAdapter->ipv4NotifierWorkQueue,
9880 hdd_ipv4_notifier_work_queue);
9881
9882#ifdef WLAN_NS_OFFLOAD
9883 // Workqueue which gets scheduled in IPv6 notification callback.
9884 vos_init_work(&pAdapter->ipv6NotifierWorkQueue,
9885 hdd_ipv6_notifier_work_queue);
9886#endif
9887
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309888 if (WLAN_HDD_P2P_GO == session_type)
9889 {
9890 /* Initialize the work queue to
9891 * defer the back to back RoC request */
9892 INIT_DELAYED_WORK(&pAdapter->roc_work,
9893 hdd_p2p_roc_work_queue);
9894 }
Bhargav Shahd0715912015-10-01 18:17:37 +05309895
Jeff Johnson295189b2012-06-20 16:38:30 -07009896 break;
9897 }
9898 case WLAN_HDD_MONITOR:
9899 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009900 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9901 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309902 {
9903 hddLog(VOS_TRACE_LEVEL_FATAL,
9904 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009905 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309906 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009907
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309908 pAdapter->device_mode = session_type;
9909 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
9910
Katya Nigame7b69a82015-04-28 15:24:06 +05309911 // Register wireless extensions
9912 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
9913 {
9914 hddLog(VOS_TRACE_LEVEL_FATAL,
9915 "hdd_register_wext() failed with status code %08d [x%08x]",
9916 status, status );
9917 status = VOS_STATUS_E_FAILURE;
9918 }
9919
Jeff Johnson295189b2012-06-20 16:38:30 -07009920#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
9921 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
9922#else
9923 pAdapter->dev->open = hdd_mon_open;
9924 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05309925 pAdapter->dev->stop = hdd_mon_stop;
9926 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07009927#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05309928 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309929 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009930 hdd_init_tx_rx( pAdapter );
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309931
9932 if (VOS_MONITOR_MODE != hdd_get_conparam())
9933 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9934
Jeff Johnson295189b2012-06-20 16:38:30 -07009935 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309936 status = hdd_register_interface( pAdapter, rtnl_held );
Katya Nigame7b69a82015-04-28 15:24:06 +05309937 //Stop the Interface TX queue.
9938 netif_tx_disable(pAdapter->dev);
9939 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009940 }
9941 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009942 case WLAN_HDD_FTM:
9943 {
9944 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9945
9946 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309947 {
9948 hddLog(VOS_TRACE_LEVEL_FATAL,
9949 FL("failed to allocate adapter for session %d"), session_type);
9950 return NULL;
9951 }
9952
Jeff Johnson295189b2012-06-20 16:38:30 -07009953 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
9954 * message while loading driver in FTM mode. */
9955 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
9956 pAdapter->device_mode = session_type;
9957 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309958
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309959 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309960 hdd_init_tx_rx( pAdapter );
9961
9962 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309963 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309964 netif_tx_disable(pAdapter->dev);
9965 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009966 }
9967 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009968 default:
9969 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309970 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
9971 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009972 VOS_ASSERT(0);
9973 return NULL;
9974 }
9975 }
9976
Jeff Johnson295189b2012-06-20 16:38:30 -07009977 if( VOS_STATUS_SUCCESS == status )
9978 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309979 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -07009980 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
9981 if( NULL == pHddAdapterNode )
9982 {
9983 status = VOS_STATUS_E_NOMEM;
9984 }
9985 else
9986 {
9987 pHddAdapterNode->pAdapter = pAdapter;
9988 status = hdd_add_adapter_back ( pHddCtx,
9989 pHddAdapterNode );
9990 }
9991 }
9992
9993 if( VOS_STATUS_SUCCESS != status )
9994 {
9995 if( NULL != pAdapter )
9996 {
9997 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
9998 pAdapter = NULL;
9999 }
10000 if( NULL != pHddAdapterNode )
10001 {
10002 vos_mem_free( pHddAdapterNode );
10003 }
10004
10005 goto resume_bmps;
10006 }
10007
10008 if(VOS_STATUS_SUCCESS == status)
10009 {
10010 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -070010011 //Initialize the WoWL service
10012 if(!hdd_init_wowl(pAdapter))
10013 {
10014 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
10015 goto err_free_netdev;
10016 }
Manjeet Singh3ed79242017-01-11 19:04:32 +053010017 //Initialize the TSF capture data
10018 wlan_hdd_tsf_init(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010019 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010020 return pAdapter;
10021
10022err_free_netdev:
Jeff Johnson295189b2012-06-20 16:38:30 -070010023 wlan_hdd_release_intf_addr( pHddCtx,
10024 pAdapter->macAddressCurrent.bytes );
Hanumanth Reddy Pothulaab8e1942018-05-24 18:10:39 +053010025 free_netdev(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070010026
10027resume_bmps:
10028 //If bmps disabled enable it
10029 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
10030 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010031 if (pHddCtx->hdd_wlan_suspended)
10032 {
10033 hdd_set_pwrparams(pHddCtx);
10034 }
10035 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010036 }
10037 return NULL;
10038}
10039
10040VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
10041 tANI_U8 rtnl_held )
10042{
10043 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
10044 VOS_STATUS status;
10045
10046 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
10047 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010048 {
10049 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
10050 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010051 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010052 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010053
10054 while ( pCurrent->pAdapter != pAdapter )
10055 {
10056 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
10057 if( VOS_STATUS_SUCCESS != status )
10058 break;
10059
10060 pCurrent = pNext;
10061 }
10062 pAdapterNode = pCurrent;
10063 if( VOS_STATUS_SUCCESS == status )
10064 {
10065 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10066 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010067
10068#ifdef FEATURE_WLAN_TDLS
10069
10070 /* A Mutex Lock is introduced while changing/initializing the mode to
10071 * protect the concurrent access for the Adapters by TDLS module.
10072 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010073 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010074#endif
10075
Jeff Johnson295189b2012-06-20 16:38:30 -070010076 hdd_remove_adapter( pHddCtx, pAdapterNode );
10077 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080010078 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010079
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010080#ifdef FEATURE_WLAN_TDLS
10081 mutex_unlock(&pHddCtx->tdls_lock);
10082#endif
10083
Jeff Johnson295189b2012-06-20 16:38:30 -070010084
10085 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +053010086 if ((!vos_concurrent_open_sessions_running()) &&
10087 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
10088 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010089 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010090 if (pHddCtx->hdd_wlan_suspended)
10091 {
10092 hdd_set_pwrparams(pHddCtx);
10093 }
10094 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010095 }
10096
10097 return VOS_STATUS_SUCCESS;
10098 }
10099
10100 return VOS_STATUS_E_FAILURE;
10101}
10102
10103VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
10104{
10105 hdd_adapter_list_node_t *pHddAdapterNode;
10106 VOS_STATUS status;
10107
10108 ENTER();
10109
10110 do
10111 {
10112 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
10113 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
10114 {
10115 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
10116 vos_mem_free( pHddAdapterNode );
10117 }
10118 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
10119
10120 EXIT();
10121
10122 return VOS_STATUS_SUCCESS;
10123}
10124
10125void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
10126{
10127 v_U8_t addIE[1] = {0};
10128
10129 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10130 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
10131 eANI_BOOLEAN_FALSE) )
10132 {
10133 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010134 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010135 }
10136
10137 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10138 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10139 eANI_BOOLEAN_FALSE) )
10140 {
10141 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010142 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010143 }
10144
10145 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10146 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10147 eANI_BOOLEAN_FALSE) )
10148 {
10149 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010150 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010151 }
10152}
10153
Anurag Chouhan83026002016-12-13 22:46:21 +053010154VOS_STATUS hdd_cleanup_ap_events(hdd_adapter_t *adapter)
10155{
10156#ifdef DHCP_SERVER_OFFLOAD
10157 vos_event_destroy(&adapter->dhcp_status.vos_event);
10158#endif
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010159#ifdef MDNS_OFFLOAD
10160 vos_event_destroy(&adapter->mdns_status.vos_event);
10161#endif
Anurag Chouhan83026002016-12-13 22:46:21 +053010162 return VOS_STATUS_SUCCESS;
10163}
10164
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010165int wlan_hdd_stop_mon(hdd_context_t *hdd_ctx, bool wait)
10166{
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010167 hdd_adapter_t *adapter;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010168 hdd_mon_ctx_t *mon_ctx;
10169 void (*func_ptr)(void *context) = NULL;
10170 int ret = 0;
10171 void *cookie = NULL;
10172 struct hdd_request *request;
10173 static const struct hdd_request_params params = {
10174 .priv_size = 0,
10175 .timeout_ms = MON_MODE_MSG_TIMEOUT,
10176 };
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010177
10178 adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
10179 if (!adapter) {
10180 hddLog(LOGE, FL("Invalid STA + MON mode"));
10181 return -EINVAL;
10182 }
10183
10184 mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(adapter);
10185 if (!mon_ctx)
10186 return 0;
10187
10188 if (mon_ctx->state != MON_MODE_START)
10189 return 0;
10190
10191 mon_ctx->state = MON_MODE_STOP;
10192 if (wait) {
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010193 func_ptr = hdd_mon_post_msg_cb;
10194 request = hdd_request_alloc(&params);
10195 if (!request) {
10196 hddLog(VOS_TRACE_LEVEL_ERROR,
10197 FL("Request allocation failure"));
10198 return -ENOMEM;
10199 }
10200 cookie = hdd_request_cookie(request);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010201 }
10202
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010203 /*
10204 * If func_ptr is NULL, on receiving WDI_MON_START_RSP or
10205 * WDI_MON_STOP_RSP hdd_mon_post_msg_cb() won't be invoked
10206 * and so uninitialized cookie won't be accessed.
10207 */
10208 if (VOS_STATUS_SUCCESS != wlan_hdd_mon_postMsg(cookie,
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010209 mon_ctx,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010210 func_ptr)) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010211 hddLog(LOGE, FL("failed to stop MON MODE"));
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010212 ret = -EINVAL;
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010213 }
10214
10215 if (!wait)
10216 goto bmps_roaming;
10217
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010218 if (!ret)
10219 ret = hdd_request_wait_for_response(request);
10220 hdd_request_put(request);
10221 if (ret) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010222 hddLog(LOGE,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010223 FL("timeout on stop monitor mode completion %d"), ret);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010224 return -EINVAL;
10225 }
10226
10227bmps_roaming:
10228 hddLog(LOG1, FL("Enable BMPS"));
10229 hdd_enable_bmps_imps(hdd_ctx);
10230 hdd_restore_roaming(hdd_ctx);
10231
10232 return 0;
10233}
10234
10235bool wlan_hdd_check_monitor_state(hdd_context_t *hdd_ctx)
10236{
10237 hdd_adapter_t *mon_adapter;
10238 hdd_mon_ctx_t *mon_ctx;
10239
10240 if (hdd_ctx->concurrency_mode != VOS_STA_MON)
10241 return false;
10242
10243 mon_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
10244 if (!mon_adapter) {
10245 hddLog(LOGE, FL("Invalid concurrency mode"));
10246 return false;
10247 }
10248
10249 mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(mon_adapter);
10250 if (mon_ctx->state == MON_MODE_START)
10251 return true;
10252
10253 return false;
10254}
10255
10256int wlan_hdd_check_and_stop_mon(hdd_adapter_t *sta_adapter, bool wait)
10257{
10258 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(sta_adapter);
10259
10260 if ((sta_adapter->device_mode != WLAN_HDD_INFRA_STATION) ||
10261 !wlan_hdd_check_monitor_state(hdd_ctx))
10262 return 0;
10263
10264 if (wlan_hdd_stop_mon(hdd_ctx, wait))
10265 return -EINVAL;
10266
10267 return 0;
10268}
10269
10270void hdd_disable_roaming(hdd_context_t *hdd_ctx)
10271{
10272 if (!hdd_ctx)
10273 return;
10274
10275 if (!hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled) {
10276 hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
10277 return;
10278 }
10279
10280 hddLog(LOG1, FL("Disable driver and firmware roaming"));
10281
10282 hdd_ctx->roaming_ini_original =
10283 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled;
10284
10285 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
10286 CFG_LFR_FEATURE_ENABLED_MIN;
10287
10288 sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
10289 CFG_LFR_FEATURE_ENABLED_MIN);
10290}
10291
10292void hdd_restore_roaming(hdd_context_t *hdd_ctx)
10293{
10294 if (!hdd_ctx->roaming_ini_original)
10295 return;
10296
10297 hddLog(LOG1, FL("Enable driver and firmware roaming"));
10298
10299 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
10300 CFG_LFR_FEATURE_ENABLED_MAX;
10301
10302 hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
10303
10304 sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
10305 CFG_LFR_FEATURE_ENABLED_MAX);
10306}
Anurag Chouhan83026002016-12-13 22:46:21 +053010307
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010308VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
10309 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -070010310{
10311 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
10312 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010313 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010314 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010315 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010316 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +053010317 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010318
Anand N Sunkad26d71b92014-12-24 18:08:22 +053010319 if (pHddCtx->isLogpInProgress) {
10320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10321 "%s:LOGP in Progress. Ignore!!!",__func__);
10322 return VOS_STATUS_E_FAILURE;
10323 }
10324
Jeff Johnson295189b2012-06-20 16:38:30 -070010325 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010326
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010327 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -070010328 switch(pAdapter->device_mode)
10329 {
Nirav Shah0cf4d892015-11-05 16:27:27 +053010330 case WLAN_HDD_IBSS:
10331 if ( VOS_TRUE == bCloseSession )
10332 {
10333 status = hdd_sta_id_hash_detach(pAdapter);
10334 if (status != VOS_STATUS_SUCCESS)
10335 hddLog(VOS_TRACE_LEVEL_ERROR,
10336 FL("sta id hash detach failed"));
10337 }
10338
Jeff Johnson295189b2012-06-20 16:38:30 -070010339 case WLAN_HDD_INFRA_STATION:
10340 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -070010341 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010342 {
10343 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +053010344#ifdef FEATURE_WLAN_TDLS
10345 mutex_lock(&pHddCtx->tdls_lock);
10346 wlan_hdd_tdls_exit(pAdapter, TRUE);
10347 mutex_unlock(&pHddCtx->tdls_lock);
10348#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010349 if( hdd_connIsConnected(pstation) ||
10350 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010351 {
Abhishek Singhe21a5212017-06-09 09:42:58 +053010352 /*
10353 * Indicate sme of disconnect so that in progress connection
10354 * or preauth can be aborted.
10355 */
10356 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10357 pAdapter->sessionId);
Abhishek Singh99f17b82017-02-06 16:57:56 +053010358 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010359 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
10360 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
10361 pAdapter->sessionId,
10362 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
10363 else
10364 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
10365 pAdapter->sessionId,
10366 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Abhishek Singh7b52ed52016-02-11 17:45:54 +053010367 /* Success implies disconnect command got queued up successfully
10368 * Or cmd not queued as scan for SSID is in progress
10369 */
10370 if((eHAL_STATUS_SUCCESS == halStatus) ||
10371 (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -070010372 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010373 ret = wait_for_completion_interruptible_timeout(
10374 &pAdapter->disconnect_comp_var,
10375 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singh7b52ed52016-02-11 17:45:54 +053010376 if (ret <= 0 &&
10377 (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010378 {
10379 hddLog(VOS_TRACE_LEVEL_ERROR,
10380 "%s: wait on disconnect_comp_var failed %ld",
10381 __func__, ret);
10382 }
10383 }
10384 else
10385 {
10386 hddLog(LOGE, "%s: failed to post disconnect event to SME",
10387 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010388 }
10389 memset(&wrqu, '\0', sizeof(wrqu));
10390 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
10391 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
10392 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
10393 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010394 else if(pstation->conn_info.connState ==
10395 eConnectionState_Disconnecting)
10396 {
10397 ret = wait_for_completion_interruptible_timeout(
10398 &pAdapter->disconnect_comp_var,
10399 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10400 if (ret <= 0)
10401 {
10402 hddLog(VOS_TRACE_LEVEL_ERROR,
10403 FL("wait on disconnect_comp_var failed %ld"), ret);
10404 }
10405 }
Sachin Ahuja27dd2402016-08-01 20:30:31 +053010406 if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -070010407 {
Mahesh A Saptasagar0b61dcc2016-02-15 14:23:38 +053010408 wlan_hdd_scan_abort(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010409 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +053010410 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
10411 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010412 {
10413 while (pAdapter->is_roc_inprogress)
10414 {
10415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10416 "%s: ROC in progress for session %d!!!",
10417 __func__, pAdapter->sessionId);
10418 // waiting for ROC to expire
10419 msleep(500);
10420 /* In GO present case , if retry exceeds 3,
10421 it means something went wrong. */
10422 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
10423 {
10424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10425 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +053010426 if (eHAL_STATUS_SUCCESS !=
10427 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
10428 pAdapter->sessionId ))
10429 {
10430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10431 FL("Failed to Cancel Remain on Channel"));
10432 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010433 wait_for_completion_interruptible_timeout(
10434 &pAdapter->cancel_rem_on_chan_var,
10435 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
10436 break;
10437 }
10438 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010439 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010440 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +053010441#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010442 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +053010443#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010444
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010445 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010446
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010447 /* It is possible that the caller of this function does not
10448 * wish to close the session
10449 */
10450 if (VOS_TRUE == bCloseSession &&
10451 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010452 {
10453 INIT_COMPLETION(pAdapter->session_close_comp_var);
10454 if (eHAL_STATUS_SUCCESS ==
Agrawal Ashish5a3522c2016-03-02 15:08:28 +053010455 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, FALSE,
10456 VOS_FALSE, hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010457 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010458 unsigned long ret;
10459
Jeff Johnson295189b2012-06-20 16:38:30 -070010460 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010461 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010462 &pAdapter->session_close_comp_var,
10463 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010464 if ( 0 >= ret)
10465 {
10466 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010467 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010468 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010469 }
10470 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010471 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010472 break;
10473
10474 case WLAN_HDD_SOFTAP:
10475 case WLAN_HDD_P2P_GO:
Nirav Shah0cf4d892015-11-05 16:27:27 +053010476 if ( VOS_TRUE == bCloseSession )
10477 {
10478 status = hdd_sta_id_hash_detach(pAdapter);
10479 if (status != VOS_STATUS_SUCCESS)
10480 hddLog(VOS_TRACE_LEVEL_ERROR,
10481 FL("sta id hash detach failed"));
10482 }
10483
Jeff Johnson295189b2012-06-20 16:38:30 -070010484 //Any softap specific cleanup here...
Anurag Chouhan83026002016-12-13 22:46:21 +053010485 hdd_cleanup_ap_events(pAdapter);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010486 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
10487 while (pAdapter->is_roc_inprogress) {
10488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10489 "%s: ROC in progress for session %d!!!",
10490 __func__, pAdapter->sessionId);
10491 msleep(500);
10492 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
10493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10494 "%s: ROC completion is not received.!!!", __func__);
10495 WLANSAP_CancelRemainOnChannel(
10496 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
10497 wait_for_completion_interruptible_timeout(
10498 &pAdapter->cancel_rem_on_chan_var,
10499 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
10500 break;
10501 }
10502 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +053010503
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010504 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010505 }
Agrawal Ashish17ef5082016-10-17 18:33:21 +053010506#ifdef SAP_AUTH_OFFLOAD
10507 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
10508 hdd_set_sap_auth_offload(pAdapter, FALSE);
10509#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010510 mutex_lock(&pHddCtx->sap_lock);
10511 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10512 {
10513 VOS_STATUS status;
10514 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10515
10516 //Stop Bss.
10517 status = WLANSAP_StopBss(pHddCtx->pvosContext);
10518 if (VOS_IS_STATUS_SUCCESS(status))
10519 {
10520 hdd_hostapd_state_t *pHostapdState =
10521 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10522
10523 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10524
10525 if (!VOS_IS_STATUS_SUCCESS(status))
10526 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010527 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
10528 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010529 }
10530 }
10531 else
10532 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010533 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010534 }
10535 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010536 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010537
10538 if (eHAL_STATUS_FAILURE ==
10539 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
10540 0, NULL, eANI_BOOLEAN_FALSE))
10541 {
10542 hddLog(LOGE,
10543 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010544 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010545 }
10546
10547 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
10548 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10549 eANI_BOOLEAN_FALSE) )
10550 {
10551 hddLog(LOGE,
10552 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
10553 }
10554
10555 // Reset WNI_CFG_PROBE_RSP Flags
10556 wlan_hdd_reset_prob_rspies(pAdapter);
10557 kfree(pAdapter->sessionCtx.ap.beacon);
10558 pAdapter->sessionCtx.ap.beacon = NULL;
10559 }
10560 mutex_unlock(&pHddCtx->sap_lock);
Hanumanth Reddy Pothulab4537b82018-03-02 12:20:38 +053010561
10562#ifdef WLAN_NS_OFFLOAD
10563 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
10564#endif
10565 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
10566
Jeff Johnson295189b2012-06-20 16:38:30 -070010567 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -070010568
Jeff Johnson295189b2012-06-20 16:38:30 -070010569 case WLAN_HDD_MONITOR:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010570 if (VOS_MONITOR_MODE != hdd_get_conparam())
10571 wlan_hdd_stop_mon(pHddCtx, true);
10572 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -070010573
Jeff Johnson295189b2012-06-20 16:38:30 -070010574 default:
10575 break;
10576 }
10577
10578 EXIT();
10579 return VOS_STATUS_SUCCESS;
10580}
10581
Kapil Gupta137ef892016-12-13 19:38:00 +053010582/**
10583 * wlan_hdd_restart_sap() - to restart SAP in driver internally
10584 * @ap_adapter: - Pointer to SAP hdd_adapter_t structure
10585 *
10586 * wlan_hdd_restart_sap first delete SAP and do cleanup.
10587 * After that WLANSAP_StartBss start re-start process of SAP.
10588 *
10589 * Return: None
10590 */
10591static void wlan_hdd_restart_sap(hdd_adapter_t *ap_adapter)
10592{
10593 hdd_ap_ctx_t *pHddApCtx;
10594 hdd_hostapd_state_t *pHostapdState;
10595 VOS_STATUS vos_status;
10596 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(ap_adapter);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010597#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053010598 struct station_del_parameters delStaParams;
10599#endif
10600 tsap_Config_t *pConfig;
10601
10602 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
10603 pConfig = &pHddApCtx->sapConfig;
10604
10605 mutex_lock(&pHddCtx->sap_lock);
10606 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010607#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053010608 delStaParams.mac = NULL;
10609 delStaParams.subtype = SIR_MAC_MGMT_DEAUTH >> 4;
10610 delStaParams.reason_code = eCsrForcedDeauthSta;
10611 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
10612 &delStaParams);
10613#else
10614 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
10615 NULL);
10616#endif
10617 hdd_cleanup_actionframe(pHddCtx, ap_adapter);
10618
10619 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
10620 vos_event_reset(&pHostapdState->vosEvent);
10621
10622 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10623 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
10624 10000);
10625 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10626 hddLog(LOGE, FL("SAP Stop Failed"));
10627 goto end;
10628 }
10629 }
10630 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
10631 wlan_hdd_decr_active_session(pHddCtx, ap_adapter->device_mode);
10632 hddLog(LOG1, FL("SAP Stop Success"));
10633
10634 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
10635 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10636 goto end;
10637 }
10638
10639 if (WLANSAP_StartBss(pHddCtx->pvosContext, hdd_hostapd_SAPEventCB,
10640 pConfig, (v_PVOID_t)ap_adapter->dev) != VOS_STATUS_SUCCESS) {
10641 hddLog(LOGE, FL("SAP Start Bss fail"));
10642 goto end;
10643 }
10644
10645 hddLog(LOG1, FL("Waiting for SAP to start"));
10646 vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10647 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10648 hddLog(LOGE, FL("SAP Start failed"));
10649 goto end;
10650 }
10651 hddLog(LOG1, FL("SAP Start Success"));
10652 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
10653 wlan_hdd_incr_active_session(pHddCtx, ap_adapter->device_mode);
10654 pHostapdState->bCommit = TRUE;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010655 if (!VOS_IS_STATUS_SUCCESS(hdd_dhcp_mdns_offload(ap_adapter))) {
10656 hddLog(VOS_TRACE_LEVEL_ERROR, FL("DHCP/MDNS offload Failed!!"));
10657 vos_event_reset(&pHostapdState->vosEvent);
10658 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10659 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
10660 10000);
10661 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10662 hddLog(LOGE, FL("SAP Stop Failed"));
10663 goto end;
10664 }
10665 }
10666 }
Kapil Gupta137ef892016-12-13 19:38:00 +053010667 }
10668end:
10669 mutex_unlock(&pHddCtx->sap_lock);
10670 return;
10671}
10672
10673/**
10674 * __hdd_sap_restart_handle() - to handle restarting of SAP
10675 * @work: name of the work
10676 *
10677 * Purpose of this function is to trigger sap start. this function
10678 * will be called from workqueue.
10679 *
10680 * Return: void.
10681 */
10682static void __hdd_sap_restart_handle(struct work_struct *work)
10683{
10684 hdd_adapter_t *sap_adapter;
10685 hdd_context_t *hdd_ctx = container_of(work,
10686 hdd_context_t,
10687 sap_start_work);
10688 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
10689 vos_ssr_unprotect(__func__);
10690 return;
10691 }
10692 sap_adapter = hdd_get_adapter(hdd_ctx,
10693 WLAN_HDD_SOFTAP);
10694 if (sap_adapter == NULL) {
10695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10696 FL("sap_adapter is NULL"));
10697 vos_ssr_unprotect(__func__);
10698 return;
10699 }
10700
10701 if (hdd_ctx->is_ch_avoid_in_progress) {
10702 sap_adapter->sessionCtx.ap.sapConfig.channel = AUTO_CHANNEL_SELECT;
10703 wlan_hdd_restart_sap(sap_adapter);
10704 hdd_change_ch_avoidance_status(hdd_ctx, false);
10705 }
Agrawal Ashish574b3e62017-02-09 18:58:34 +053010706 if (hdd_ctx->cfg_ini->enable_sap_auth_offload)
10707 wlan_hdd_restart_sap(sap_adapter);
Kapil Gupta137ef892016-12-13 19:38:00 +053010708}
10709
10710/**
10711 * hdd_sap_restart_handle() - to handle restarting of SAP
10712 * @work: name of the work
10713 *
10714 * Purpose of this function is to trigger sap start. this function
10715 * will be called from workqueue.
10716 *
10717 * Return: void.
10718 */
10719static void hdd_sap_restart_handle(struct work_struct *work)
10720{
10721 vos_ssr_protect(__func__);
10722 __hdd_sap_restart_handle(work);
10723 vos_ssr_unprotect(__func__);
10724}
10725
10726
Abhishek Singh78c691f2017-11-30 13:48:44 +053010727/**
10728 * __hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
10729 * @work: name of the work
10730 *
10731 * Purpose of this function is to force SCC using ECSA. This function
10732 * will be called from workqueue.
10733 *
10734 * Return: void.
10735 */
10736static void
10737__hdd_force_scc_with_ecsa_handle(struct work_struct *work)
10738{
10739 hdd_adapter_t *sap_adapter;
10740 hdd_station_ctx_t *sta_ctx;
10741 hdd_adapter_t *sta_adapter;
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010742 ptSapContext sap_ctx = NULL;
10743 v_CONTEXT_t vos_ctx;
10744 tANI_U8 target_channel;
10745 tsap_Config_t *sap_config;
10746 bool sta_sap_scc_on_dfs_chan;
10747 eNVChannelEnabledType chan_state;
Abhishek Singh78c691f2017-11-30 13:48:44 +053010748 hdd_context_t *hdd_ctx = container_of(to_delayed_work(work),
10749 hdd_context_t,
10750 ecsa_chan_change_work);
10751
10752 if (wlan_hdd_validate_context(hdd_ctx))
10753 return;
10754
10755 sap_adapter = hdd_get_adapter(hdd_ctx,
10756 WLAN_HDD_SOFTAP);
10757 if (!sap_adapter) {
10758 hddLog(LOGE, FL("sap_adapter is NULL"));
10759 return;
10760 }
10761
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010762 vos_ctx = hdd_ctx->pvosContext;
10763 if (!vos_ctx) {
10764 hddLog(LOGE, FL("vos_ctx is NULL"));
10765 return;
10766 }
10767
10768 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
10769 if (!sap_ctx) {
10770 hddLog(LOGE, FL("sap_ctx is NULL"));
10771 return;
10772 }
10773
10774 sap_config = &sap_adapter->sessionCtx.ap.sapConfig;
10775
10776 sta_sap_scc_on_dfs_chan = hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_ctx);
10777
Abhishek Singh78c691f2017-11-30 13:48:44 +053010778 sta_adapter = hdd_get_adapter(hdd_ctx,
10779 WLAN_HDD_INFRA_STATION);
10780 if (!sta_adapter) {
10781 hddLog(LOGE, FL("sta_adapter is NULL"));
10782 return;
10783 }
Abhishek Singh78c691f2017-11-30 13:48:44 +053010784
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010785 if (wlansap_chk_n_set_chan_change_in_progress(sap_ctx))
Abhishek Singh78c691f2017-11-30 13:48:44 +053010786 return;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010787 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
10788
10789 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
10790 if (sta_ctx->conn_info.connState != eConnectionState_Associated) {
10791 if (sta_ctx->conn_info.connState == eConnectionState_NotConnected) {
10792 chan_state = vos_nv_getChannelEnabledState(sap_ctx->channel);
10793 hddLog(LOG1, FL("sta not in connected state %d, sta_sap_scc_on_dfs_chan %d, chan_state %d"),
10794 sta_ctx->conn_info.connState, sta_sap_scc_on_dfs_chan,
10795 chan_state);
10796 if (sta_sap_scc_on_dfs_chan &&
10797 (chan_state == NV_CHANNEL_DFS)) {
10798 hddLog(LOGE, FL("Switch SAP to user configured channel"));
10799 target_channel = sap_config->user_config_channel;
10800 goto switch_channel;
10801 }
10802 }
10803 goto abort;
Abhishek Singh78c691f2017-11-30 13:48:44 +053010804 }
10805
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010806 target_channel = sta_ctx->conn_info.operationChannel;
10807switch_channel:
10808 hddLog(LOGE, FL("Switch SAP to %d channel"),
10809 target_channel);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010810 if (!wlansap_set_channel_change(vos_ctx, target_channel, true))
10811 return;
10812
10813abort:
10814 wlansap_reset_chan_change_in_progress(sap_ctx);
10815 complete(&sap_ctx->ecsa_info.chan_switch_comp);
Abhishek Singh78c691f2017-11-30 13:48:44 +053010816}
10817
10818/**
10819 * hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
10820 * @work: name of the work
10821 *
10822 * Purpose of this function is to force SCC using ECSA. This function
10823 * will be called from workqueue.
10824 *
10825 * Return: void.
10826 */
10827static void
10828hdd_force_scc_with_ecsa_handle(struct work_struct *work)
10829{
10830 vos_ssr_protect(__func__);
10831 __hdd_force_scc_with_ecsa_handle(work);
10832 vos_ssr_unprotect(__func__);
10833}
10834
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010835int hdd_wait_for_ecsa_complete(hdd_context_t *hdd_ctx)
10836{
10837 int ret;
10838 ptSapContext sap_ctx = NULL;
10839 v_CONTEXT_t vos_ctx;
10840
10841 vos_ctx = hdd_ctx->pvosContext;
10842 if (!vos_ctx) {
10843 hddLog(LOGE, FL("vos_ctx is NULL"));
10844 return 0;
10845 }
10846
10847 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
10848 if (!sap_ctx) {
10849 hddLog(LOG1, FL("sap_ctx is NULL"));
10850 return 0;
10851 }
10852 if(!sap_ctx->isSapSessionOpen) {
10853 hddLog(LOG1, FL("sap session not opened, SAP in state %d"),
10854 sap_ctx->sapsMachine);
10855 return 0;
10856 }
10857
10858 if (!wlansap_get_change_in_progress(sap_ctx)) {
10859 hddLog(LOG1, FL("channel switch not in progress"));
10860 return 0;
10861 }
10862 ret = wait_for_completion_timeout(&sap_ctx->ecsa_info.chan_switch_comp,
10863 msecs_to_jiffies(HDD_SAP_CHAN_CNG_WAIT_TIME));
10864 if (!ret)
10865 {
10866 hddLog(LOGE, FL("Timeout waiting for SAP channel switch"));
10867 return ret;
10868 }
10869
10870 return 0;
10871}
10872
10873
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010874/**
10875 * hdd_is_sta_sap_scc_allowed_on_dfs_chan() - check if sta+sap scc allowed on
10876 * dfs chan
10877 * @hdd_ctx: pointer to hdd context
10878 *
10879 * This function used to check if sta+sap scc allowed on DFS channel.
10880 *
10881 * Return: None
10882 */
10883bool hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_context_t *hdd_ctx)
10884{
10885 if (hdd_ctx->cfg_ini->force_scc_with_ecsa &&
10886 hdd_ctx->cfg_ini->sta_sap_scc_on_dfs_chan)
10887 return true;
10888 else
10889 return false;
10890}
10891
Jeff Johnson295189b2012-06-20 16:38:30 -070010892VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
10893{
10894 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10895 VOS_STATUS status;
10896 hdd_adapter_t *pAdapter;
10897
10898 ENTER();
10899
10900 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10901
10902 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10903 {
10904 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010905
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010906 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -070010907
10908 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10909 pAdapterNode = pNext;
10910 }
10911
10912 EXIT();
10913
10914 return VOS_STATUS_SUCCESS;
10915}
10916
Rajeev Kumarf999e582014-01-09 17:33:29 -080010917
10918#ifdef FEATURE_WLAN_BATCH_SCAN
10919/**---------------------------------------------------------------------------
10920
10921 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
10922 structures
10923
10924 \param - pAdapter Pointer to HDD adapter
10925
10926 \return - None
10927
10928 --------------------------------------------------------------------------*/
10929void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
10930{
10931 tHddBatchScanRsp *pNode;
10932 tHddBatchScanRsp *pPrev;
10933
Siddharth Bhalb3e9b792014-02-24 15:14:16 +053010934 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -080010935 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +053010936 hddLog(VOS_TRACE_LEVEL_ERROR,
10937 "%s: Adapter context is Null", __func__);
10938 return;
10939 }
10940
10941 pNode = pAdapter->pBatchScanRsp;
10942 while (pNode)
10943 {
10944 pPrev = pNode;
10945 pNode = pNode->pNext;
10946 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -080010947 }
10948
10949 pAdapter->pBatchScanRsp = NULL;
10950 pAdapter->numScanList = 0;
10951 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
10952 pAdapter->prev_batch_id = 0;
10953
10954 return;
10955}
10956#endif
10957
10958
Jeff Johnson295189b2012-06-20 16:38:30 -070010959VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
10960{
10961 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10962 VOS_STATUS status;
10963 hdd_adapter_t *pAdapter;
10964
10965 ENTER();
10966
10967 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10968
10969 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10970 {
10971 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053010972 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010973 netif_tx_disable(pAdapter->dev);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053010974
10975 if (pHddCtx->cfg_ini->sap_internal_restart &&
10976 pAdapter->device_mode == WLAN_HDD_SOFTAP) {
10977 hddLog(LOG1, FL("driver supports sap restart"));
10978 vos_flush_work(&pHddCtx->sap_start_work);
10979 hdd_sap_indicate_disconnect_for_sta(pAdapter);
10980 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053010981 hdd_softap_deinit_tx_rx(pAdapter, true);
10982 hdd_sap_destroy_timers(pAdapter);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053010983 } else {
10984 netif_carrier_off(pAdapter->dev);
10985 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010986
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070010987 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053010988
10989 if (pAdapter->device_mode == WLAN_HDD_MONITOR)
10990 pAdapter->sessionCtx.monitor.state = MON_MODE_STOP;
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070010991
Jeff Johnson295189b2012-06-20 16:38:30 -070010992 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +053010993
Katya Nigam1fd24402015-02-16 14:52:19 +053010994 if(pAdapter->device_mode == WLAN_HDD_IBSS )
10995 hdd_ibss_deinit_tx_rx(pAdapter);
10996
Nirav Shah7e3c8132015-06-22 23:51:42 +053010997 status = hdd_sta_id_hash_detach(pAdapter);
10998 if (status != VOS_STATUS_SUCCESS)
10999 hddLog(VOS_TRACE_LEVEL_ERROR,
11000 FL("sta id hash detach failed for session id %d"),
11001 pAdapter->sessionId);
11002
Agarwal Ashish6267caa2014-08-06 19:16:21 +053011003 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11004
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +053011005 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
11006 {
11007 hdd_wmm_adapter_close( pAdapter );
11008 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
11009 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011010
Siddharth Bhal2db319d2014-12-03 12:37:18 +053011011 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11012 {
11013 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
11014 }
11015
Rajeev Kumarf999e582014-01-09 17:33:29 -080011016#ifdef FEATURE_WLAN_BATCH_SCAN
11017 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
11018 {
11019 hdd_deinit_batch_scan(pAdapter);
11020 }
11021#endif
11022
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +053011023#ifdef FEATURE_WLAN_TDLS
11024 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +053011025 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +053011026 mutex_unlock(&pHddCtx->tdls_lock);
11027#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011028 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11029 pAdapterNode = pNext;
11030 }
11031
11032 EXIT();
11033
11034 return VOS_STATUS_SUCCESS;
11035}
11036
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011037/**
Abhishek Singh5a597e62016-12-05 15:16:30 +053011038 * hdd_get_bss_entry() - Get the bss entry matching the chan, bssid and ssid
11039 * @wiphy: wiphy
11040 * @channel: channel of the BSS to find
11041 * @bssid: bssid of the BSS to find
11042 * @ssid: ssid of the BSS to find
11043 * @ssid_len: ssid len of of the BSS to find
11044 *
11045 * The API is a wrapper to get bss from kernel matching the chan,
11046 * bssid and ssid
11047 *
11048 * Return: Void
11049 */
11050#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
11051 && !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
11052
11053struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
11054 struct ieee80211_channel *channel,
11055 const u8 *bssid,
11056 const u8 *ssid, size_t ssid_len)
11057{
11058 return cfg80211_get_bss(wiphy, channel, bssid,
11059 ssid, ssid_len,
11060 WLAN_CAPABILITY_ESS,
11061 WLAN_CAPABILITY_ESS);
11062}
11063#else
11064struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
11065 struct ieee80211_channel *channel,
11066 const u8 *bssid,
11067 const u8 *ssid, size_t ssid_len)
11068{
11069 return cfg80211_get_bss(wiphy, channel, bssid,
11070 ssid, ssid_len,
11071 IEEE80211_BSS_TYPE_ESS,
11072 IEEE80211_PRIVACY_ANY);
11073}
11074#endif
11075
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011076#if defined(CFG80211_CONNECT_BSS) || \
11077 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
11078
11079#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) || \
11080 defined (CFG80211_CONNECT_TIMEOUT_REASON_CODE)
11081/**
11082 * hdd_connect_bss() - helper function to send connection status to supplicant
11083 * @dev: network device
11084 * @bssid: bssid to which we want to associate
11085 * @bss: information about connected bss
11086 * @req_ie: Request Information Element
11087 * @req_ie_len: len of the req IE
11088 * @resp_ie: Response IE
11089 * @resp_ie_len: len of ht response IE
11090 * @status: status
11091 * @gfp: Kernel Flag
11092 *
11093 * This is a helper function to send connection status to supplicant
11094 * and gets invoked from wrapper API
11095 *
11096 * Return: Void
11097 */
11098static void hdd_connect_bss(struct net_device *dev,
11099 const u8 *bssid,
11100 struct cfg80211_bss *bss,
11101 const u8 *req_ie,
11102 size_t req_ie_len,
11103 const u8 *resp_ie,
11104 size_t resp_ie_len,
11105 u16 status,
11106 gfp_t gfp)
11107{
11108 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
11109 resp_ie, resp_ie_len, status, gfp, NL80211_TIMEOUT_UNSPECIFIED);
11110}
11111#else
11112/**
11113 * hdd_connect_bss() - helper function to send connection status to supplicant
11114 * @dev: network device
11115 * @bssid: bssid to which we want to associate
11116 * @bss: information about connected bss
11117 * @req_ie: Request Information Element
11118 * @req_ie_len: len of the req IE
11119 * @resp_ie: Response IE
11120 * @resp_ie_len: len of ht response IE
11121 * @status: status
11122 * @gfp: Kernel Flag
11123 *
11124 * This is a helper function to send connection status to supplicant
11125 * and gets invoked from wrapper API
11126 *
11127 * Return: Void
11128 */
11129static void hdd_connect_bss(struct net_device *dev,
11130 const u8 *bssid,
11131 struct cfg80211_bss *bss,
11132 const u8 *req_ie,
11133 size_t req_ie_len,
11134 const u8 *resp_ie,
11135 size_t resp_ie_len,
11136 u16 status,
11137 gfp_t gfp)
11138{
11139 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
11140 resp_ie, resp_ie_len, status, gfp);
11141}
11142#endif
11143
Abhishek Singh5a597e62016-12-05 15:16:30 +053011144/**
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011145 * hdd_connect_result() - API to send connection status to supplicant
11146 * @dev: network device
11147 * @bssid: bssid to which we want to associate
11148 * @roam_info: information about connected bss
11149 * @req_ie: Request Information Element
11150 * @req_ie_len: len of the req IE
11151 * @resp_ie: Response IE
11152 * @resp_ie_len: len of ht response IE
11153 * @status: status
11154 * @gfp: Kernel Flag
11155 *
11156 * The API is a wrapper to send connection status to supplicant
11157 *
11158 * Return: Void
11159 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011160void hdd_connect_result(struct net_device *dev,
11161 const u8 *bssid,
11162 tCsrRoamInfo *roam_info,
11163 const u8 *req_ie,
11164 size_t req_ie_len,
11165 const u8 *resp_ie,
11166 size_t resp_ie_len,
11167 u16 status,
11168 gfp_t gfp)
11169{
11170 hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev);
11171 struct cfg80211_bss *bss = NULL;
11172
11173 if (WLAN_STATUS_SUCCESS == status) {
11174 struct ieee80211_channel *chan;
11175 int freq;
11176 int chan_no = roam_info->pBssDesc->channelId;;
11177
11178 if (chan_no <= 14)
11179 freq = ieee80211_channel_to_frequency(chan_no,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011180 HDD_NL80211_BAND_2GHZ);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011181 else
11182 freq = ieee80211_channel_to_frequency(chan_no,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011183 HDD_NL80211_BAND_5GHZ);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011184
11185 chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
Abhishek Singh5a597e62016-12-05 15:16:30 +053011186 bss = hdd_get_bss_entry(padapter->wdev.wiphy,
11187 chan, bssid,
11188 roam_info->u.pConnectedProfile->SSID.ssId,
11189 roam_info->u.pConnectedProfile->SSID.length);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011190 }
11191
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011192 hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie, resp_ie_len,
11193 status, gfp);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011194}
11195#else
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011196/**
11197 * hdd_connect_result() - API to send connection status to supplicant
11198 * @dev: network device
11199 * @bssid: bssid to which we want to associate
11200 * @roam_info: information about connected bss
11201 * @req_ie: Request Information Element
11202 * @req_ie_len: len of the req IE
11203 * @resp_ie: Response IE
11204 * @resp_ie_len: len of ht response IE
11205 * @status: status
11206 * @gfp: Kernel Flag
11207 *
11208 * The API is a wrapper to send connection status to supplicant
11209 *
11210 * Return: Void
11211 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011212void hdd_connect_result(struct net_device *dev,
11213 const u8 *bssid,
11214 tCsrRoamInfo *roam_info,
11215 const u8 *req_ie,
11216 size_t req_ie_len,
11217 const u8 * resp_ie,
11218 size_t resp_ie_len,
11219 u16 status,
11220 gfp_t gfp)
11221{
11222 cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
11223 resp_ie, resp_ie_len, status, gfp);
11224}
11225#endif
11226
Jeff Johnson295189b2012-06-20 16:38:30 -070011227VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
11228{
11229 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11230 VOS_STATUS status;
11231 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011232 eConnectionState connState;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011233 v_CONTEXT_t pVosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011234
11235 ENTER();
11236
11237 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11238
11239 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11240 {
11241 pAdapter = pAdapterNode->pAdapter;
11242
Kumar Anand82c009f2014-05-29 00:29:42 -070011243 hdd_wmm_init( pAdapter );
11244
Jeff Johnson295189b2012-06-20 16:38:30 -070011245 switch(pAdapter->device_mode)
11246 {
11247 case WLAN_HDD_INFRA_STATION:
11248 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -070011249 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011250
11251 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
11252
Jeff Johnson295189b2012-06-20 16:38:30 -070011253 hdd_init_station_mode(pAdapter);
11254 /* Open the gates for HDD to receive Wext commands */
11255 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011256 pHddCtx->scan_info.mScanPending = FALSE;
11257 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011258
11259 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +053011260 if (!pHddCtx->isLogpInProgress)
11261 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011262
11263 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011264 if (eConnectionState_Associated == connState ||
11265 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -070011266 {
11267 union iwreq_data wrqu;
11268 memset(&wrqu, '\0', sizeof(wrqu));
11269 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
11270 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
11271 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070011272 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011273
Jeff Johnson295189b2012-06-20 16:38:30 -070011274 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagar9ff4bcc2016-06-01 17:17:50 +053011275 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, false,
Mahesh A Saptasagarb5a15142016-05-25 11:27:43 +053011276 WLAN_REASON_UNSPECIFIED);
Jeff Johnson295189b2012-06-20 16:38:30 -070011277 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011278 else if (eConnectionState_Connecting == connState)
11279 {
11280 /*
11281 * Indicate connect failure to supplicant if we were in the
11282 * process of connecting
11283 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011284 hdd_connect_result(pAdapter->dev, NULL, NULL,
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011285 NULL, 0, NULL, 0,
11286 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
11287 GFP_KERNEL);
11288 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011289 break;
11290
11291 case WLAN_HDD_SOFTAP:
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011292 if (pHddCtx->cfg_ini->sap_internal_restart) {
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011293 hdd_init_ap_mode(pAdapter, true);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011294 status = hdd_sta_id_hash_attach(pAdapter);
11295 if (VOS_STATUS_SUCCESS != status)
11296 {
11297 hddLog(VOS_TRACE_LEVEL_FATAL,
11298 FL("failed to attach hash for"));
11299 }
11300 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011301 break;
11302
11303 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -070011304 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -070011305 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -070011306 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -070011307 break;
11308
11309 case WLAN_HDD_MONITOR:
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011310 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11311
11312 hddLog(VOS_TRACE_LEVEL_INFO, FL("[SSR] monitor mode"));
11313 if (!pVosContext) {
11314 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos context is NULL"));
11315 break;
11316 }
11317
11318 hdd_init_tx_rx(pAdapter);
11319 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk);
Jeff Johnson295189b2012-06-20 16:38:30 -070011320 break;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011321
Jeff Johnson295189b2012-06-20 16:38:30 -070011322 default:
11323 break;
11324 }
11325
11326 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11327 pAdapterNode = pNext;
11328 }
11329
11330 EXIT();
11331
11332 return VOS_STATUS_SUCCESS;
11333}
11334
11335VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
11336{
11337 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11338 hdd_adapter_t *pAdapter;
11339 VOS_STATUS status;
11340 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011341 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011342
11343 ENTER();
11344
11345 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11346
11347 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11348 {
11349 pAdapter = pAdapterNode->pAdapter;
11350
11351 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11352 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11353 {
11354 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11355 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11356
Abhishek Singhf4669da2014-05-26 15:07:49 +053011357 hddLog(VOS_TRACE_LEVEL_INFO,
11358 "%s: Set HDD connState to eConnectionState_NotConnected",
11359 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +053011360 spin_lock_bh(&pAdapter->lock_for_active_session);
11361 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11362 {
11363 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11364 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011365 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +053011366 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -070011367 init_completion(&pAdapter->disconnect_comp_var);
11368 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
11369 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11370
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011371 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070011372 &pAdapter->disconnect_comp_var,
11373 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011374 if (0 >= ret)
11375 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
11376 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -070011377
11378 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
11379 pHddCtx->isAmpAllowed = VOS_FALSE;
11380 sme_RoamConnect(pHddCtx->hHal,
11381 pAdapter->sessionId, &(pWextState->roamProfile),
11382 &roamId);
11383 }
11384
11385 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11386 pAdapterNode = pNext;
11387 }
11388
11389 EXIT();
11390
11391 return VOS_STATUS_SUCCESS;
11392}
11393
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011394void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
11395{
11396 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11397 VOS_STATUS status;
11398 hdd_adapter_t *pAdapter;
11399 hdd_station_ctx_t *pHddStaCtx;
11400 hdd_ap_ctx_t *pHddApCtx;
11401 hdd_hostapd_state_t * pHostapdState;
11402 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
11403 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
11404 const char *p2pMode = "DEV";
11405 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011406
11407 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11408 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11409 {
11410 pAdapter = pAdapterNode->pAdapter;
11411 switch (pAdapter->device_mode) {
11412 case WLAN_HDD_INFRA_STATION:
11413 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11414 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
11415 staChannel = pHddStaCtx->conn_info.operationChannel;
11416 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
11417 }
11418 break;
11419 case WLAN_HDD_P2P_CLIENT:
11420 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11421 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
11422 p2pChannel = pHddStaCtx->conn_info.operationChannel;
11423 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
11424 p2pMode = "CLI";
11425 }
11426 break;
11427 case WLAN_HDD_P2P_GO:
11428 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11429 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11430 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
11431 p2pChannel = pHddApCtx->operatingChannel;
11432 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
11433 }
11434 p2pMode = "GO";
11435 break;
11436 case WLAN_HDD_SOFTAP:
11437 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11438 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11439 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
11440 apChannel = pHddApCtx->operatingChannel;
11441 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
11442 }
11443 break;
11444 default:
11445 break;
11446 }
11447 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11448 pAdapterNode = pNext;
11449 }
11450 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
11451 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
11452 }
Yeshwanth Sriram Guntuka0004c0b2017-12-06 14:43:49 +053011453 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s",
11454 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011455 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053011456 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011457 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
11458 }
11459 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053011460 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011461 apChannel, MAC_ADDR_ARRAY(apBssid));
11462 }
11463
11464 if (p2pChannel > 0 && apChannel > 0) {
11465 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
11466 }
11467}
11468
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011469bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070011470{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011471 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -070011472}
11473
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011474/* Once SSR is disabled then it cannot be set. */
11475void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -070011476{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011477 if (HDD_SSR_DISABLED == isSsrRequired)
11478 return;
11479
Jeff Johnson295189b2012-06-20 16:38:30 -070011480 isSsrRequired = value;
11481}
11482
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +053011483void hdd_set_pre_close( hdd_context_t *pHddCtx)
11484{
11485 sme_PreClose(pHddCtx->hHal);
11486}
11487
Jeff Johnson295189b2012-06-20 16:38:30 -070011488VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
11489 hdd_adapter_list_node_t** ppAdapterNode)
11490{
11491 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011492 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011493 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
11494 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011495 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011496 return status;
11497}
11498
11499VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
11500 hdd_adapter_list_node_t* pAdapterNode,
11501 hdd_adapter_list_node_t** pNextAdapterNode)
11502{
11503 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011504 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011505 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
11506 (hdd_list_node_t*) pAdapterNode,
11507 (hdd_list_node_t**)pNextAdapterNode );
11508
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011509 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011510 return status;
11511}
11512
11513VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
11514 hdd_adapter_list_node_t* pAdapterNode)
11515{
11516 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011517 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011518 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
11519 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011520 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011521 return status;
11522}
11523
11524VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
11525 hdd_adapter_list_node_t** ppAdapterNode)
11526{
11527 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011528 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011529 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
11530 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011531 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011532 return status;
11533}
11534
11535VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
11536 hdd_adapter_list_node_t* pAdapterNode)
11537{
11538 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011539 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011540 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
11541 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011542 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011543 return status;
11544}
11545
11546VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
11547 hdd_adapter_list_node_t* pAdapterNode)
11548{
11549 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011550 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011551 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
11552 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011553 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011554 return status;
11555}
11556
11557hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
11558 tSirMacAddr macAddr )
11559{
11560 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11561 hdd_adapter_t *pAdapter;
11562 VOS_STATUS status;
11563
11564 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11565
11566 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11567 {
11568 pAdapter = pAdapterNode->pAdapter;
11569
11570 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
11571 macAddr, sizeof(tSirMacAddr) ) )
11572 {
11573 return pAdapter;
11574 }
11575 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11576 pAdapterNode = pNext;
11577 }
11578
11579 return NULL;
11580
11581}
11582
11583hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
11584{
11585 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11586 hdd_adapter_t *pAdapter;
11587 VOS_STATUS status;
11588
11589 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11590
11591 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11592 {
11593 pAdapter = pAdapterNode->pAdapter;
11594
11595 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
11596 IFNAMSIZ ) )
11597 {
11598 return pAdapter;
11599 }
11600 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11601 pAdapterNode = pNext;
11602 }
11603
11604 return NULL;
11605
11606}
11607
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053011608hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
11609 tANI_U32 sme_session_id )
11610{
11611 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11612 hdd_adapter_t *pAdapter;
11613 VOS_STATUS vos_status;
11614
11615
11616 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11617
11618 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
11619 {
11620 pAdapter = pAdapterNode->pAdapter;
11621
11622 if (pAdapter->sessionId == sme_session_id)
11623 return pAdapter;
11624
11625 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
11626 pAdapterNode = pNext;
11627 }
11628
11629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11630 "%s: sme_session_id %d does not exist with host",
11631 __func__, sme_session_id);
11632
11633 return NULL;
11634}
11635
Jeff Johnson295189b2012-06-20 16:38:30 -070011636hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
11637{
11638 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11639 hdd_adapter_t *pAdapter;
11640 VOS_STATUS status;
11641
11642 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11643
11644 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11645 {
11646 pAdapter = pAdapterNode->pAdapter;
11647
11648 if( pAdapter && (mode == pAdapter->device_mode) )
11649 {
11650 return pAdapter;
11651 }
11652 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11653 pAdapterNode = pNext;
11654 }
11655
11656 return NULL;
11657
11658}
11659
11660//Remove this function later
11661hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
11662{
11663 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11664 hdd_adapter_t *pAdapter;
11665 VOS_STATUS status;
11666
11667 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11668
11669 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11670 {
11671 pAdapter = pAdapterNode->pAdapter;
11672
11673 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
11674 {
11675 return pAdapter;
11676 }
11677
11678 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11679 pAdapterNode = pNext;
11680 }
11681
11682 return NULL;
11683
11684}
11685
Jeff Johnson295189b2012-06-20 16:38:30 -070011686/**---------------------------------------------------------------------------
11687
Mahesh A Saptasgar64534612014-09-23 13:13:33 +053011688 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -070011689
11690 This API returns the operating channel of the requested device mode
11691
11692 \param - pHddCtx - Pointer to the HDD context.
11693 - mode - Device mode for which operating channel is required
11694 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
11695 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
11696 \return - channel number. "0" id the requested device is not found OR it is not connected.
11697 --------------------------------------------------------------------------*/
11698v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
11699{
11700 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11701 VOS_STATUS status;
11702 hdd_adapter_t *pAdapter;
11703 v_U8_t operatingChannel = 0;
11704
11705 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11706
11707 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11708 {
11709 pAdapter = pAdapterNode->pAdapter;
11710
11711 if( mode == pAdapter->device_mode )
11712 {
11713 switch(pAdapter->device_mode)
11714 {
11715 case WLAN_HDD_INFRA_STATION:
11716 case WLAN_HDD_P2P_CLIENT:
11717 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
11718 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
11719 break;
11720 case WLAN_HDD_SOFTAP:
11721 case WLAN_HDD_P2P_GO:
11722 /*softap connection info */
11723 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11724 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
11725 break;
11726 default:
11727 break;
11728 }
11729
11730 break; //Found the device of interest. break the loop
11731 }
11732
11733 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11734 pAdapterNode = pNext;
11735 }
11736 return operatingChannel;
11737}
11738
11739#ifdef WLAN_FEATURE_PACKET_FILTERING
11740/**---------------------------------------------------------------------------
11741
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011742 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -070011743
11744 This used to set the multicast address list.
11745
11746 \param - dev - Pointer to the WLAN device.
11747 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011748 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -070011749
11750 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011751static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -070011752{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011753 hdd_adapter_t *pAdapter;
11754 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011755 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011756 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011757 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011758
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011759 ENTER();
11760
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011761 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011762 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070011763 {
11764 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011765 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011766 return;
11767 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011768 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11769 ret = wlan_hdd_validate_context(pHddCtx);
11770 if (0 != ret)
11771 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011772 return;
11773 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011774 if (dev->flags & IFF_ALLMULTI)
11775 {
11776 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011777 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011778 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011779 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011780 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011781 {
11782 mc_count = netdev_mc_count(dev);
11783 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011784 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -070011785 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
11786 {
11787 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011788 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011789 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011790 return;
11791 }
11792
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011793 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -070011794
11795 netdev_for_each_mc_addr(ha, dev) {
11796 if (i == mc_count)
11797 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011798 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
11799 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -080011800 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011801 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011802 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -070011803 i++;
11804 }
11805 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011806
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +053011807 if (pHddCtx->hdd_wlan_suspended)
11808 {
11809 /*
11810 * Configure the Mcast address list to FW
11811 * If wlan is already in suspend mode
11812 */
11813 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
11814 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011815 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011816 return;
11817}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011818
11819static void hdd_set_multicast_list(struct net_device *dev)
11820{
11821 vos_ssr_protect(__func__);
11822 __hdd_set_multicast_list(dev);
11823 vos_ssr_unprotect(__func__);
11824}
Jeff Johnson295189b2012-06-20 16:38:30 -070011825#endif
11826
11827/**---------------------------------------------------------------------------
11828
11829 \brief hdd_select_queue() -
11830
11831 This function is registered with the Linux OS for network
11832 core to decide which queue to use first.
11833
11834 \param - dev - Pointer to the WLAN device.
11835 - skb - Pointer to OS packet (sk_buff).
11836 \return - ac, Queue Index/access category corresponding to UP in IP header
11837
11838 --------------------------------------------------------------------------*/
11839v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011840 struct sk_buff *skb
11841#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
11842 , void *accel_priv
11843#endif
11844#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
11845 , select_queue_fallback_t fallback
11846#endif
11847)
Jeff Johnson295189b2012-06-20 16:38:30 -070011848{
11849 return hdd_wmm_select_queue(dev, skb);
11850}
11851
11852
11853/**---------------------------------------------------------------------------
11854
11855 \brief hdd_wlan_initial_scan() -
11856
11857 This function triggers the initial scan
11858
11859 \param - pAdapter - Pointer to the HDD adapter.
11860
11861 --------------------------------------------------------------------------*/
11862void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
11863{
11864 tCsrScanRequest scanReq;
11865 tCsrChannelInfo channelInfo;
11866 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -070011867 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011868 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11869
11870 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
11871 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
11872 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
11873
11874 if(sme_Is11dSupported(pHddCtx->hHal))
11875 {
11876 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
11877 if ( HAL_STATUS_SUCCESS( halStatus ) )
11878 {
11879 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
11880 if( !scanReq.ChannelInfo.ChannelList )
11881 {
11882 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
11883 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080011884 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011885 return;
11886 }
11887 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
11888 channelInfo.numOfChannels);
11889 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
11890 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080011891 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011892 }
11893
11894 scanReq.scanType = eSIR_PASSIVE_SCAN;
11895 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
11896 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
11897 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
11898 }
11899 else
11900 {
11901 scanReq.scanType = eSIR_ACTIVE_SCAN;
11902 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
11903 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
11904 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
11905 }
11906
11907 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
11908 if ( !HAL_STATUS_SUCCESS( halStatus ) )
11909 {
11910 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
11911 __func__, halStatus );
11912 }
11913
11914 if(sme_Is11dSupported(pHddCtx->hHal))
11915 vos_mem_free(scanReq.ChannelInfo.ChannelList);
11916}
11917
Jeff Johnson295189b2012-06-20 16:38:30 -070011918/**---------------------------------------------------------------------------
11919
11920 \brief hdd_full_power_callback() - HDD full power callback function
11921
11922 This is the function invoked by SME to inform the result of a full power
11923 request issued by HDD
11924
11925 \param - callbackcontext - Pointer to cookie
11926 \param - status - result of request
11927
11928 \return - None
11929
11930 --------------------------------------------------------------------------*/
11931static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
11932{
Jeff Johnson72a40512013-12-19 10:14:15 -080011933 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011934
11935 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070011936 "%s: context = %pK, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070011937
11938 if (NULL == callbackContext)
11939 {
11940 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070011941 "%s: Bad param, context [%pK]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011942 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011943 return;
11944 }
11945
Jeff Johnson72a40512013-12-19 10:14:15 -080011946 /* there is a race condition that exists between this callback
11947 function and the caller since the caller could time out either
11948 before or while this code is executing. we use a spinlock to
11949 serialize these actions */
11950 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011951
11952 if (POWER_CONTEXT_MAGIC != pContext->magic)
11953 {
11954 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -080011955 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011956 hddLog(VOS_TRACE_LEVEL_WARN,
11957 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011958 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -070011959 return;
11960 }
11961
Jeff Johnson72a40512013-12-19 10:14:15 -080011962 /* context is valid so caller is still waiting */
11963
11964 /* paranoia: invalidate the magic */
11965 pContext->magic = 0;
11966
11967 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -070011968 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -080011969
11970 /* serialization is complete */
11971 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011972}
11973
Katya Nigamf0511f62015-05-05 16:40:57 +053011974void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
11975{
11976 pMonCtx->typeSubtypeBitmap = 0;
11977 if( type%10 ) /* Management Packets */
11978 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
11979 type/=10;
11980 if( type%10 ) /* Control Packets */
11981 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
11982 type/=10;
11983 if( type%10 ) /* Data Packets */
11984 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
11985}
11986
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053011987VOS_STATUS wlan_hdd_mon_postMsg(void *context, hdd_mon_ctx_t *pMonCtx,
11988 void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +053011989{
11990 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011991 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053011992
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011993 if (MON_MODE_START == pMonCtx->state)
11994 monMsg.type = WDA_MON_START_REQ;
11995 else if (MON_MODE_STOP == pMonCtx->state)
11996 monMsg.type = WDA_MON_STOP_REQ;
11997 else {
11998 hddLog(VOS_TRACE_LEVEL_ERROR,
11999 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +053012000 return VOS_STATUS_E_FAILURE;
12001 }
12002
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012003 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
12004 if (pMonModeReq == NULL) {
12005 hddLog(VOS_TRACE_LEVEL_ERROR,
12006 FL("fail to allocate memory for monitor mode req"));
12007 return VOS_STATUS_E_FAILURE;
12008 }
Katya Nigamf0511f62015-05-05 16:40:57 +053012009
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012010 pMonModeReq->context = context;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012011 pMonModeReq->data = pMonCtx;
12012 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +053012013
Katya Nigamf0511f62015-05-05 16:40:57 +053012014 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012015 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053012016 monMsg.bodyval = 0;
12017
12018 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
12019 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
12020 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012021 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +053012022 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012023 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +053012024}
12025
Katya Nigame7b69a82015-04-28 15:24:06 +053012026void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
12027{
12028 VOS_STATUS vosStatus;
12029 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012030 hdd_mon_ctx_t *pMonCtx = NULL;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012031 int ret;
12032 void *cookie;
12033 struct hdd_request *request;
12034 static const struct hdd_request_params params = {
12035 .priv_size = 0,
12036 .timeout_ms = MON_MODE_MSG_TIMEOUT,
12037 };
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053012038
Katya Nigame7b69a82015-04-28 15:24:06 +053012039 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
12040 if(pAdapter == NULL || pVosContext == NULL)
12041 {
12042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
12043 return ;
12044 }
Katya Nigamf0511f62015-05-05 16:40:57 +053012045
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012046 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
12047 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
12048 pMonCtx->state = MON_MODE_STOP;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012049 request = hdd_request_alloc(&params);
12050 if (!request) {
12051 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
12052 return;
12053 }
12054 cookie = hdd_request_cookie(request);
12055
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012056 if (VOS_STATUS_SUCCESS !=
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012057 wlan_hdd_mon_postMsg(cookie, pMonCtx,
12058 hdd_mon_post_msg_cb)) {
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012059 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12060 FL("failed to post MON MODE REQ"));
12061 pMonCtx->state = MON_MODE_START;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012062 goto req_put;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012063 }
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012064
12065 ret = hdd_request_wait_for_response(request);
12066 if (ret)
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012067 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012068 FL("timeout on monitor mode completion %d"), ret);
12069
12070req_put:
12071 hdd_request_put(request);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012072 }
12073
Katya Nigame7b69a82015-04-28 15:24:06 +053012074 hdd_UnregisterWext(pAdapter->dev);
12075
12076 vos_mon_stop( pVosContext );
12077
12078 vosStatus = vos_sched_close( pVosContext );
12079 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
12080 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12081 "%s: Failed to close VOSS Scheduler",__func__);
12082 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12083 }
12084
12085 vosStatus = vos_nv_close();
12086 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12087 {
12088 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12089 "%s: Failed to close NV", __func__);
12090 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12091 }
12092
12093 vos_close(pVosContext);
12094
12095 #ifdef WLAN_KD_READY_NOTIFIER
12096 nl_srv_exit(pHddCtx->ptt_pid);
12097 #else
12098 nl_srv_exit();
12099 #endif
12100
Katya Nigame7b69a82015-04-28 15:24:06 +053012101 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +053012102}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012103/**
12104 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
12105 * @ wiphy: the wiphy to validate against
12106 *
12107 * Return: void
12108 */
12109void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
12110{
12111 int i =0;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053012112 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012113 {
12114 if (NULL != wiphy->bands[i] &&
12115 (NULL != wiphy->bands[i]->channels))
12116 {
12117 vos_mem_free(wiphy->bands[i]->channels);
12118 wiphy->bands[i]->channels = NULL;
12119 }
12120 }
12121}
Jeff Johnson295189b2012-06-20 16:38:30 -070012122/**---------------------------------------------------------------------------
12123
12124 \brief hdd_wlan_exit() - HDD WLAN exit function
12125
12126 This is the driver exit point (invoked during rmmod)
12127
12128 \param - pHddCtx - Pointer to the HDD Context
12129
12130 \return - None
12131
12132 --------------------------------------------------------------------------*/
12133void hdd_wlan_exit(hdd_context_t *pHddCtx)
12134{
12135 eHalStatus halStatus;
12136 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
12137 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +053012138 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080012139 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -080012140 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012141 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +053012142 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012143
12144 ENTER();
12145
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012146
Katya Nigame7b69a82015-04-28 15:24:06 +053012147 if (VOS_MONITOR_MODE == hdd_get_conparam())
12148 {
12149 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
12150 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053012151 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +053012152 }
12153 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -080012154 {
12155 // Unloading, restart logic is no more required.
12156 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -070012157
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053012158#ifdef FEATURE_WLAN_TDLS
12159 /* At the time of driver unloading; if tdls connection is present;
12160 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
12161 * wlan_hdd_tdls_find_peer always checks for valid context;
12162 * as load/unload in progress there can be a race condition.
12163 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
12164 * when tdls state is enabled.
12165 * As soon as driver set load/unload flag; tdls flag also needs
12166 * to be disabled so that hdd_rx_packet_cbk won't call
12167 * wlan_hdd_tdls_find_peer.
12168 */
Masti, Narayanraddi20494af2015-12-17 20:56:42 +053012169 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE,
12170 HDD_SET_TDLS_MODE_SOURCE_USER);
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053012171#endif
12172
c_hpothu5ab05e92014-06-13 17:34:05 +053012173 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12174 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -070012175 {
c_hpothu5ab05e92014-06-13 17:34:05 +053012176 pAdapter = pAdapterNode->pAdapter;
12177 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070012178 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053012179 /* Disable TX on the interface, after this hard_start_xmit() will
12180 * not be called on that interface
12181 */
12182 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
12183 netif_tx_disable(pAdapter->dev);
12184
12185 /* Mark the interface status as "down" for outside world */
12186 netif_carrier_off(pAdapter->dev);
12187
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053012188 /* DeInit the adapter. This ensures that all data packets
12189 * are freed.
12190 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053012191#ifdef FEATURE_WLAN_TDLS
12192 mutex_lock(&pHddCtx->tdls_lock);
12193#endif
c_hpothu002231a2015-02-05 14:58:51 +053012194 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053012195#ifdef FEATURE_WLAN_TDLS
12196 mutex_unlock(&pHddCtx->tdls_lock);
12197#endif
Masti, Narayanraddi26378462016-01-05 18:20:28 +053012198 vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work);
12199
12200 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053012201
c_hpothu5ab05e92014-06-13 17:34:05 +053012202 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012203 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
12204 WLAN_HDD_MONITOR == pAdapter->device_mode)
c_hpothu5ab05e92014-06-13 17:34:05 +053012205 {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012206 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12207 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
12208 wlan_hdd_cfg80211_deregister_frames(pAdapter);
12209
c_hpothu5ab05e92014-06-13 17:34:05 +053012210 hdd_UnregisterWext(pAdapter->dev);
12211 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012212
Jeff Johnson295189b2012-06-20 16:38:30 -070012213 }
c_hpothu5ab05e92014-06-13 17:34:05 +053012214 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12215 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012216 }
mukul sharmabab477d2015-06-11 17:14:55 +053012217
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012218 // Cancel any outstanding scan requests. We are about to close all
12219 // of our adapters, but an adapter structure is what SME passes back
12220 // to our callback function. Hence if there are any outstanding scan
12221 // requests then there is a race condition between when the adapter
12222 // is closed and when the callback is invoked.We try to resolve that
12223 // race condition here by canceling any outstanding scans before we
12224 // close the adapters.
12225 // Note that the scans may be cancelled in an asynchronous manner,
12226 // so ideally there needs to be some kind of synchronization. Rather
12227 // than introduce a new synchronization here, we will utilize the
12228 // fact that we are about to Request Full Power, and since that is
12229 // synchronized, the expectation is that by the time Request Full
12230 // Power has completed all scans will be cancelled.
12231 if (pHddCtx->scan_info.mScanPending)
12232 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +053012233 if(NULL != pAdapter)
12234 {
12235 hddLog(VOS_TRACE_LEVEL_INFO,
12236 FL("abort scan mode: %d sessionId: %d"),
12237 pAdapter->device_mode,
12238 pAdapter->sessionId);
12239 }
12240 hdd_abort_mac_scan(pHddCtx,
12241 pHddCtx->scan_info.sessionId,
12242 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012243 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012244 }
c_hpothu5ab05e92014-06-13 17:34:05 +053012245 else
Jeff Johnson88ba7742013-02-27 14:36:02 -080012246 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012247 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +053012248 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
12249 {
12250 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
12251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12252 "%s: in middle of FTM START", __func__);
12253 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
12254 msecs_to_jiffies(20000));
12255 if(!lrc)
12256 {
12257 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12258 "%s: timedout on ftmStartCmpVar fatal error", __func__);
12259 }
12260 }
Jeff Johnson88ba7742013-02-27 14:36:02 -080012261 wlan_hdd_ftm_close(pHddCtx);
12262 goto free_hdd_ctx;
12263 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012264
Jeff Johnson295189b2012-06-20 16:38:30 -070012265 /* DeRegister with platform driver as client for Suspend/Resume */
12266 vosStatus = hddDeregisterPmOps(pHddCtx);
12267 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
12268 {
12269 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
12270 VOS_ASSERT(0);
12271 }
12272
12273 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
12274 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
12275 {
12276 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
12277 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012278
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012279 //Stop the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053012280 if ((pHddCtx->cfg_ini->dynSplitscan) && (VOS_TIMER_STATE_RUNNING ==
12281 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012282 {
12283 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
12284 }
12285
12286 // Destroy the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053012287 if ((pHddCtx->cfg_ini->dynSplitscan) &&
12288 (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
12289 &pHddCtx->tx_rx_trafficTmr))))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012290 {
12291 hddLog(VOS_TRACE_LEVEL_ERROR,
12292 "%s: Cannot deallocate Traffic monitor timer", __func__);
12293 }
12294
Bhargav Shahd0715912015-10-01 18:17:37 +053012295 if (VOS_TIMER_STATE_RUNNING ==
12296 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
12297 vos_timer_stop(&pHddCtx->delack_timer);
12298 }
12299
12300 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
12301 &pHddCtx->delack_timer))) {
12302 hddLog(VOS_TRACE_LEVEL_ERROR,
12303 "%s: Cannot deallocate Bus bandwidth timer", __func__);
12304 }
12305
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012306 if (VOS_TIMER_STATE_RUNNING ==
12307 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) {
12308 vos_timer_stop(&pHddCtx->tdls_source_timer);
12309 }
12310
Abhishek Singh8a3e4dc2017-01-02 10:39:18 +053012311 vos_set_snoc_high_freq_voting(false);
12312
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012313 vos_timer_destroy(&pHddCtx->tdls_source_timer);
12314
Jeff Johnson295189b2012-06-20 16:38:30 -070012315 //Disable IMPS/BMPS as we do not want the device to enter any power
12316 //save mode during shutdown
12317 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
12318 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
12319 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
12320
12321 //Ensure that device is in full power as we will touch H/W during vos_Stop
12322 init_completion(&powerContext.completion);
12323 powerContext.magic = POWER_CONTEXT_MAGIC;
12324
12325 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
12326 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
12327
12328 if (eHAL_STATUS_SUCCESS != halStatus)
12329 {
12330 if (eHAL_STATUS_PMC_PENDING == halStatus)
12331 {
12332 /* request was sent -- wait for the response */
12333 lrc = wait_for_completion_interruptible_timeout(
12334 &powerContext.completion,
12335 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -070012336 if (lrc <= 0)
12337 {
12338 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012339 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -070012340 }
12341 }
12342 else
12343 {
12344 hddLog(VOS_TRACE_LEVEL_ERROR,
12345 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012346 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -070012347 /* continue -- need to clean up as much as possible */
12348 }
12349 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +053012350 if ((eHAL_STATUS_SUCCESS == halStatus) ||
12351 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
12352 {
12353 /* This will issue a dump command which will clean up
12354 BTQM queues and unblock MC thread */
12355 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
12356 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012357
Jeff Johnson72a40512013-12-19 10:14:15 -080012358 /* either we never sent a request, we sent a request and received a
12359 response or we sent a request and timed out. if we never sent a
12360 request or if we sent a request and got a response, we want to
12361 clear the magic out of paranoia. if we timed out there is a
12362 race condition such that the callback function could be
12363 executing at the same time we are. of primary concern is if the
12364 callback function had already verified the "magic" but had not
12365 yet set the completion variable when a timeout occurred. we
12366 serialize these activities by invalidating the magic while
12367 holding a shared spinlock which will cause us to block if the
12368 callback is currently executing */
12369 spin_lock(&hdd_context_lock);
12370 powerContext.magic = 0;
12371 spin_unlock(&hdd_context_lock);
12372
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +053012373 /* If Device is shutdown, no point for SME to wait for responses
12374 from device. Pre Close SME */
12375 if(wcnss_device_is_shutdown())
12376 {
12377 sme_PreClose(pHddCtx->hHal);
12378 }
Yue Ma0d4891e2013-08-06 17:01:45 -070012379 hdd_debugfs_exit(pHddCtx);
12380
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012381#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +053012382 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012383 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
12384#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +053012385 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012386 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
12387
Jeff Johnson295189b2012-06-20 16:38:30 -070012388 // Unregister the Net Device Notifier
12389 unregister_netdevice_notifier(&hdd_netdev_notifier);
12390
Jeff Johnson295189b2012-06-20 16:38:30 -070012391 hdd_stop_all_adapters( pHddCtx );
12392
Jeff Johnson295189b2012-06-20 16:38:30 -070012393#ifdef WLAN_BTAMP_FEATURE
12394 vosStatus = WLANBAP_Stop(pVosContext);
12395 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12396 {
12397 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12398 "%s: Failed to stop BAP",__func__);
12399 }
12400#endif //WLAN_BTAMP_FEATURE
12401
12402 //Stop all the modules
12403 vosStatus = vos_stop( pVosContext );
12404 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12405 {
12406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12407 "%s: Failed to stop VOSS",__func__);
12408 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053012409 if (isSsrPanicOnFailure())
12410 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012411 }
12412
Jeff Johnson295189b2012-06-20 16:38:30 -070012413 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -070012414 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012415
12416 //Close the scheduler before calling vos_close to make sure no thread is
12417 // scheduled after the each module close is called i.e after all the data
12418 // structures are freed.
12419 vosStatus = vos_sched_close( pVosContext );
12420 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
12421 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12422 "%s: Failed to close VOSS Scheduler",__func__);
12423 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12424 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012425#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
12426 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012427 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070012428#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012429 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012430 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012431
Mihir Shete7a24b5f2013-12-21 12:18:31 +053012432#ifdef CONFIG_ENABLE_LINUX_REG
12433 vosStatus = vos_nv_close();
12434 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12435 {
12436 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12437 "%s: Failed to close NV", __func__);
12438 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12439 }
12440#endif
12441
Jeff Johnson295189b2012-06-20 16:38:30 -070012442 //Close VOSS
12443 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
12444 vos_close(pVosContext);
12445
Jeff Johnson295189b2012-06-20 16:38:30 -070012446 //Close Watchdog
12447 if(pHddCtx->cfg_ini->fIsLogpEnabled)
12448 vos_watchdog_close(pVosContext);
12449
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053012450 //Clean up HDD Nlink Service
12451 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053012452
Manjeet Singh47ee8472016-04-11 11:57:18 +053012453 hdd_close_tx_queues(pHddCtx);
c_manjeecfd1efb2015-09-25 19:32:34 +053012454 wlan_free_fwr_mem_dump_buffer();
12455 memdump_deinit();
12456
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012457#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012458 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012459 {
12460 wlan_logging_sock_deactivate_svc();
12461 }
12462#endif
12463
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053012464#ifdef WLAN_KD_READY_NOTIFIER
12465 nl_srv_exit(pHddCtx->ptt_pid);
12466#else
12467 nl_srv_exit();
12468#endif /* WLAN_KD_READY_NOTIFIER */
12469
Abhishek Singh00b71972016-01-07 10:51:04 +053012470#ifdef WLAN_FEATURE_RMC
12471 hdd_close_cesium_nl_sock();
12472#endif /* WLAN_FEATURE_RMC */
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053012473
Jeff Johnson295189b2012-06-20 16:38:30 -070012474 hdd_close_all_adapters( pHddCtx );
12475
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012476 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
Abhishek Singh78c691f2017-11-30 13:48:44 +053012477 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
Kapil Gupta137ef892016-12-13 19:38:00 +053012478 vos_flush_work(&pHddCtx->sap_start_work);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012479
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +053012480free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -070012481 /* free the power on lock from platform driver */
12482 if (free_riva_power_on_lock("wlan"))
12483 {
12484 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
12485 __func__);
12486 }
12487
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053012488 /* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */
12489 wlan_hdd_free_cache_channels(pHddCtx);
12490
c_hpothu78c7b602014-05-17 17:35:49 +053012491 //Free up dynamically allocated members inside HDD Adapter
12492 if (pHddCtx->cfg_ini)
12493 {
12494 kfree(pHddCtx->cfg_ini);
12495 pHddCtx->cfg_ini= NULL;
12496 }
12497
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053012498 hdd_request_manager_deinit();
12499
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053012500 /* FTM/MONITOR mode, WIPHY did not registered
Leo Changf04ddad2013-09-18 13:46:38 -070012501 If un-register here, system crash will happen */
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053012502 if (!(VOS_FTM_MODE == hdd_get_conparam() ||
12503 VOS_MONITOR_MODE == hdd_get_conparam()))
Leo Changf04ddad2013-09-18 13:46:38 -070012504 {
12505 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012506 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -070012507 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012508 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070012509 if (hdd_is_ssr_required())
12510 {
12511 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -070012512 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -070012513 msleep(5000);
12514 }
12515 hdd_set_ssr_required (VOS_FALSE);
12516}
12517
12518
12519/**---------------------------------------------------------------------------
12520
12521 \brief hdd_update_config_from_nv() - Function to update the contents of
12522 the running configuration with parameters taken from NV storage
12523
12524 \param - pHddCtx - Pointer to the HDD global context
12525
12526 \return - VOS_STATUS_SUCCESS if successful
12527
12528 --------------------------------------------------------------------------*/
12529static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
12530{
Jeff Johnson295189b2012-06-20 16:38:30 -070012531 v_BOOL_t itemIsValid = VOS_FALSE;
12532 VOS_STATUS status;
12533 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
12534 v_U8_t macLoop;
12535
12536 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
12537 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
12538 if(status != VOS_STATUS_SUCCESS)
12539 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012540 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070012541 return VOS_STATUS_E_FAILURE;
12542 }
12543
12544 if (itemIsValid == VOS_TRUE)
12545 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012546 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -070012547 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
12548 VOS_MAX_CONCURRENCY_PERSONA);
12549 if(status != VOS_STATUS_SUCCESS)
12550 {
12551 /* Get MAC from NV fail, not update CFG info
12552 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -080012553 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070012554 return VOS_STATUS_E_FAILURE;
12555 }
12556
12557 /* If first MAC is not valid, treat all others are not valid
12558 * Then all MACs will be got from ini file */
12559 if(vos_is_macaddr_zero(&macFromNV[0]))
12560 {
12561 /* MAC address in NV file is not configured yet */
12562 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
12563 return VOS_STATUS_E_INVAL;
12564 }
12565
12566 /* Get MAC address from NV, update CFG info */
12567 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
12568 {
12569 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
12570 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012571 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -070012572 /* This MAC is not valid, skip it
12573 * This MAC will be got from ini file */
12574 }
12575 else
12576 {
12577 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
12578 (v_U8_t *)&macFromNV[macLoop].bytes[0],
12579 VOS_MAC_ADDR_SIZE);
12580 }
12581 }
12582 }
12583 else
12584 {
12585 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
12586 return VOS_STATUS_E_FAILURE;
12587 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012588
Jeff Johnson295189b2012-06-20 16:38:30 -070012589
12590 return VOS_STATUS_SUCCESS;
12591}
12592
12593/**---------------------------------------------------------------------------
12594
12595 \brief hdd_post_voss_start_config() - HDD post voss start config helper
12596
12597 \param - pAdapter - Pointer to the HDD
12598
12599 \return - None
12600
12601 --------------------------------------------------------------------------*/
12602VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
12603{
12604 eHalStatus halStatus;
12605 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012606 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -070012607
Jeff Johnson295189b2012-06-20 16:38:30 -070012608
12609 // Send ready indication to the HDD. This will kick off the MAC
12610 // into a 'running' state and should kick off an initial scan.
12611 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
12612 if ( !HAL_STATUS_SUCCESS( halStatus ) )
12613 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053012614 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -070012615 "code %08d [x%08x]",__func__, halStatus, halStatus );
12616 return VOS_STATUS_E_FAILURE;
12617 }
12618
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012619 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -070012620 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
12621 // And RIVA will crash
12622 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
12623 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012624 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
12625 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
12626
12627
Jeff Johnson295189b2012-06-20 16:38:30 -070012628 return VOS_STATUS_SUCCESS;
12629}
12630
Jeff Johnson295189b2012-06-20 16:38:30 -070012631/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012632void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070012633{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012634
12635 vos_wake_lock_acquire(&wlan_wake_lock, reason);
12636
Jeff Johnson295189b2012-06-20 16:38:30 -070012637}
12638
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012639void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070012640{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012641
12642 vos_wake_lock_release(&wlan_wake_lock, reason);
12643
Jeff Johnson295189b2012-06-20 16:38:30 -070012644}
12645
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012646void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012647{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012648
12649 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
12650 reason);
12651
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012652}
12653
Jeff Johnson295189b2012-06-20 16:38:30 -070012654/**---------------------------------------------------------------------------
12655
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012656 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
12657 information between Host and Riva
12658
12659 This function gets reported version of FW
12660 It also finds the version of Riva headers used to compile the host
12661 It compares the above two and prints a warning if they are different
12662 It gets the SW and HW version string
12663 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
12664 indicating the features they support through a bitmap
12665
12666 \param - pHddCtx - Pointer to HDD context
12667
12668 \return - void
12669
12670 --------------------------------------------------------------------------*/
12671
12672void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
12673{
12674
12675 tSirVersionType versionCompiled;
12676 tSirVersionType versionReported;
12677 tSirVersionString versionString;
12678 tANI_U8 fwFeatCapsMsgSupported = 0;
12679 VOS_STATUS vstatus;
12680
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080012681 memset(&versionCompiled, 0, sizeof(versionCompiled));
12682 memset(&versionReported, 0, sizeof(versionReported));
12683
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012684 /* retrieve and display WCNSS version information */
12685 do {
12686
12687 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
12688 &versionCompiled);
12689 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12690 {
12691 hddLog(VOS_TRACE_LEVEL_FATAL,
12692 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012693 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012694 break;
12695 }
12696
12697 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
12698 &versionReported);
12699 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12700 {
12701 hddLog(VOS_TRACE_LEVEL_FATAL,
12702 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012703 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012704 break;
12705 }
12706
12707 if ((versionCompiled.major != versionReported.major) ||
12708 (versionCompiled.minor != versionReported.minor) ||
12709 (versionCompiled.version != versionReported.version) ||
12710 (versionCompiled.revision != versionReported.revision))
12711 {
12712 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
12713 "Host expected %u.%u.%u.%u\n",
12714 WLAN_MODULE_NAME,
12715 (int)versionReported.major,
12716 (int)versionReported.minor,
12717 (int)versionReported.version,
12718 (int)versionReported.revision,
12719 (int)versionCompiled.major,
12720 (int)versionCompiled.minor,
12721 (int)versionCompiled.version,
12722 (int)versionCompiled.revision);
12723 }
12724 else
12725 {
12726 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
12727 WLAN_MODULE_NAME,
12728 (int)versionReported.major,
12729 (int)versionReported.minor,
12730 (int)versionReported.version,
12731 (int)versionReported.revision);
12732 }
12733
12734 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
12735 versionString,
12736 sizeof(versionString));
12737 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12738 {
12739 hddLog(VOS_TRACE_LEVEL_FATAL,
12740 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012741 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012742 break;
12743 }
12744
12745 pr_info("%s: WCNSS software version %s\n",
12746 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +053012747 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012748
12749 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
12750 versionString,
12751 sizeof(versionString));
12752 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12753 {
12754 hddLog(VOS_TRACE_LEVEL_FATAL,
12755 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012756 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012757 break;
12758 }
12759
12760 pr_info("%s: WCNSS hardware version %s\n",
12761 WLAN_MODULE_NAME, versionString);
12762
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012763 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
12764 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012765 send the message only if it the riva is 1.1
12766 minor numbers for different riva branches:
12767 0 -> (1.0)Mainline Build
12768 1 -> (1.1)Mainline Build
12769 2->(1.04) Stability Build
12770 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012771 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012772 ((versionReported.minor>=1) && (versionReported.version>=1)))
12773 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
12774 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012775
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012776 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -080012777 {
12778#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
12779 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
12780 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
12781#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -070012782 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
12783 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
12784 {
12785 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
12786 }
12787
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012788 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -080012789 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012790
12791 } while (0);
12792
12793}
Neelansh Mittaledafed22014-09-04 18:54:39 +053012794void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
12795{
12796 struct sk_buff *skb;
12797 struct nlmsghdr *nlh;
12798 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053012799 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +053012800 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012801
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053012802 if (in_interrupt() || irqs_disabled() || in_atomic())
12803 flags = GFP_ATOMIC;
12804
12805 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +053012806
12807 if(skb == NULL) {
12808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12809 "%s: alloc_skb failed", __func__);
12810 return;
12811 }
12812
12813 nlh = (struct nlmsghdr *)skb->data;
12814 nlh->nlmsg_pid = 0; /* from kernel */
12815 nlh->nlmsg_flags = 0;
12816 nlh->nlmsg_seq = 0;
12817 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
12818
12819 ani_hdr = NLMSG_DATA(nlh);
12820 ani_hdr->type = type;
12821
12822 switch(type) {
12823 case WLAN_SVC_SAP_RESTART_IND:
12824 ani_hdr->length = 0;
12825 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
12826 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
12827 break;
Bhargav Shahd0715912015-10-01 18:17:37 +053012828 case WLAN_SVC_WLAN_TP_IND:
12829 ani_hdr->length = len;
12830 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
12831 + len));
12832 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12833 memcpy(nl_data, data, len);
12834 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
12835 break;
Bhargav shah23c94942015-10-13 12:48:35 +053012836 case WLAN_MSG_RPS_ENABLE_IND:
12837 ani_hdr->length = len;
12838 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
12839 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12840 memcpy(nl_data, data, len);
12841 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
12842 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012843 default:
12844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12845 "Attempt to send unknown nlink message %d", type);
12846 kfree_skb(skb);
12847 return;
12848 }
12849
12850 nl_srv_bcast(skb);
12851
12852 return;
12853}
12854
Bhargav Shahd0715912015-10-01 18:17:37 +053012855/**
12856 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
12857 * @pHddCtx: Valid Global HDD context pointer
12858 * @rx_packets: Number of RX packet in perticular time
12859 *
12860 * Based on the RX packet this function calculate next value of tcp delack.
12861 * This function compare rx packet value to high and low threshold limit.
12862 *
12863 * Return: void
12864 */
12865void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
12866{
12867 /* average of rx_packets and prev_rx is taken so that
12868 bus width doesnot fluctuate much */
12869 uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
Alok Kumarf3724462018-04-05 15:18:54 +053012870 enum wlan_tp_level next_rx_level = pHddCtx->cur_rx_level;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012871
Bhargav Shahd0715912015-10-01 18:17:37 +053012872 pHddCtx->prev_rx = rx_packets;
12873 if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
Alok Kumarf3724462018-04-05 15:18:54 +053012874 next_rx_level = WLAN_SVC_TP_HIGH;
Bhargav Shahd0715912015-10-01 18:17:37 +053012875 else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
Alok Kumarf3724462018-04-05 15:18:54 +053012876 next_rx_level = WLAN_SVC_TP_LOW;
Bhargav Shahd0715912015-10-01 18:17:37 +053012877
12878 hdd_set_delack_value(pHddCtx, next_rx_level);
12879}
12880
12881#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))
12882
12883/**
12884 * hdd_tcp_delack_compute_function() - get link status
12885 * @priv: Valid Global HDD context pointer
12886 *
12887 * This function find number of RX packet during timer life span.
12888 * It request tcp delack with number of RX packet and re-configure delack timer
12889 * for tcpDelAckComputeInterval timer interval.
12890 *
12891 * Return: void
12892 */
12893void hdd_tcp_delack_compute_function(void *priv)
12894{
12895 hdd_context_t *pHddCtx = (hdd_context_t *)priv;
12896 hdd_adapter_t *pAdapter = NULL;
12897 v_U32_t rx_packets = 0;
12898 hdd_adapter_list_node_t *pAdapterNode = NULL;
12899 VOS_STATUS status = 0;
12900
12901 for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12902 NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
12903 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
12904 if ((pAdapter = pAdapterNode->pAdapter) == NULL)
12905 continue;
12906
12907 rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
12908 pAdapter->prev_rx_packets);
12909 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
12910 }
12911
12912 hdd_request_tcp_delack(pHddCtx, rx_packets);
12913
12914 vos_timer_start(&pHddCtx->delack_timer,
12915 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
12916}
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012917
12918/**---------------------------------------------------------------------------
12919
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012920 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
12921
12922 \param - pHddCtx - Pointer to the hdd context
12923
12924 \return - true if hardware supports 5GHz
12925
12926 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +053012927boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012928{
12929 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
12930 * then hardware support 5Ghz.
12931 */
12932 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
12933 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012934 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012935 return true;
12936 }
12937 else
12938 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012939 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012940 __func__);
12941 return false;
12942 }
12943}
12944
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012945/**---------------------------------------------------------------------------
12946
12947 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
12948 generate function
12949
12950 This is generate the random mac address for WLAN interface
12951
12952 \param - pHddCtx - Pointer to HDD context
12953 idx - Start interface index to get auto
12954 generated mac addr.
12955 mac_addr - Mac address
12956
12957 \return - 0 for success, < 0 for failure
12958
12959 --------------------------------------------------------------------------*/
12960
12961static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
12962 int idx, v_MACADDR_t mac_addr)
12963{
12964 int i;
12965 unsigned int serialno;
12966 serialno = wcnss_get_serial_number();
12967
12968 if (0 != serialno)
12969 {
12970 /* MAC address has 3 bytes of OUI so we have a maximum of 3
12971 bytes of the serial number that can be used to generate
12972 the other 3 bytes of the MAC address. Mask off all but
12973 the lower 3 bytes (this will also make sure we don't
12974 overflow in the next step) */
12975 serialno &= 0x00FFFFFF;
12976
12977 /* we need a unique address for each session */
12978 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
12979
12980 /* autogen other Mac addresses */
12981 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
12982 {
12983 /* start with the entire default address */
12984 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
12985 /* then replace the lower 3 bytes */
12986 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
12987 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
12988 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
12989
Nachiket Kukadede2e24f2017-09-25 16:24:27 +053012990 if (0 == memcmp(&pHddCtx->cfg_ini->intfMacAddr[i].bytes[0],
12991 &mac_addr.bytes[0], VOS_MAC_ADDR_SIZE))
12992 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] +=
12993 VOS_MAX_CONCURRENCY_PERSONA;
12994
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012995 serialno++;
12996 hddLog(VOS_TRACE_LEVEL_ERROR,
12997 "%s: Derived Mac Addr: "
12998 MAC_ADDRESS_STR, __func__,
12999 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
13000 }
13001
13002 }
13003 else
13004 {
13005 hddLog(LOGE, FL("Failed to Get Serial NO"));
13006 return -1;
13007 }
13008 return 0;
13009}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013010
Katya Nigame7b69a82015-04-28 15:24:06 +053013011int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
13012{
13013 VOS_STATUS status;
13014 v_CONTEXT_t pVosContext= NULL;
13015 hdd_adapter_t *pAdapter= NULL;
13016
13017 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13018
13019 if (NULL == pVosContext)
13020 {
13021 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13022 "%s: Trying to open VOSS without a PreOpen", __func__);
13023 VOS_ASSERT(0);
13024 return VOS_STATUS_E_FAILURE;
13025 }
13026
13027 status = vos_nv_open();
13028 if (!VOS_IS_STATUS_SUCCESS(status))
13029 {
13030 /* NV module cannot be initialized */
13031 hddLog( VOS_TRACE_LEVEL_FATAL,
13032 "%s: vos_nv_open failed", __func__);
13033 return VOS_STATUS_E_FAILURE;
13034 }
13035
13036 status = vos_init_wiphy_from_nv_bin();
13037 if (!VOS_IS_STATUS_SUCCESS(status))
13038 {
13039 /* NV module cannot be initialized */
13040 hddLog( VOS_TRACE_LEVEL_FATAL,
13041 "%s: vos_init_wiphy failed", __func__);
13042 goto err_vos_nv_close;
13043 }
13044
13045 status = vos_open( &pVosContext, pHddCtx->parent_dev);
13046 if ( !VOS_IS_STATUS_SUCCESS( status ))
13047 {
13048 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
13049 goto err_vos_nv_close;
13050 }
13051
13052 status = vos_mon_start( pVosContext );
13053 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13054 {
13055 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
13056 goto err_vosclose;
13057 }
13058
13059 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
13060 WDA_featureCapsExchange(pVosContext);
13061 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
13062
13063 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
13064 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13065 if( pAdapter == NULL )
13066 {
13067 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
13068 goto err_close_adapter;
13069 }
13070
13071 //Initialize the nlink service
13072 if(nl_srv_init() != 0)
13073 {
13074 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
13075 goto err_close_adapter;
13076 }
13077 return VOS_STATUS_SUCCESS;
13078
13079err_close_adapter:
13080 hdd_close_all_adapters( pHddCtx );
13081 vos_mon_stop( pVosContext );
13082err_vosclose:
13083 status = vos_sched_close( pVosContext );
13084 if (!VOS_IS_STATUS_SUCCESS(status)) {
13085 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
13086 "%s: Failed to close VOSS Scheduler", __func__);
13087 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
13088 }
13089 vos_close(pVosContext );
13090
13091err_vos_nv_close:
13092 vos_nv_close();
13093
13094return status;
13095}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013096/**---------------------------------------------------------------------------
13097
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013098 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
13099 completed to flush out the scan results
13100
13101 11d scan is done during driver load and is a passive scan on all
13102 channels supported by the device, 11d scans may find some APs on
13103 frequencies which are forbidden to be used in the regulatory domain
13104 the device is operating in. If these APs are notified to the supplicant
13105 it may try to connect to these APs, thus flush out all the scan results
13106 which are present in SME after 11d scan is done.
13107
13108 \return - eHalStatus
13109
13110 --------------------------------------------------------------------------*/
13111static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
13112 tANI_U32 scanId, eCsrScanStatus status)
13113{
13114 ENTER();
13115
13116 sme_ScanFlushResult(halHandle, 0);
13117
13118 EXIT();
13119
13120 return eHAL_STATUS_SUCCESS;
13121}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013122/**---------------------------------------------------------------------------
13123
13124 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
13125 logging is completed successfully.
13126
13127 \return - None
13128
13129 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +053013130void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013131{
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013132 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013133
13134 if (NULL == pHddCtx)
13135 {
13136 hddLog(VOS_TRACE_LEVEL_ERROR,
13137 "%s: HDD context is NULL",__func__);
13138 return;
13139 }
13140
c_manjeecfd1efb2015-09-25 19:32:34 +053013141 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +053013142 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013143 {
13144 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
13145 pHddCtx->mgmt_frame_logging = TRUE;
13146 }
13147 else
13148 {
13149 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
13150 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +053013151 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013152 }
13153
c_manjeecfd1efb2015-09-25 19:32:34 +053013154 /*Check feature supported by FW*/
13155 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
13156 {
13157 //Store fwr mem dump size given by firmware.
13158 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
13159 }
13160 else
13161 {
13162 wlan_store_fwr_mem_dump_size(0);
13163 }
13164
13165
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013166}
13167/**---------------------------------------------------------------------------
13168
13169 \brief hdd_init_frame_logging - function to initialize frame logging.
13170 Currently only Mgmt Frames are logged in both TX
13171 and Rx direction and are sent to userspace
13172 application using logger thread when queried.
13173
13174 \return - None
13175
13176 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013177void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013178{
13179 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013180 tSirFWLoggingInitParam wlanFWLoggingInitParam = {0};
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013181
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013182 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
13183 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013184 {
13185 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
13186 return;
13187 }
13188
c_manjeecfd1efb2015-09-25 19:32:34 +053013189 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013190 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
13191 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +053013192 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
13193 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013194
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013195 if (pHddCtx->cfg_ini->enableFWLogging ||
13196 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013197 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013198 wlanFWLoggingInitParam.enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013199 }
13200
Sushant Kaushik46804902015-07-08 14:46:03 +053013201 if (pHddCtx->cfg_ini->enableMgmtLogging)
13202 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013203 wlanFWLoggingInitParam.enableFlag |= WLAN_FRAME_LOG_EN;
Sushant Kaushik46804902015-07-08 14:46:03 +053013204 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013205 if (pHddCtx->cfg_ini->enableBMUHWtracing)
13206 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013207 wlanFWLoggingInitParam.enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013208 }
c_manjeecfd1efb2015-09-25 19:32:34 +053013209 if(pHddCtx->cfg_ini->enableFwrMemDump &&
13210 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
13211 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013212 wlanFWLoggingInitParam.enableFlag |= WLAN_FW_MEM_DUMP_EN;
c_manjeecfd1efb2015-09-25 19:32:34 +053013213 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013214 if( wlanFWLoggingInitParam.enableFlag == 0 )
c_manjeecfd1efb2015-09-25 19:32:34 +053013215 {
13216 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
13217 return;
13218 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013219 wlanFWLoggingInitParam.frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
13220 wlanFWLoggingInitParam.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
13221 wlanFWLoggingInitParam.bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
13222 wlanFWLoggingInitParam.continuousFrameLogging =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013223 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013224
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013225 wlanFWLoggingInitParam.enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013226
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013227 wlanFWLoggingInitParam.minLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013228 pHddCtx->cfg_ini->minLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013229 wlanFWLoggingInitParam.maxLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013230 pHddCtx->cfg_ini->maxLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013231 wlanFWLoggingInitParam.fwlogInitCallback = hdd_init_frame_logging_done;
13232 wlanFWLoggingInitParam.fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013233
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013234 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, &wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013235
13236 if (eHAL_STATUS_SUCCESS != halStatus)
13237 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013238 hddLog(LOGE, FL("sme_InitMgmtFrameLogging failed, returned %d"),
13239 halStatus);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013240 }
13241
13242 return;
13243}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013244
Bhargav shah23c94942015-10-13 12:48:35 +053013245static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
13246{
13247 hdd_adapter_t *adapter;
13248 hdd_adapter_list_node_t *adapter_node, *next;
13249 VOS_STATUS status = VOS_STATUS_SUCCESS;
13250 struct wlan_rps_data rps_data;
13251 int count;
13252
13253 if(!hdd_ctxt->cfg_ini->rps_mask)
13254 {
13255 return;
13256 }
13257
13258 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
13259 {
13260 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
13261 }
13262
13263 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
13264
13265 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
13266 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
13267 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
13268
13269 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
13270
13271 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
13272 {
13273 adapter = adapter_node->pAdapter;
13274 if (NULL != adapter) {
13275 strlcpy(rps_data.ifname, adapter->dev->name,
13276 sizeof(rps_data.ifname));
13277 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
13278 (void *)&rps_data,sizeof(rps_data));
13279 }
13280 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
13281 adapter_node = next;
13282 }
13283}
13284
Masti, Narayanraddi26378462016-01-05 18:20:28 +053013285void wlan_hdd_schedule_defer_scan(struct work_struct *work)
13286{
13287 scan_context_t *scan_ctx =
13288 container_of(work, scan_context_t, scan_work.work);
13289
13290 if (NULL == scan_ctx)
13291 {
13292 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13293 FL("scan_ctx is NULL"));
13294 return;
13295 }
13296
13297 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
13298 return;
13299
13300 scan_ctx->attempt++;
13301
13302 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
13303#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13304 scan_ctx->dev,
13305#endif
13306 scan_ctx->scan_request);
13307}
13308
13309int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx,
13310 struct wiphy *wiphy,
13311#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13312 struct net_device *dev,
13313#endif
13314 struct cfg80211_scan_request *request)
13315{
13316 scan_context_t *scan_ctx;
13317
13318 ENTER();
13319 if (0 != (wlan_hdd_validate_context(pHddCtx)))
13320 {
13321 return -1;
13322 }
13323
13324 scan_ctx = &pHddCtx->scan_ctxt;
13325
13326 scan_ctx->wiphy = wiphy;
13327#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13328 scan_ctx->dev = dev;
13329#endif
13330
13331 scan_ctx->scan_request = request;
13332
13333 EXIT();
13334 return 0;
13335}
13336
13337void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
13338 struct wiphy *wiphy,
13339#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13340 struct net_device *dev,
13341#endif
13342 struct cfg80211_scan_request *request,
13343 unsigned long delay)
13344{
13345 if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic)
13346 {
13347#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13348 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request);
13349#else
13350 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request);
13351#endif
13352 pHddCtx->scan_ctxt.attempt = 0;
13353 pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC;
13354 }
13355 schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay);
13356}
13357
13358void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx)
13359{
13360 scan_ctx->magic = 0;
13361 scan_ctx->attempt = 0;
13362 scan_ctx->reject = 0;
13363 scan_ctx->scan_request = NULL;
13364
13365 return;
13366}
13367
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013368/**---------------------------------------------------------------------------
13369
Jeff Johnson295189b2012-06-20 16:38:30 -070013370 \brief hdd_wlan_startup() - HDD init function
13371
13372 This is the driver startup code executed once a WLAN device has been detected
13373
13374 \param - dev - Pointer to the underlying device
13375
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013376 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -070013377
13378 --------------------------------------------------------------------------*/
13379
13380int hdd_wlan_startup(struct device *dev )
13381{
13382 VOS_STATUS status;
13383 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070013384 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013385 hdd_context_t *pHddCtx = NULL;
13386 v_CONTEXT_t pVosContext= NULL;
13387#ifdef WLAN_BTAMP_FEATURE
13388 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
13389 WLANBAP_ConfigType btAmpConfig;
13390 hdd_config_t *pConfig;
13391#endif
13392 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013393 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013394 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -070013395
13396 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013397 /*
13398 * cfg80211: wiphy allocation
13399 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013400 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070013401
13402 if(wiphy == NULL)
13403 {
13404 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013405 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013406 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013407 pHddCtx = wiphy_priv(wiphy);
13408
Jeff Johnson295189b2012-06-20 16:38:30 -070013409 //Initialize the adapter context to zeros.
13410 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
13411
Jeff Johnson295189b2012-06-20 16:38:30 -070013412 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013413 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +053013414 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070013415
13416 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
13417
Siddharth Bhalcd92b782015-06-29 12:25:40 +053013418 /* register for riva power on lock to platform driver
13419 * Locking power early to ensure FW doesn't reset by kernel while
13420 * host driver is busy initializing itself */
13421 if (req_riva_power_on_lock("wlan"))
13422 {
13423 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
13424 __func__);
13425 goto err_free_hdd_context;
13426 }
13427
Jeff Johnson295189b2012-06-20 16:38:30 -070013428 /*Get vos context here bcoz vos_open requires it*/
13429 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13430
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -080013431 if(pVosContext == NULL)
13432 {
13433 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
13434 goto err_free_hdd_context;
13435 }
13436
Jeff Johnson295189b2012-06-20 16:38:30 -070013437 //Save the Global VOSS context in adapter context for future.
13438 pHddCtx->pvosContext = pVosContext;
13439
13440 //Save the adapter context in global context for future.
13441 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
13442
Jeff Johnson295189b2012-06-20 16:38:30 -070013443 pHddCtx->parent_dev = dev;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053013444 pHddCtx->last_scan_reject_session_id = 0xFF;
13445 pHddCtx->last_scan_reject_reason = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013446 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053013447 pHddCtx->scan_reject_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013448
13449 init_completion(&pHddCtx->full_pwr_comp_var);
13450 init_completion(&pHddCtx->standby_comp_var);
13451 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013452 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013453 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +053013454 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053013455 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053013456 init_completion(&pHddCtx->mc_sus_event_var);
13457 init_completion(&pHddCtx->tx_sus_event_var);
13458 init_completion(&pHddCtx->rx_sus_event_var);
13459
Amar Singhala49cbc52013-10-08 18:37:44 -070013460
mukul sharma4bd8d2e2015-08-13 20:33:25 +053013461 hdd_init_ll_stats_ctx(pHddCtx);
Anurag Chouhan6ee81542017-02-09 18:09:27 +053013462 hdd_init_nud_stats_ctx(pHddCtx);
mukul sharma4bd8d2e2015-08-13 20:33:25 +053013463
Amar Singhala49cbc52013-10-08 18:37:44 -070013464#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -070013465 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -070013466#else
13467 init_completion(&pHddCtx->driver_crda_req);
13468#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013469
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +053013470#ifdef WLAN_FEATURE_EXTSCAN
13471 init_completion(&pHddCtx->ext_scan_context.response_event);
13472#endif /* WLAN_FEATURE_EXTSCAN */
13473
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013474 spin_lock_init(&pHddCtx->schedScan_lock);
Kapil Gupta137ef892016-12-13 19:38:00 +053013475 vos_spin_lock_init(&pHddCtx->sap_update_info_lock);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013476
Jeff Johnson295189b2012-06-20 16:38:30 -070013477 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
13478
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053013479 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
13480 hdd_processSpoofMacAddrRequest);
Kapil Gupta137ef892016-12-13 19:38:00 +053013481 vos_init_work(&pHddCtx->sap_start_work, hdd_sap_restart_handle);
Abhishek Singh78c691f2017-11-30 13:48:44 +053013482 vos_init_delayed_work(&pHddCtx->ecsa_chan_change_work,
13483 hdd_force_scc_with_ecsa_handle);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053013484
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013485#ifdef FEATURE_WLAN_TDLS
13486 /* tdls_lock is initialized before an hdd_open_adapter ( which is
13487 * invoked by other instances also) to protect the concurrent
13488 * access for the Adapters by TDLS module.
13489 */
13490 mutex_init(&pHddCtx->tdls_lock);
13491#endif
Siddharth Bhal76972212014-10-15 16:22:51 +053013492 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +053013493 mutex_init(&pHddCtx->wmmLock);
13494
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +053013495 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +053013496 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013497
Agarwal Ashish1f422872014-07-22 00:11:55 +053013498 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013499 // Load all config first as TL config is needed during vos_open
13500 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
13501 if(pHddCtx->cfg_ini == NULL)
13502 {
13503 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
13504 goto err_free_hdd_context;
13505 }
13506
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053013507 hdd_request_manager_init();
13508
Jeff Johnson295189b2012-06-20 16:38:30 -070013509 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
13510
13511 // Read and parse the qcom_cfg.ini file
13512 status = hdd_parse_config_ini( pHddCtx );
13513 if ( VOS_STATUS_SUCCESS != status )
13514 {
13515 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
13516 __func__, WLAN_INI_FILE);
13517 goto err_config;
13518 }
Arif Hussaind5218912013-12-05 01:10:55 -080013519#ifdef MEMORY_DEBUG
13520 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
13521 vos_mem_init();
13522
13523 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
13524 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
13525#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013526
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +053013527 /* INI has been read, initialise the configuredMcastBcastFilter with
13528 * INI value as this will serve as the default value
13529 */
13530 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
13531 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
13532 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013533
13534 if (false == hdd_is_5g_supported(pHddCtx))
13535 {
13536 //5Ghz is not supported.
13537 if (1 != pHddCtx->cfg_ini->nBandCapability)
13538 {
13539 hddLog(VOS_TRACE_LEVEL_INFO,
13540 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
13541 pHddCtx->cfg_ini->nBandCapability = 1;
13542 }
13543 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013544
13545 /* If SNR Monitoring is enabled, FW has to parse all beacons
13546 * for calcaluting and storing the average SNR, so set Nth beacon
13547 * filter to 1 to enable FW to parse all the beaocons
13548 */
13549 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
13550 {
13551 /* The log level is deliberately set to WARN as overriding
13552 * nthBeaconFilter to 1 will increase power cosumption and this
13553 * might just prove helpful to detect the power issue.
13554 */
13555 hddLog(VOS_TRACE_LEVEL_WARN,
13556 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
13557 pHddCtx->cfg_ini->nthBeaconFilter = 1;
13558 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013559 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013560 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -070013561 */
Manjeet Singh61016fa2016-12-02 11:10:19 +053013562 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
Jeff Johnson295189b2012-06-20 16:38:30 -070013563 {
Manjeet Singh61016fa2016-12-02 11:10:19 +053013564 hddLog(VOS_TRACE_LEVEL_FATAL,
13565 "%s: wlan_hdd_cfg80211_init return failure", __func__);
13566 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070013567 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013568
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013569 // Update VOS trace levels based upon the cfg.ini
13570 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
13571 pHddCtx->cfg_ini->vosTraceEnableBAP);
13572 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
13573 pHddCtx->cfg_ini->vosTraceEnableTL);
13574 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
13575 pHddCtx->cfg_ini->vosTraceEnableWDI);
13576 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
13577 pHddCtx->cfg_ini->vosTraceEnableHDD);
13578 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
13579 pHddCtx->cfg_ini->vosTraceEnableSME);
13580 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
13581 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +053013582 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
13583 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013584 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
13585 pHddCtx->cfg_ini->vosTraceEnableWDA);
13586 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
13587 pHddCtx->cfg_ini->vosTraceEnableSYS);
13588 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
13589 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013590 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
13591 pHddCtx->cfg_ini->vosTraceEnableSAP);
13592 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
13593 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013594
Jeff Johnson295189b2012-06-20 16:38:30 -070013595 // Update WDI trace levels based upon the cfg.ini
13596 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
13597 pHddCtx->cfg_ini->wdiTraceEnableDAL);
13598 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
13599 pHddCtx->cfg_ini->wdiTraceEnableCTL);
13600 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
13601 pHddCtx->cfg_ini->wdiTraceEnableDAT);
13602 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
13603 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -070013604
Jeff Johnson88ba7742013-02-27 14:36:02 -080013605 if (VOS_FTM_MODE == hdd_get_conparam())
13606 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013607 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
13608 {
13609 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
13610 goto err_free_hdd_context;
13611 }
13612 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +053013613 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +053013614 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -070013615 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -080013616 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013617
Katya Nigame7b69a82015-04-28 15:24:06 +053013618 if( VOS_MONITOR_MODE == hdd_get_conparam())
13619 {
13620 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
13621 {
13622 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
13623 goto err_free_hdd_context;
13624 }
13625 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
13626 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
13627 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
13628 return VOS_STATUS_SUCCESS;
13629 }
13630
Jeff Johnson88ba7742013-02-27 14:36:02 -080013631 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -070013632 if(pHddCtx->cfg_ini->fIsLogpEnabled)
13633 {
13634 status = vos_watchdog_open(pVosContext,
13635 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
13636
13637 if(!VOS_IS_STATUS_SUCCESS( status ))
13638 {
13639 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Ashish Kumar Dhanotiya532bdef2017-05-09 17:31:59 +053013640 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070013641 }
13642 }
13643
13644 pHddCtx->isLogpInProgress = FALSE;
13645 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
13646
Amar Singhala49cbc52013-10-08 18:37:44 -070013647#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070013648 /* initialize the NV module. This is required so that
13649 we can initialize the channel information in wiphy
13650 from the NV.bin data. The channel information in
13651 wiphy needs to be initialized before wiphy registration */
13652
13653 status = vos_nv_open();
13654 if (!VOS_IS_STATUS_SUCCESS(status))
13655 {
13656 /* NV module cannot be initialized */
13657 hddLog( VOS_TRACE_LEVEL_FATAL,
13658 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +053013659 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -070013660 }
13661
13662 status = vos_init_wiphy_from_nv_bin();
13663 if (!VOS_IS_STATUS_SUCCESS(status))
13664 {
13665 /* NV module cannot be initialized */
13666 hddLog( VOS_TRACE_LEVEL_FATAL,
13667 "%s: vos_init_wiphy failed", __func__);
13668 goto err_vos_nv_close;
13669 }
13670
Amar Singhala49cbc52013-10-08 18:37:44 -070013671#endif
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013672 //Initialize the nlink service
13673 if(nl_srv_init() != 0)
13674 {
13675 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
13676 goto err_vos_nv_close;
13677 }
13678
13679#ifdef WLAN_KD_READY_NOTIFIER
13680 pHddCtx->kd_nl_init = 1;
13681#endif /* WLAN_KD_READY_NOTIFIER */
13682
Girish Gowlibf0e1ab2015-01-19 16:05:16 +053013683 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053013684 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070013685 if ( !VOS_IS_STATUS_SUCCESS( status ))
13686 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013687 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013688 goto err_nl_srv;
Jeff Johnson295189b2012-06-20 16:38:30 -070013689 }
13690
Jeff Johnson295189b2012-06-20 16:38:30 -070013691 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
13692
13693 if ( NULL == pHddCtx->hHal )
13694 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013695 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013696 goto err_vosclose;
13697 }
13698
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013699 status = vos_preStart( pHddCtx->pvosContext );
13700 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13701 {
13702 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013703 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013704 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013705
Arif Hussaineaf68602013-12-30 23:10:44 -080013706 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
13707 {
13708 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
13709 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
13710 __func__, enable_dfs_chan_scan);
13711 }
13712 if (0 == enable_11d || 1 == enable_11d)
13713 {
13714 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
13715 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
13716 __func__, enable_11d);
13717 }
13718
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013719 /* Note that the vos_preStart() sequence triggers the cfg download.
13720 The cfg download must occur before we update the SME config
13721 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -070013722 status = hdd_set_sme_config( pHddCtx );
13723
13724 if ( VOS_STATUS_SUCCESS != status )
13725 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013726 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013727 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013728 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013729
Jeff Johnson295189b2012-06-20 16:38:30 -070013730 /* In the integrated architecture we update the configuration from
13731 the INI file and from NV before vOSS has been started so that
13732 the final contents are available to send down to the cCPU */
13733
13734 // Apply the cfg.ini to cfg.dat
13735 if (FALSE == hdd_update_config_dat(pHddCtx))
13736 {
13737 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013738 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013739 }
13740
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013741 // Get mac addr from platform driver
13742 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
13743
13744 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013745 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013746 /* Store the mac addr for first interface */
13747 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
13748
13749 hddLog(VOS_TRACE_LEVEL_ERROR,
13750 "%s: WLAN Mac Addr: "
13751 MAC_ADDRESS_STR, __func__,
13752 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
13753
13754 /* Here, passing Arg2 as 1 because we do not want to change the
13755 last 3 bytes (means non OUI bytes) of first interface mac
13756 addr.
13757 */
13758 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
13759 {
13760 hddLog(VOS_TRACE_LEVEL_ERROR,
13761 "%s: Failed to generate wlan interface mac addr "
13762 "using MAC from ini file ", __func__);
13763 }
13764 }
13765 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
13766 {
13767 // Apply the NV to cfg.dat
13768 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070013769#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
13770 /* There was not a valid set of MAC Addresses in NV. See if the
13771 default addresses were modified by the cfg.ini settings. If so,
13772 we'll use them, but if not, we'll autogenerate a set of MAC
13773 addresses based upon the device serial number */
13774
13775 static const v_MACADDR_t default_address =
13776 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070013777
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013778 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
13779 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013780 {
13781 /* cfg.ini has the default address, invoke autogen logic */
13782
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013783 /* Here, passing Arg2 as 0 because we want to change the
13784 last 3 bytes (means non OUI bytes) of all the interfaces
13785 mac addr.
13786 */
13787 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
13788 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070013789 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013790 hddLog(VOS_TRACE_LEVEL_ERROR,
13791 "%s: Failed to generate wlan interface mac addr "
13792 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
13793 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070013794 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013795 }
13796 else
13797#endif //WLAN_AUTOGEN_MACADDR_FEATURE
13798 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013799 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013800 "%s: Invalid MAC address in NV, using MAC from ini file "
13801 MAC_ADDRESS_STR, __func__,
13802 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
13803 }
13804 }
13805 {
13806 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013807
13808 /* Set the MAC Address Currently this is used by HAL to
13809 * add self sta. Remove this once self sta is added as
13810 * part of session open.
13811 */
Jeff Johnson295189b2012-06-20 16:38:30 -070013812 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
13813 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
13814 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013815
Jeff Johnson295189b2012-06-20 16:38:30 -070013816 if (!HAL_STATUS_SUCCESS( halStatus ))
13817 {
13818 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
13819 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013820 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013821 }
13822 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013823
13824 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
13825 Note: Firmware image will be read and downloaded inside vos_start API */
13826 status = vos_start( pHddCtx->pvosContext );
13827 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13828 {
13829 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053013830 if (isSsrPanicOnFailure())
13831 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013832 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013833 }
13834
Leo Chang6cec3e22014-01-21 15:33:49 -080013835#ifdef FEATURE_WLAN_CH_AVOID
13836 /* Plug in avoid channel notification callback
13837 * This should happen before ADD_SELF_STA
13838 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053013839
13840 /* check the Channel Avoidance is enabled */
13841 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
13842 {
13843 sme_AddChAvoidCallback(pHddCtx->hHal,
13844 hdd_hostapd_ch_avoid_cb);
13845 }
Leo Chang6cec3e22014-01-21 15:33:49 -080013846#endif /* FEATURE_WLAN_CH_AVOID */
13847
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070013848 /* Exchange capability info between Host and FW and also get versioning info from FW */
13849 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070013850
Agarwal Ashishad9281b2014-06-10 14:57:30 +053013851#ifdef CONFIG_ENABLE_LINUX_REG
13852 status = wlan_hdd_init_channels(pHddCtx);
13853 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13854 {
13855 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
13856 __func__);
13857 goto err_vosstop;
13858 }
13859#endif
13860
Jeff Johnson295189b2012-06-20 16:38:30 -070013861 status = hdd_post_voss_start_config( pHddCtx );
13862 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13863 {
13864 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
13865 __func__);
13866 goto err_vosstop;
13867 }
Amar Singhala49cbc52013-10-08 18:37:44 -070013868
13869#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013870 wlan_hdd_cfg80211_update_reg_info( wiphy );
13871
13872 /* registration of wiphy dev with cfg80211 */
13873 if (0 > wlan_hdd_cfg80211_register(wiphy))
13874 {
13875 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
13876 goto err_vosstop;
13877 }
Amar Singhala49cbc52013-10-08 18:37:44 -070013878#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013879
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013880#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013881 /* registration of wiphy dev with cfg80211 */
13882 if (0 > wlan_hdd_cfg80211_register(wiphy))
13883 {
13884 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
13885 goto err_vosstop;
13886 }
13887
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013888 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013889 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13890 {
13891 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
13892 __func__);
13893 goto err_unregister_wiphy;
13894 }
13895#endif
13896
c_hpothu4a298be2014-12-22 21:12:51 +053013897 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
13898
Jeff Johnson295189b2012-06-20 16:38:30 -070013899 if (VOS_STA_SAP_MODE == hdd_get_conparam())
13900 {
13901 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
13902 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13903 }
13904 else
13905 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013906 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
13907 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13908 if (pAdapter != NULL)
13909 {
Katya Nigama7d81d72014-11-12 12:44:34 +053013910 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070013911 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053013912 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
13913 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
13914 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070013915
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053013916 /* Generate the P2P Device Address. This consists of the device's
13917 * primary MAC address with the locally administered bit set.
13918 */
13919 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070013920 }
13921 else
13922 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053013923 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
13924 if (p2p_dev_addr != NULL)
13925 {
13926 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
13927 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
13928 }
13929 else
13930 {
13931 hddLog(VOS_TRACE_LEVEL_FATAL,
13932 "%s: Failed to allocate mac_address for p2p_device",
13933 __func__);
13934 goto err_close_adapter;
13935 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013936 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013937
13938 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
13939 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
13940 if ( NULL == pP2pAdapter )
13941 {
13942 hddLog(VOS_TRACE_LEVEL_FATAL,
13943 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013944 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070013945 goto err_close_adapter;
13946 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013947 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013948 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013949
13950 if( pAdapter == NULL )
13951 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013952 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
13953 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070013954 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013955
Arif Hussain66559122013-11-21 10:11:40 -080013956 if (country_code)
13957 {
13958 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080013959 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080013960 hdd_checkandupdate_dfssetting(pAdapter, country_code);
13961#ifndef CONFIG_ENABLE_LINUX_REG
13962 hdd_checkandupdate_phymode(pAdapter, country_code);
13963#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080013964 ret = sme_ChangeCountryCode(pHddCtx->hHal,
13965 (void *)(tSmeChangeCountryCallback)
13966 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080013967 country_code,
13968 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053013969 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080013970 if (eHAL_STATUS_SUCCESS == ret)
13971 {
Arif Hussaincb607082013-12-20 11:57:42 -080013972 ret = wait_for_completion_interruptible_timeout(
13973 &pAdapter->change_country_code,
13974 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
13975
13976 if (0 >= ret)
13977 {
13978 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13979 "%s: SME while setting country code timed out", __func__);
13980 }
Arif Hussain66559122013-11-21 10:11:40 -080013981 }
13982 else
13983 {
Arif Hussaincb607082013-12-20 11:57:42 -080013984 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13985 "%s: SME Change Country code from module param fail ret=%d",
13986 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080013987 }
13988 }
13989
Jeff Johnson295189b2012-06-20 16:38:30 -070013990#ifdef WLAN_BTAMP_FEATURE
13991 vStatus = WLANBAP_Open(pVosContext);
13992 if(!VOS_IS_STATUS_SUCCESS(vStatus))
13993 {
13994 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13995 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070013996 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070013997 }
13998
13999 vStatus = BSL_Init(pVosContext);
14000 if(!VOS_IS_STATUS_SUCCESS(vStatus))
14001 {
14002 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14003 "%s: Failed to Init BSL",__func__);
14004 goto err_bap_close;
14005 }
14006 vStatus = WLANBAP_Start(pVosContext);
14007 if (!VOS_IS_STATUS_SUCCESS(vStatus))
14008 {
14009 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14010 "%s: Failed to start TL",__func__);
14011 goto err_bap_close;
14012 }
14013
14014 pConfig = pHddCtx->cfg_ini;
14015 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
14016 status = WLANBAP_SetConfig(&btAmpConfig);
14017
14018#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070014019
Mihir Shete9c238772014-10-15 14:35:16 +053014020 /*
14021 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
14022 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
14023 * which is greater than 0xf. So the below check is safe to make
14024 * sure that there is no entry for UapsdMask in the ini
14025 */
14026 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
14027 {
14028 if(IS_DYNAMIC_WMM_PS_ENABLED)
14029 {
14030 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
14031 __func__);
14032 pHddCtx->cfg_ini->UapsdMask =
14033 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
14034 }
14035 else
14036 {
14037 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
14038 __func__);
14039 pHddCtx->cfg_ini->UapsdMask =
14040 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
14041 }
14042 }
14043
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070014044#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
14045 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
14046 {
14047 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
14048 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
14049 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
14050 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
14051 }
14052#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014053
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014054 wlan_hdd_tdls_init(pHddCtx);
14055
Masti, Narayanraddi26378462016-01-05 18:20:28 +053014056 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
14057
14058 vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work,
14059 wlan_hdd_schedule_defer_scan);
14060
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053014061 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
14062
Jeff Johnson295189b2012-06-20 16:38:30 -070014063 /* Register with platform driver as client for Suspend/Resume */
14064 status = hddRegisterPmOps(pHddCtx);
14065 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14066 {
14067 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
14068#ifdef WLAN_BTAMP_FEATURE
14069 goto err_bap_stop;
14070#else
Jeff Johnsone7245742012-09-05 17:12:55 -070014071 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070014072#endif //WLAN_BTAMP_FEATURE
14073 }
14074
Yue Ma0d4891e2013-08-06 17:01:45 -070014075 /* Open debugfs interface */
14076 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
14077 {
14078 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14079 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070014080 }
14081
Jeff Johnson295189b2012-06-20 16:38:30 -070014082 /* Register TM level change handler function to the platform */
14083 status = hddDevTmRegisterNotifyCallback(pHddCtx);
14084 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14085 {
14086 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
14087 goto err_unregister_pmops;
14088 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014089
Jeff Johnson295189b2012-06-20 16:38:30 -070014090 // register net device notifier for device change notification
14091 ret = register_netdevice_notifier(&hdd_netdev_notifier);
14092
14093 if(ret < 0)
14094 {
14095 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053014096 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070014097 }
14098
Jeff Johnson295189b2012-06-20 16:38:30 -070014099 //Initialize the BTC service
14100 if(btc_activate_service(pHddCtx) != 0)
14101 {
14102 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053014103 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070014104 }
14105
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053014106#ifdef FEATURE_OEM_DATA_SUPPORT
14107 //Initialize the OEM service
14108 if (oem_activate_service(pHddCtx) != 0)
14109 {
14110 hddLog(VOS_TRACE_LEVEL_FATAL,
14111 "%s: oem_activate_service failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014112 goto err_btc_activate_service;
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053014113 }
14114#endif
14115
Jeff Johnson295189b2012-06-20 16:38:30 -070014116#ifdef PTT_SOCK_SVC_ENABLE
14117 //Initialize the PTT service
14118 if(ptt_sock_activate_svc(pHddCtx) != 0)
14119 {
14120 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014121 goto err_oem_activate_service;
Jeff Johnson295189b2012-06-20 16:38:30 -070014122 }
14123#endif
14124
Abhishek Singh00b71972016-01-07 10:51:04 +053014125#ifdef WLAN_FEATURE_RMC
14126 if (hdd_open_cesium_nl_sock() < 0)
14127 {
14128 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014129 goto err_ptt_sock_activate_svc;
Abhishek Singh00b71972016-01-07 10:51:04 +053014130 }
14131#endif
14132
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014133#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14134 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
14135 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053014136 if(wlan_logging_sock_activate_svc(
14137 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053014138 pHddCtx->cfg_ini->wlanLoggingNumBuf,
14139 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
14140 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053014141 {
14142 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
14143 " failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014144 goto err_open_cesium_nl_sock;
Deepthi Gowri78083a32014-11-04 12:55:51 +053014145 }
14146 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
14147 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053014148 if (!pHddCtx->cfg_ini->gEnableDebugLog)
14149 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053014150 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
14151 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014152 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014153
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014154 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
14155 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053014156 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053014157 pHddCtx->cfg_ini->enableContFWLogging ||
14158 pHddCtx->cfg_ini->enableFwrMemDump )
14159 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014160 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014161 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014162 }
14163 else
14164 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014165 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014166 }
14167
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014168#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014169
Agrawal Ashish17ef5082016-10-17 18:33:21 +053014170#ifdef SAP_AUTH_OFFLOAD
14171 if (!sme_IsFeatureSupportedByFW(SAP_OFFLOADS))
14172 {
14173 hddLog(VOS_TRACE_LEVEL_INFO, FL(" SAP AUTH OFFLOAD not supp by FW"));
14174 pHddCtx->cfg_ini->enable_sap_auth_offload = 0;
14175 }
14176#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014177
Sushant Kaushik215778f2015-05-21 14:05:36 +053014178 if (vos_is_multicast_logging())
14179 wlan_logging_set_log_level();
14180
Jeff Johnson295189b2012-06-20 16:38:30 -070014181 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070014182 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070014183 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070014184 /* Action frame registered in one adapter which will
14185 * applicable to all interfaces
14186 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053014187 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014188 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014189
14190 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053014191 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070014192
Jeff Johnsone7245742012-09-05 17:12:55 -070014193#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
14194 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014195 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070014196 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014197
Jeff Johnsone7245742012-09-05 17:12:55 -070014198#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080014199 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014200 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080014201 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014202
Jeff Johnsone7245742012-09-05 17:12:55 -070014203
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014204 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
14205 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070014206
Katya Nigam5c306ea2014-06-19 15:39:54 +053014207 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070014208 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014209 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053014210
14211#ifdef FEATURE_WLAN_SCAN_PNO
14212 /*SME must send channel update configuration to RIVA*/
14213 sme_UpdateChannelConfig(pHddCtx->hHal);
14214#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053014215 /* Send the update default channel list to the FW*/
14216 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053014217
14218 /* Fwr capabilities received, Set the Dot11 mode */
Abhishek Singh41ebce12016-02-03 10:43:21 +053014219 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
14220 hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode));
Mukul Sharma45063942015-04-01 20:07:59 +053014221 sme_SetDefDot11Mode(pHddCtx->hHal);
14222
Abhishek Singha306a442013-11-07 18:39:01 +053014223#ifndef CONFIG_ENABLE_LINUX_REG
14224 /*updating wiphy so that regulatory user hints can be processed*/
14225 if (wiphy)
14226 {
14227 regulatory_hint(wiphy, "00");
14228 }
14229#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070014230 // Initialize the restart logic
14231 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053014232
Hanumanth Reddy Pothula146bca42016-11-08 12:01:07 +053014233 if (pHddCtx->cfg_ini->fIsLogpEnabled) {
14234 vos_wdthread_init_timer_work(vos_process_wd_timer);
14235 /* Initialize the timer to detect thread stuck issues */
14236 vos_thread_stuck_timer_init(
14237 &((VosContextType*)pVosContext)->vosWatchdog);
14238 }
14239
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070014240 //Register the traffic monitor timer now
14241 if ( pHddCtx->cfg_ini->dynSplitscan)
14242 {
14243 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
14244 VOS_TIMER_TYPE_SW,
14245 hdd_tx_rx_pkt_cnt_stat_timer_handler,
14246 (void *)pHddCtx);
14247 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053014248 wlan_hdd_cfg80211_nan_init(pHddCtx);
14249
Bhargav Shahd0715912015-10-01 18:17:37 +053014250 mutex_init(&pHddCtx->cur_rx_level_lock);
14251 vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
14252 hdd_tcp_delack_compute_function,(void *)pHddCtx);
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053014253 vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW,
14254 wlan_hdd_change_tdls_mode, (void *)pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +053014255
Dino Mycle6fb96c12014-06-10 11:52:40 +053014256#ifdef WLAN_FEATURE_EXTSCAN
14257 sme_EXTScanRegisterCallback(pHddCtx->hHal,
14258 wlan_hdd_cfg80211_extscan_callback,
14259 pHddCtx);
14260#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014261
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053014262#ifdef FEATURE_OEM_DATA_SUPPORT
14263 sme_OemDataRegisterCallback(pHddCtx->hHal,
14264 wlan_hdd_cfg80211_oemdata_callback,
14265 pHddCtx);
14266#endif /* FEATURE_OEM_DATA_SUPPORT */
14267
Gupta, Kapil7c34b322015-09-30 13:12:35 +053014268 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014269#ifdef WLAN_NS_OFFLOAD
14270 // Register IPv6 notifier to notify if any change in IP
14271 // So that we can reconfigure the offload parameters
14272 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
14273 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
14274 if (ret)
14275 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014276 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014277 }
14278 else
14279 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014280 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014281 }
14282#endif
14283
Sravan Kumar Kairamb0edc612016-10-26 13:55:24 +053014284 vos_mem_set((uint8_t *)&pHddCtx->bad_sta, HDD_MAX_STA_COUNT, 0);
14285
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014286 // Register IPv4 notifier to notify if any change in IP
14287 // So that we can reconfigure the offload parameters
14288 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
14289 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
14290 if (ret)
14291 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014292 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014293 }
14294 else
14295 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014296 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014297 }
c_manjeecfd1efb2015-09-25 19:32:34 +053014298 /*Fw mem dump procfs initialization*/
14299 memdump_init();
Bhargav shah23c94942015-10-13 12:48:35 +053014300 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014301
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053014302 pHddCtx->is_ap_mode_wow_supported =
14303 sme_IsFeatureSupportedByFW(SAP_MODE_WOW);
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053014304
Hanumanth Reddy Pothulae92bcc12017-05-19 13:56:35 +053014305 pHddCtx->is_fatal_event_log_sup =
14306 sme_IsFeatureSupportedByFW(FATAL_EVENT_LOGGING);
14307 hddLog(VOS_TRACE_LEVEL_INFO, FL("FATAL_EVENT_LOGGING: %d"),
14308 pHddCtx->is_fatal_event_log_sup);
14309
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053014310 hdd_assoc_registerFwdEapolCB(pVosContext);
14311
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053014312 mutex_init(&pHddCtx->cache_channel_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070014313 goto success;
14314
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014315err_open_cesium_nl_sock:
14316#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14317 hdd_close_cesium_nl_sock();
14318#endif
14319
14320err_ptt_sock_activate_svc:
14321#ifdef PTT_SOCK_SVC_ENABLE
14322 ptt_sock_deactivate_svc(pHddCtx);
14323#endif
14324
14325err_oem_activate_service:
14326#ifdef FEATURE_OEM_DATA_SUPPORT
14327 oem_deactivate_service();
14328#endif
14329
14330err_btc_activate_service:
14331 btc_deactivate_service();
14332
Jeff Johnson295189b2012-06-20 16:38:30 -070014333err_reg_netdev:
14334 unregister_netdevice_notifier(&hdd_netdev_notifier);
14335
Jeff Johnson295189b2012-06-20 16:38:30 -070014336err_unregister_pmops:
14337 hddDevTmUnregisterNotifyCallback(pHddCtx);
14338 hddDeregisterPmOps(pHddCtx);
14339
Yue Ma0d4891e2013-08-06 17:01:45 -070014340 hdd_debugfs_exit(pHddCtx);
14341
Jeff Johnson295189b2012-06-20 16:38:30 -070014342#ifdef WLAN_BTAMP_FEATURE
14343err_bap_stop:
14344 WLANBAP_Stop(pVosContext);
14345#endif
14346
14347#ifdef WLAN_BTAMP_FEATURE
14348err_bap_close:
14349 WLANBAP_Close(pVosContext);
14350#endif
14351
Jeff Johnson295189b2012-06-20 16:38:30 -070014352err_close_adapter:
14353 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053014354#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053014355err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053014356#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053014357 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053014358 hdd_wlan_free_wiphy_channels(wiphy);
14359
Jeff Johnson295189b2012-06-20 16:38:30 -070014360err_vosstop:
14361 vos_stop(pVosContext);
14362
Amar Singhala49cbc52013-10-08 18:37:44 -070014363err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070014364 status = vos_sched_close( pVosContext );
14365 if (!VOS_IS_STATUS_SUCCESS(status)) {
14366 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
14367 "%s: Failed to close VOSS Scheduler", __func__);
14368 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
14369 }
Amar Singhala49cbc52013-10-08 18:37:44 -070014370 vos_close(pVosContext );
14371
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053014372err_nl_srv:
14373#ifdef WLAN_KD_READY_NOTIFIER
14374 nl_srv_exit(pHddCtx->ptt_pid);
14375#else
14376 nl_srv_exit();
14377#endif /* WLAN_KD_READY_NOTIFIER */
Amar Singhal0a402232013-10-11 20:57:16 -070014378err_vos_nv_close:
14379
c_hpothue6a36282014-03-19 12:27:38 +053014380#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070014381 vos_nv_close();
14382
c_hpothu70f8d812014-03-22 22:59:23 +053014383#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014384
14385err_wdclose:
14386 if(pHddCtx->cfg_ini->fIsLogpEnabled)
14387 vos_watchdog_close(pVosContext);
14388
Jeff Johnson295189b2012-06-20 16:38:30 -070014389err_config:
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053014390 hdd_request_manager_deinit();
Jeff Johnson295189b2012-06-20 16:38:30 -070014391 kfree(pHddCtx->cfg_ini);
14392 pHddCtx->cfg_ini= NULL;
14393
14394err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014395 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053014396 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070014397 wiphy_free(wiphy) ;
14398 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070014399 VOS_BUG(1);
14400
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080014401 if (hdd_is_ssr_required())
14402 {
14403 /* WDI timeout had happened during load, so SSR is needed here */
14404 subsystem_restart("wcnss");
14405 msleep(5000);
14406 }
14407 hdd_set_ssr_required (VOS_FALSE);
14408
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014409 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070014410
14411success:
14412 EXIT();
14413 return 0;
14414}
14415
14416/**---------------------------------------------------------------------------
14417
Jeff Johnson32d95a32012-09-10 13:15:23 -070014418 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070014419
Jeff Johnson32d95a32012-09-10 13:15:23 -070014420 This is the driver entry point - called in different timeline depending
14421 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070014422
14423 \param - None
14424
14425 \return - 0 for success, non zero for failure
14426
14427 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070014428static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070014429{
14430 VOS_STATUS status;
14431 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014432 struct device *dev = NULL;
14433 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014434#ifdef HAVE_WCNSS_CAL_DOWNLOAD
14435 int max_retries = 0;
14436#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014437#ifdef HAVE_CBC_DONE
14438 int max_cbc_retries = 0;
14439#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014440
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014441#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14442 wlan_logging_sock_init_svc();
14443#endif
14444
Jeff Johnson295189b2012-06-20 16:38:30 -070014445 ENTER();
14446
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014447 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070014448
14449 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
14450 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
14451
Jeff Johnson295189b2012-06-20 16:38:30 -070014452#ifdef ANI_BUS_TYPE_PCI
14453
14454 dev = wcnss_wlan_get_device();
14455
14456#endif // ANI_BUS_TYPE_PCI
14457
14458#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014459
14460#ifdef HAVE_WCNSS_CAL_DOWNLOAD
14461 /* wait until WCNSS driver downloads NV */
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053014462 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014463 msleep(1000);
14464 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014465
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053014466 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014467 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014468 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014469#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14470 wlan_logging_sock_deinit_svc();
14471#endif
14472
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014473 return -ENODEV;
14474 }
14475#endif
14476
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014477#ifdef HAVE_CBC_DONE
14478 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
14479 msleep(1000);
14480 }
14481 if (max_cbc_retries >= 10) {
14482 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
14483 }
14484#endif
14485
Jeff Johnson295189b2012-06-20 16:38:30 -070014486 dev = wcnss_wlan_get_device();
14487#endif // ANI_BUS_TYPE_PLATFORM
14488
14489
14490 do {
14491 if (NULL == dev) {
14492 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
14493 ret_status = -1;
14494 break;
14495 }
14496
Jeff Johnson295189b2012-06-20 16:38:30 -070014497#ifdef TIMER_MANAGER
14498 vos_timer_manager_init();
14499#endif
14500
14501 /* Preopen VOSS so that it is ready to start at least SAL */
14502 status = vos_preOpen(&pVosContext);
14503
14504 if (!VOS_IS_STATUS_SUCCESS(status))
14505 {
14506 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
14507 ret_status = -1;
14508 break;
14509 }
14510
Sushant Kaushik02beb352015-06-04 15:15:01 +053014511 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053014512 hdd_register_debug_callback();
14513
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014514#ifndef MODULE
14515 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
14516 */
14517 hdd_set_conparam((v_UINT_t)con_mode);
14518#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014519
14520 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014521 if (hdd_wlan_startup(dev))
14522 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014523 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014524 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014525 vos_preClose( &pVosContext );
14526 ret_status = -1;
14527 break;
14528 }
14529
Jeff Johnson295189b2012-06-20 16:38:30 -070014530 } while (0);
14531
14532 if (0 != ret_status)
14533 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014534#ifdef TIMER_MANAGER
14535 vos_timer_exit();
14536#endif
14537#ifdef MEMORY_DEBUG
14538 vos_mem_exit();
14539#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014540 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014541#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14542 wlan_logging_sock_deinit_svc();
14543#endif
14544
Jeff Johnson295189b2012-06-20 16:38:30 -070014545 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
14546 }
14547 else
14548 {
14549 //Send WLAN UP indication to Nlink Service
14550 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
14551
14552 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070014553 }
14554
14555 EXIT();
14556
14557 return ret_status;
14558}
14559
Jeff Johnson32d95a32012-09-10 13:15:23 -070014560/**---------------------------------------------------------------------------
14561
14562 \brief hdd_module_init() - Init Function
14563
14564 This is the driver entry point (invoked when module is loaded using insmod)
14565
14566 \param - None
14567
14568 \return - 0 for success, non zero for failure
14569
14570 --------------------------------------------------------------------------*/
14571#ifdef MODULE
14572static int __init hdd_module_init ( void)
14573{
14574 return hdd_driver_init();
14575}
Jeff Johnson32d95a32012-09-10 13:15:23 -070014576#else /* #ifdef MODULE */
14577static int __init hdd_module_init ( void)
14578{
14579 /* Driver initialization is delayed to fwpath_changed_handler */
14580 return 0;
14581}
Jeff Johnson32d95a32012-09-10 13:15:23 -070014582#endif /* #ifdef MODULE */
14583
Jeff Johnson295189b2012-06-20 16:38:30 -070014584
14585/**---------------------------------------------------------------------------
14586
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014587 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070014588
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014589 This is the driver exit point (invoked when module is unloaded using rmmod
14590 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070014591
14592 \param - None
14593
14594 \return - None
14595
14596 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014597static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070014598{
14599 hdd_context_t *pHddCtx = NULL;
14600 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053014601 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053014602 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014603
14604 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
14605
14606 //Get the global vos context
14607 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14608
14609 if(!pVosContext)
14610 {
14611 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
14612 goto done;
14613 }
14614
14615 //Get the HDD context.
14616 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
14617
14618 if(!pHddCtx)
14619 {
14620 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
14621 }
Katya Nigame7b69a82015-04-28 15:24:06 +053014622 else if (VOS_MONITOR_MODE == hdd_get_conparam())
14623 {
14624 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
14625 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
14626 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
14627 hdd_wlan_exit(pHddCtx);
14628 vos_preClose( &pVosContext );
14629 goto done;
14630 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014631 else
14632 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053014633 /* We wait for active entry threads to exit from driver
14634 * by waiting until rtnl_lock is available.
14635 */
14636 rtnl_lock();
14637 rtnl_unlock();
14638
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014639 INIT_COMPLETION(pHddCtx->ssr_comp_var);
14640 if ((pHddCtx->isLogpInProgress) && (FALSE ==
14641 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
14642 {
Siddharth Bhala204f572015-01-17 02:03:36 +053014643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014644 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053014645 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
14646 msecs_to_jiffies(30000));
14647 if(!rc)
14648 {
14649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14650 "%s:SSR timedout, fatal error", __func__);
14651 VOS_BUG(0);
14652 }
14653 }
14654
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014655 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
14656 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070014657
c_hpothu8adb97b2014-12-08 19:38:20 +053014658 /* Driver Need to send country code 00 in below condition
14659 * 1) If gCountryCodePriority is set to 1; and last country
14660 * code set is through 11d. This needs to be done in case
14661 * when NV country code is 00.
14662 * This Needs to be done as when kernel store last country
14663 * code and if stored country code is not through 11d,
14664 * in sme_HandleChangeCountryCodeByUser we will disable 11d
14665 * in next load/unload as soon as we get any country through
14666 * 11d. In sme_HandleChangeCountryCodeByUser
14667 * pMsg->countryCode will be last countryCode and
14668 * pMac->scan.countryCode11d will be country through 11d so
14669 * due to mismatch driver will disable 11d.
14670 *
14671 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053014672
c_hpothu8adb97b2014-12-08 19:38:20 +053014673 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053014674 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053014675 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053014676 {
14677 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053014678 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053014679 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
14680 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053014681
c_hpothu8adb97b2014-12-08 19:38:20 +053014682 //Do all the cleanup before deregistering the driver
14683 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070014684 }
14685
Jeff Johnson295189b2012-06-20 16:38:30 -070014686 vos_preClose( &pVosContext );
14687
14688#ifdef TIMER_MANAGER
14689 vos_timer_exit();
14690#endif
14691#ifdef MEMORY_DEBUG
14692 vos_mem_exit();
14693#endif
14694
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014695#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14696 wlan_logging_sock_deinit_svc();
14697#endif
14698
Jeff Johnson295189b2012-06-20 16:38:30 -070014699done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014700 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014701
Jeff Johnson295189b2012-06-20 16:38:30 -070014702 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
14703}
14704
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014705/**---------------------------------------------------------------------------
14706
14707 \brief hdd_module_exit() - Exit function
14708
14709 This is the driver exit point (invoked when module is unloaded using rmmod)
14710
14711 \param - None
14712
14713 \return - None
14714
14715 --------------------------------------------------------------------------*/
14716static void __exit hdd_module_exit(void)
14717{
14718 hdd_driver_exit();
14719}
14720
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014721#ifdef MODULE
14722static int fwpath_changed_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014723 const struct kernel_param *kp)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014724{
Jeff Johnson76052702013-04-16 13:55:05 -070014725 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014726}
14727
14728static int con_mode_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014729 const struct kernel_param *kp)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014730{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070014731 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014732}
14733#else /* #ifdef MODULE */
14734/**---------------------------------------------------------------------------
14735
Jeff Johnson76052702013-04-16 13:55:05 -070014736 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014737
Jeff Johnson76052702013-04-16 13:55:05 -070014738 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014739 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070014740 - invoked when module parameter fwpath is modified from userspace to signal
14741 initializing the WLAN driver or when con_mode is modified from userspace
14742 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014743
14744 \return - 0 for success, non zero for failure
14745
14746 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070014747static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014748{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014749 int ret_status;
14750
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014751 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014752 ret_status = hdd_driver_init();
14753 wlan_hdd_inited = ret_status ? 0 : 1;
14754 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014755 }
14756
14757 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070014758
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014759 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070014760
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014761 ret_status = hdd_driver_init();
14762 wlan_hdd_inited = ret_status ? 0 : 1;
14763 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014764}
14765
Jeff Johnson295189b2012-06-20 16:38:30 -070014766/**---------------------------------------------------------------------------
14767
Jeff Johnson76052702013-04-16 13:55:05 -070014768 \brief fwpath_changed_handler() - Handler Function
14769
14770 Handle changes to the fwpath parameter
14771
14772 \return - 0 for success, non zero for failure
14773
14774 --------------------------------------------------------------------------*/
14775static int fwpath_changed_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014776 const struct kernel_param *kp)
Jeff Johnson76052702013-04-16 13:55:05 -070014777{
14778 int ret;
14779
14780 ret = param_set_copystring(kmessage, kp);
14781 if (0 == ret)
14782 ret = kickstart_driver();
14783 return ret;
14784}
14785
14786/**---------------------------------------------------------------------------
14787
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014788 \brief con_mode_handler() -
14789
14790 Handler function for module param con_mode when it is changed by userspace
14791 Dynamically linked - do nothing
14792 Statically linked - exit and init driver, as in rmmod and insmod
14793
Jeff Johnson76052702013-04-16 13:55:05 -070014794 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014795
Jeff Johnson76052702013-04-16 13:55:05 -070014796 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014797
14798 --------------------------------------------------------------------------*/
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014799static int con_mode_handler(const char *kmessage,
14800 const struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014801{
Jeff Johnson76052702013-04-16 13:55:05 -070014802 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014803
Jeff Johnson76052702013-04-16 13:55:05 -070014804 ret = param_set_int(kmessage, kp);
14805 if (0 == ret)
14806 ret = kickstart_driver();
14807 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014808}
14809#endif /* #ifdef MODULE */
14810
14811/**---------------------------------------------------------------------------
14812
Jeff Johnson295189b2012-06-20 16:38:30 -070014813 \brief hdd_get_conparam() -
14814
14815 This is the driver exit point (invoked when module is unloaded using rmmod)
14816
14817 \param - None
14818
14819 \return - tVOS_CON_MODE
14820
14821 --------------------------------------------------------------------------*/
14822tVOS_CON_MODE hdd_get_conparam ( void )
14823{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014824#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070014825 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014826#else
14827 return (tVOS_CON_MODE)curr_con_mode;
14828#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014829}
14830void hdd_set_conparam ( v_UINT_t newParam )
14831{
14832 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014833#ifndef MODULE
14834 curr_con_mode = con_mode;
14835#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014836}
14837/**---------------------------------------------------------------------------
14838
14839 \brief hdd_softap_sta_deauth() - function
14840
14841 This to take counter measure to handle deauth req from HDD
14842
14843 \param - pAdapter - Pointer to the HDD
14844
14845 \param - enable - boolean value
14846
14847 \return - None
14848
14849 --------------------------------------------------------------------------*/
14850
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014851VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
14852 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070014853{
Jeff Johnson295189b2012-06-20 16:38:30 -070014854 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014855 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014856 struct hdd_cache_sta_info *cache_sta_info;
14857 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014858
14859 ENTER();
14860
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014861 hddLog(LOG1, "hdd_softap_sta_deauth:(%pK, false)",
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070014862 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014863
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014864 if (!pSapCtx) {
14865 hddLog(LOGE, "sap context is NULL");
14866 return vosStatus;
14867 }
14868
14869 cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
14870 pDelStaParams->peerMacAddr);
14871 if (cache_sta_info) {
14872 cache_sta_info->reason_code = pDelStaParams->reason_code;
14873 cache_sta_info->rx_rate =
14874 wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
14875 WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
14876 &cache_sta_info->rssi);
14877 }
14878
Jeff Johnson295189b2012-06-20 16:38:30 -070014879 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014880 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014881 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070014882
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014883 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070014884
14885 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014886 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070014887}
14888
14889/**---------------------------------------------------------------------------
14890
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014891 \brief hdd_del_all_sta() - function
14892
14893 This function removes all the stations associated on stopping AP/P2P GO.
14894
14895 \param - pAdapter - Pointer to the HDD
14896
14897 \return - None
14898
14899 --------------------------------------------------------------------------*/
14900
14901int hdd_del_all_sta(hdd_adapter_t *pAdapter)
14902{
14903 v_U16_t i;
14904 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014905 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14906 ptSapContext pSapCtx = NULL;
14907 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14908 if(pSapCtx == NULL){
14909 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14910 FL("psapCtx is NULL"));
14911 return 1;
14912 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014913 ENTER();
14914
14915 hddLog(VOS_TRACE_LEVEL_INFO,
14916 "%s: Delete all STAs associated.",__func__);
14917 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
14918 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
14919 )
14920 {
14921 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
14922 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014923 if ((pSapCtx->aStaInfo[i].isUsed) &&
14924 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014925 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014926 struct tagCsrDelStaParams delStaParams;
14927
14928 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014929 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014930 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
14931 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014932 &delStaParams);
14933 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014934 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014935 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014936 }
14937 }
14938 }
14939
14940 EXIT();
14941 return 0;
14942}
14943
14944/**---------------------------------------------------------------------------
14945
Jeff Johnson295189b2012-06-20 16:38:30 -070014946 \brief hdd_softap_sta_disassoc() - function
14947
14948 This to take counter measure to handle deauth req from HDD
14949
14950 \param - pAdapter - Pointer to the HDD
14951
14952 \param - enable - boolean value
14953
14954 \return - None
14955
14956 --------------------------------------------------------------------------*/
14957
14958void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
14959{
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014960 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14961 struct hdd_cache_sta_info *cache_sta_info;
14962 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014963
14964 ENTER();
14965
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014966 hddLog( LOGE, "hdd_softap_sta_disassoc:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014967
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014968 if (!pSapCtx) {
14969 hddLog(LOGE, "sap context is NULL");
14970 return ;
14971 }
14972
Jeff Johnson295189b2012-06-20 16:38:30 -070014973 //Ignore request to disassoc bcmc station
14974 if( pDestMacAddress[0] & 0x1 )
14975 return;
14976
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014977 cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
14978 pDestMacAddress);
14979 if (cache_sta_info) {
14980 cache_sta_info->reason_code = eSIR_MAC_DEAUTH_LEAVING_BSS_REASON;
14981 cache_sta_info->rx_rate =
14982 wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
14983 WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
14984 &cache_sta_info->rssi);
14985 }
14986
Jeff Johnson295189b2012-06-20 16:38:30 -070014987 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
14988}
14989
14990void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
14991{
14992 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14993
14994 ENTER();
14995
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014996 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014997
14998 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
14999}
15000
Jeff Johnson295189b2012-06-20 16:38:30 -070015001/**---------------------------------------------------------------------------
15002 *
15003 * \brief hdd_get__concurrency_mode() -
15004 *
15005 *
15006 * \param - None
15007 *
15008 * \return - CONCURRENCY MODE
15009 *
15010 * --------------------------------------------------------------------------*/
15011tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
15012{
15013 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
15014 hdd_context_t *pHddCtx;
15015
15016 if (NULL != pVosContext)
15017 {
15018 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
15019 if (NULL != pHddCtx)
15020 {
15021 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
15022 }
15023 }
15024
15025 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015026 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015027 return VOS_STA;
15028}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015029v_BOOL_t
15030wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
15031{
15032 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015033
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015034 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
15035 if (pAdapter == NULL)
15036 {
15037 hddLog(VOS_TRACE_LEVEL_INFO,
15038 FL("GO doesn't exist"));
15039 return TRUE;
15040 }
15041 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
15042 {
15043 hddLog(VOS_TRACE_LEVEL_INFO,
15044 FL("GO started"));
15045 return TRUE;
15046 }
15047 else
15048 /* wait till GO changes its interface to p2p device */
15049 hddLog(VOS_TRACE_LEVEL_INFO,
15050 FL("Del_bss called, avoid apps suspend"));
15051 return FALSE;
15052
15053}
Jeff Johnson295189b2012-06-20 16:38:30 -070015054/* Decide whether to allow/not the apps power collapse.
15055 * Allow apps power collapse if we are in connected state.
15056 * if not, allow only if we are in IMPS */
15057v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
15058{
15059 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080015060 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080015061 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070015062 hdd_config_t *pConfig = pHddCtx->cfg_ini;
15063 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15064 hdd_adapter_t *pAdapter = NULL;
15065 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080015066 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015067
Jeff Johnson295189b2012-06-20 16:38:30 -070015068 if (VOS_STA_SAP_MODE == hdd_get_conparam())
15069 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015070
Yathish9f22e662012-12-10 14:21:35 -080015071 concurrent_state = hdd_get_concurrency_mode();
15072
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015073 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
15074 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
15075 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080015076#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015077
Yathish9f22e662012-12-10 14:21:35 -080015078 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015079 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080015080 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
15081 return TRUE;
15082#endif
15083
Jeff Johnson295189b2012-06-20 16:38:30 -070015084 /*loop through all adapters. TBD fix for Concurrency */
15085 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15086 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15087 {
15088 pAdapter = pAdapterNode->pAdapter;
15089 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
15090 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15091 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080015092 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053015093 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053015094 && pmcState != STOPPED && pmcState != STANDBY &&
15095 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080015096 (eANI_BOOLEAN_TRUE == scanRspPending) ||
15097 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070015098 {
Mukul Sharma4be88422015-03-09 20:29:07 +053015099 if(pmcState == FULL_POWER &&
15100 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
15101 {
15102 /*
15103 * When SCO indication comes from Coex module , host will
15104 * enter in to full power mode, but this should not prevent
15105 * apps processor power collapse.
15106 */
15107 hddLog(LOG1,
15108 FL("Allow apps power collapse"
15109 "even when sco indication is set"));
15110 return TRUE;
15111 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080015112 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Deepthi Gowri03a979f2016-11-03 15:20:19 +053015113 "pmcState = %d scanRspPending = %d "
15114 "inMiddleOfRoaming = %d connected = %d",
15115 __func__, pmcState, scanRspPending,
15116 inMiddleOfRoaming, hdd_connIsConnected(
15117 WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )));
15118 wlan_hdd_get_tdls_stats(pAdapter);
15119 return FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015120 }
15121 }
15122 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15123 pAdapterNode = pNext;
15124 }
15125 return TRUE;
15126}
15127
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080015128/* Decides whether to send suspend notification to Riva
15129 * if any adapter is in BMPS; then it is required */
15130v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
15131{
15132 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
15133 hdd_config_t *pConfig = pHddCtx->cfg_ini;
15134
15135 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
15136 {
15137 return TRUE;
15138 }
15139 return FALSE;
15140}
15141
Jeff Johnson295189b2012-06-20 16:38:30 -070015142void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15143{
15144 switch(mode)
15145 {
Chilam Ngc4244af2013-04-01 15:37:32 -070015146 case VOS_STA_MODE:
15147 case VOS_P2P_CLIENT_MODE:
15148 case VOS_P2P_GO_MODE:
15149 case VOS_STA_SAP_MODE:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015150 case VOS_MONITOR_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070015151 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053015152 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070015153 break;
15154 default:
15155 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015156 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015157 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
15158 "Number of open sessions for mode %d = %d"),
15159 pHddCtx->concurrency_mode, mode,
15160 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070015161}
15162
15163
15164void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15165{
15166 switch(mode)
15167 {
Chilam Ngc4244af2013-04-01 15:37:32 -070015168 case VOS_STA_MODE:
15169 case VOS_P2P_CLIENT_MODE:
15170 case VOS_P2P_GO_MODE:
15171 case VOS_STA_SAP_MODE:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015172 case VOS_MONITOR_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053015173 pHddCtx->no_of_open_sessions[mode]--;
15174 if (!(pHddCtx->no_of_open_sessions[mode]))
15175 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015176 break;
15177 default:
15178 break;
15179 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015180 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
15181 "Number of open sessions for mode %d = %d"),
15182 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
15183
15184}
15185/**---------------------------------------------------------------------------
15186 *
15187 * \brief wlan_hdd_incr_active_session()
15188 *
15189 * This function increments the number of active sessions
15190 * maintained per device mode
15191 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
15192 * Incase of SAP/P2P GO upon bss start it is incremented
15193 *
15194 * \param pHddCtx - HDD Context
15195 * \param mode - device mode
15196 *
15197 * \return - None
15198 *
15199 * --------------------------------------------------------------------------*/
15200void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15201{
15202 switch (mode) {
15203 case VOS_STA_MODE:
15204 case VOS_P2P_CLIENT_MODE:
15205 case VOS_P2P_GO_MODE:
15206 case VOS_STA_SAP_MODE:
15207 pHddCtx->no_of_active_sessions[mode]++;
15208 break;
15209 default:
15210 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
15211 break;
15212 }
15213 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
15214 mode,
15215 pHddCtx->no_of_active_sessions[mode]);
15216}
15217
15218/**---------------------------------------------------------------------------
15219 *
15220 * \brief wlan_hdd_decr_active_session()
15221 *
15222 * This function decrements the number of active sessions
15223 * maintained per device mode
15224 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
15225 * Incase of SAP/P2P GO upon bss stop it is decremented
15226 *
15227 * \param pHddCtx - HDD Context
15228 * \param mode - device mode
15229 *
15230 * \return - None
15231 *
15232 * --------------------------------------------------------------------------*/
15233void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15234{
Bhargav Shahd0715912015-10-01 18:17:37 +053015235
Agarwal Ashish51325b52014-06-16 16:50:49 +053015236 switch (mode) {
15237 case VOS_STA_MODE:
15238 case VOS_P2P_CLIENT_MODE:
15239 case VOS_P2P_GO_MODE:
15240 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053015241 if (pHddCtx->no_of_active_sessions[mode] > 0)
15242 pHddCtx->no_of_active_sessions[mode]--;
15243 else
15244 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
15245 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053015246 break;
15247 default:
15248 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
15249 break;
15250 }
15251 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
15252 mode,
15253 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070015254}
15255
Jeff Johnsone7245742012-09-05 17:12:55 -070015256/**---------------------------------------------------------------------------
15257 *
15258 * \brief wlan_hdd_restart_init
15259 *
15260 * This function initalizes restart timer/flag. An internal function.
15261 *
15262 * \param - pHddCtx
15263 *
15264 * \return - None
15265 *
15266 * --------------------------------------------------------------------------*/
15267
15268static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
15269{
15270 /* Initialize */
15271 pHddCtx->hdd_restart_retries = 0;
15272 atomic_set(&pHddCtx->isRestartInProgress, 0);
15273 vos_timer_init(&pHddCtx->hdd_restart_timer,
15274 VOS_TIMER_TYPE_SW,
15275 wlan_hdd_restart_timer_cb,
15276 pHddCtx);
15277}
15278/**---------------------------------------------------------------------------
15279 *
15280 * \brief wlan_hdd_restart_deinit
15281 *
15282 * This function cleans up the resources used. An internal function.
15283 *
15284 * \param - pHddCtx
15285 *
15286 * \return - None
15287 *
15288 * --------------------------------------------------------------------------*/
15289
15290static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
15291{
15292
15293 VOS_STATUS vos_status;
15294 /* Block any further calls */
15295 atomic_set(&pHddCtx->isRestartInProgress, 1);
15296 /* Cleanup */
15297 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
15298 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015299 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070015300 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
15301 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015302 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070015303
15304}
15305
15306/**---------------------------------------------------------------------------
15307 *
15308 * \brief wlan_hdd_framework_restart
15309 *
15310 * This function uses a cfg80211 API to start a framework initiated WLAN
15311 * driver module unload/load.
15312 *
15313 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
15314 *
15315 *
15316 * \param - pHddCtx
15317 *
15318 * \return - VOS_STATUS_SUCCESS: Success
15319 * VOS_STATUS_E_EMPTY: Adapter is Empty
15320 * VOS_STATUS_E_NOMEM: No memory
15321
15322 * --------------------------------------------------------------------------*/
15323
15324static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
15325{
15326 VOS_STATUS status = VOS_STATUS_SUCCESS;
15327 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015328 int len = (sizeof (struct ieee80211_mgmt));
15329 struct ieee80211_mgmt *mgmt = NULL;
15330
15331 /* Prepare the DEAUTH managment frame with reason code */
15332 mgmt = kzalloc(len, GFP_KERNEL);
15333 if(mgmt == NULL)
15334 {
15335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15336 "%s: memory allocation failed (%d bytes)", __func__, len);
15337 return VOS_STATUS_E_NOMEM;
15338 }
15339 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070015340
15341 /* Iterate over all adapters/devices */
15342 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015343 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
15344 {
15345 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015346 FL("fail to get adapter: %pK %d"), pAdapterNode, status);
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015347 goto end;
15348 }
15349
Jeff Johnsone7245742012-09-05 17:12:55 -070015350 do
15351 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015352 if(pAdapterNode->pAdapter &&
15353 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070015354 {
15355 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15356 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
15357 pAdapterNode->pAdapter->dev->name,
15358 pAdapterNode->pAdapter->device_mode,
15359 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015360 /*
15361 * CFG80211 event to restart the driver
15362 *
15363 * 'cfg80211_send_unprot_deauth' sends a
15364 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
15365 * of SME(Linux Kernel) state machine.
15366 *
15367 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
15368 * the driver.
15369 *
15370 */
Abhishek Singh00b71972016-01-07 10:51:04 +053015371
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053015372#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
15373 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
15374#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015375 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053015376#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070015377 }
15378 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15379 pAdapterNode = pNext;
15380 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
15381
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015382 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015383 /* Free the allocated management frame */
15384 kfree(mgmt);
15385
Jeff Johnsone7245742012-09-05 17:12:55 -070015386 /* Retry until we unload or reach max count */
15387 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
15388 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
15389
15390 return status;
15391
15392}
15393/**---------------------------------------------------------------------------
15394 *
15395 * \brief wlan_hdd_restart_timer_cb
15396 *
15397 * Restart timer callback. An internal function.
15398 *
15399 * \param - User data:
15400 *
15401 * \return - None
15402 *
15403 * --------------------------------------------------------------------------*/
15404
15405void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
15406{
15407 hdd_context_t *pHddCtx = usrDataForCallback;
15408 wlan_hdd_framework_restart(pHddCtx);
15409 return;
15410
15411}
15412
15413
15414/**---------------------------------------------------------------------------
15415 *
15416 * \brief wlan_hdd_restart_driver
15417 *
15418 * This function sends an event to supplicant to restart the WLAN driver.
15419 *
15420 * This function is called from vos_wlanRestart.
15421 *
15422 * \param - pHddCtx
15423 *
15424 * \return - VOS_STATUS_SUCCESS: Success
15425 * VOS_STATUS_E_EMPTY: Adapter is Empty
15426 * VOS_STATUS_E_ALREADY: Request already in progress
15427
15428 * --------------------------------------------------------------------------*/
15429VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
15430{
15431 VOS_STATUS status = VOS_STATUS_SUCCESS;
15432
15433 /* A tight check to make sure reentrancy */
15434 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
15435 {
Mihir Shetefd528652014-06-23 19:07:50 +053015436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070015437 "%s: WLAN restart is already in progress", __func__);
15438
15439 return VOS_STATUS_E_ALREADY;
15440 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070015441 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080015442#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053015443 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070015444#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070015445
Jeff Johnsone7245742012-09-05 17:12:55 -070015446 return status;
15447}
15448
Bhargav Shahd0715912015-10-01 18:17:37 +053015449/**
15450 * hdd_get_total_sessions() - provide total number of active sessions
15451 * @pHddCtx: Valid Global HDD context pointer
15452 *
15453 * This function iterates through pAdaptors and find the number of all active
15454 * sessions. This active sessions includes connected sta, p2p client and number
15455 * of client connected to sap/p2p go.
15456 *
15457 * Return: Total number of active sessions.
15458 */
15459v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx)
15460{
15461 v_U8_t active_session = 0;
15462 hdd_station_ctx_t *pHddStaCtx;
15463 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15464 hdd_adapter_t *pAdapter;
15465 VOS_STATUS status;
15466
15467 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
15468 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
15469 pAdapter = pAdapterNode->pAdapter;
15470 switch (pAdapter->device_mode) {
15471 case VOS_STA_MODE:
15472 case VOS_P2P_CLIENT_MODE:
15473 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15474 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15475 active_session += 1;
15476 break;
15477 case VOS_STA_SAP_MODE:
15478 case VOS_P2P_GO_MODE:
15479 active_session += hdd_softap_get_connected_sta(pAdapter);
15480 break;
15481 default:
15482 break;
15483 }
15484
15485 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
15486 pAdapterNode = pNext;
15487 }
15488
15489 return active_session;
15490}
15491
15492/**
15493 * hdd_set_delack_value() - Set delack value
15494 * @pHddCtx: Valid Global HDD context pointer
15495 * @next_rx_level: Value to set for delack
15496 *
15497 * This function compare present value and next value of delack. If the both
15498 * are diffrent then it sets next value .
15499 *
15500 * Return: void.
15501 */
15502void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
15503{
15504 if (pHddCtx->cur_rx_level != next_rx_level) {
Alok Kumarf3724462018-04-05 15:18:54 +053015505 struct wlan_rx_tp_data rx_tp_data = {0};
15506
Bhargav Shahd0715912015-10-01 18:17:37 +053015507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15508 "%s: TCP DELACK trigger level %d",
15509 __func__, next_rx_level);
15510 mutex_lock(&pHddCtx->cur_rx_level_lock);
15511 pHddCtx->cur_rx_level = next_rx_level;
15512 mutex_unlock(&pHddCtx->cur_rx_level_lock);
Alok Kumarf3724462018-04-05 15:18:54 +053015513
15514 rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
15515 rx_tp_data.level = next_rx_level;
15516
15517 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &rx_tp_data,
15518 sizeof(rx_tp_data));
Bhargav Shahd0715912015-10-01 18:17:37 +053015519 }
15520}
15521
15522/**
15523 * hdd_set_default_stop_delack_timer() - Start delack timer
15524 * @pHddCtx: Valid Global HDD context pointer
15525 *
15526 * This function stop delack timer and set delack value to default..
15527 *
15528 * Return: void.
15529 */
15530
15531void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
15532{
15533 if (VOS_TIMER_STATE_RUNNING !=
15534 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
15535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15536 "%s: Can not stop timer", __func__);
15537 return;
15538 }
15539
15540 vos_timer_stop(&pHddCtx->delack_timer);
Alok Kumarf3724462018-04-05 15:18:54 +053015541 hdd_set_delack_value(pHddCtx, WLAN_SVC_TP_LOW);
Bhargav Shahd0715912015-10-01 18:17:37 +053015542}
15543
15544/**
15545 * hdd_start_delack_timer() - Start delack timer
15546 * @pHddCtx: Valid Global HDD context pointer
15547 *
15548 * This function starts the delack timer for tcpDelAckComputeInterval time
15549 * interval.The default timer value is 2 second.
15550 *
15551 * Return: void.
15552 */
15553void hdd_start_delack_timer(hdd_context_t *pHddCtx)
15554{
15555 if (VOS_TIMER_STATE_RUNNING ==
15556 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
15557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15558 "%s: Timer is already running", __func__);
15559 return;
15560 }
15561
15562 vos_timer_start(&pHddCtx->delack_timer,
15563 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
15564}
15565
15566/**
15567 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
15568 * @pHddCtx: Valid Global HDD context pointer
15569 *
15570 * This function updates the prev_rx_packets count from the corresponding
15571 * pAdapter states. This prev_rx_packets will diffed with the packet count
15572 * at the end of delack timer. That can give number of RX packet is spacific
15573 * time.
15574 *
15575 * Return: void.
15576 */
15577void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
15578{
15579 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15580 hdd_adapter_t *pAdapter;
15581 VOS_STATUS status;
15582
15583 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15584 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
15585 pAdapter = pAdapterNode->pAdapter;
15586 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
15587 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15588 pAdapterNode = pNext;
15589 }
15590}
15591
15592/**
15593 * hdd_manage_delack_timer() - start\stop delack timer
15594 * @pHddCtx: Valid Global HDD context pointer
15595 *
15596 * This function check the number of concerent session present, it starts the
15597 * delack timer if only one session is present.
15598 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
15599 *
15600 * Return: void.
15601 */
15602void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
15603{
15604 uint8_t sessions;
15605
15606 if (!pHddCtx->cfg_ini->enable_delack) {
15607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15608 "%s: TCP DELACK is not enabled", __func__);
15609 return;
15610 }
15611
15612 /* Blindly stop timer of BTCOEX and TDLS Session is up */
15613 if (pHddCtx->mode != 0) {
15614 hdd_set_default_stop_delack_timer(pHddCtx);
15615 return;
15616 }
15617
15618 sessions = hdd_get_total_sessions(pHddCtx);
15619 if (sessions == 1) {
15620 hdd_update_prev_rx_packet_count(pHddCtx);
15621 hdd_start_delack_timer(pHddCtx);
15622 } else {
15623 hdd_set_default_stop_delack_timer(pHddCtx);
15624 }
15625}
15626
Mihir Shetee1093ba2014-01-21 20:13:32 +053015627/**---------------------------------------------------------------------------
15628 *
15629 * \brief wlan_hdd_init_channels
15630 *
15631 * This function is used to initialize the channel list in CSR
15632 *
15633 * This function is called from hdd_wlan_startup
15634 *
15635 * \param - pHddCtx: HDD context
15636 *
15637 * \return - VOS_STATUS_SUCCESS: Success
15638 * VOS_STATUS_E_FAULT: Failure reported by SME
15639
15640 * --------------------------------------------------------------------------*/
15641static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
15642{
15643 eHalStatus status;
15644
15645 status = sme_InitChannels(pHddCtx->hHal);
15646 if (HAL_STATUS_SUCCESS(status))
15647 {
15648 return VOS_STATUS_SUCCESS;
15649 }
15650 else
15651 {
15652 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
15653 __func__, status);
15654 return VOS_STATUS_E_FAULT;
15655 }
15656}
15657
Mihir Shete04206452014-11-20 17:50:58 +053015658#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053015659VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053015660{
15661 eHalStatus status;
15662
Agarwal Ashish6db9d532014-09-30 18:19:10 +053015663 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053015664 if (HAL_STATUS_SUCCESS(status))
15665 {
15666 return VOS_STATUS_SUCCESS;
15667 }
15668 else
15669 {
15670 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
15671 __func__, status);
15672 return VOS_STATUS_E_FAULT;
15673 }
15674}
Mihir Shete04206452014-11-20 17:50:58 +053015675#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070015676/*
15677 * API to find if there is any STA or P2P-Client is connected
15678 */
15679VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
15680{
15681 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
15682}
Jeff Johnsone7245742012-09-05 17:12:55 -070015683
Mihir Shetee2ae82a2015-03-16 14:08:49 +053015684
15685/*
15686 * API to find if the firmware will send logs using DXE channel
15687 */
15688v_U8_t hdd_is_fw_logging_enabled(void)
15689{
15690 hdd_context_t *pHddCtx;
15691
15692 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
15693 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
15694
Sachin Ahuja084313e2015-05-21 17:57:10 +053015695 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053015696}
15697
Agarwal Ashish57e84372014-12-05 18:26:53 +053015698/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053015699 * API to find if the firmware will send trace logs using DXE channel
15700 */
15701v_U8_t hdd_is_fw_ev_logging_enabled(void)
15702{
15703 hdd_context_t *pHddCtx;
15704
15705 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
15706 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
15707
15708 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
15709}
15710/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053015711 * API to find if there is any session connected
15712 */
15713VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
15714{
15715 return sme_is_any_session_connected(pHddCtx->hHal);
15716}
15717
15718
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015719int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
15720{
15721 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15722 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053015723 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053015724 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015725
15726 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053015727 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015728 if (pScanInfo->mScanPending)
15729 {
c_hpothua3d45d52015-01-05 14:11:17 +053015730 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
15731 eCSR_SCAN_ABORT_DEFAULT);
15732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15733 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015734
c_hpothua3d45d52015-01-05 14:11:17 +053015735 /* If there is active scan command lets wait for the completion else
15736 * there is no need to wait as scan command might be in the SME pending
15737 * command list.
15738 */
15739 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
15740 {
Mukul Sharmab392b642017-08-17 17:45:29 +053015741 status = wait_for_completion_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015742 &pScanInfo->abortscan_event_var,
15743 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053015744 if (0 >= status)
15745 {
15746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053015747 "%s: Timeout or Interrupt occurred while waiting for abort"
15748 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053015749 return -ETIMEDOUT;
15750 }
15751 }
15752 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
15753 {
15754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15755 FL("hdd_abort_mac_scan failed"));
15756 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015757 }
15758 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053015759 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015760}
15761
Abhishek Singh7d624e12015-11-30 14:29:27 +053015762/**
15763 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
15764 * user space
15765 * @frame_ind: Management frame data to be informed.
15766 *
15767 * This function is used to indicate management frame to
15768 * user space
15769 *
15770 * Return: None
15771 *
15772 */
15773void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
15774{
15775 hdd_context_t *hdd_ctx = NULL;
15776 hdd_adapter_t *adapter = NULL;
15777 v_CONTEXT_t vos_context = NULL;
15778
15779 /* Get the global VOSS context.*/
15780 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
15781 if (!vos_context) {
15782 hddLog(LOGE, FL("Global VOS context is Null"));
15783 return;
15784 }
15785 /* Get the HDD context.*/
15786 hdd_ctx =
15787 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
15788
15789 if (0 != wlan_hdd_validate_context(hdd_ctx))
15790 {
15791 return;
15792 }
15793 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
15794 frame_ind->sessionId);
15795
15796 if ((NULL != adapter) &&
15797 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
15798 __hdd_indicate_mgmt_frame(adapter,
15799 frame_ind->frameLen,
15800 frame_ind->frameBuf,
15801 frame_ind->frameType,
15802 frame_ind->rxChan,
15803 frame_ind->rxRssi);
15804 return;
15805
15806}
15807
c_hpothu225aa7c2014-10-22 17:45:13 +053015808VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
15809{
15810 hdd_adapter_t *pAdapter;
15811 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15812 VOS_STATUS vosStatus;
15813
15814 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15815 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
15816 {
15817 pAdapter = pAdapterNode->pAdapter;
15818 if (NULL != pAdapter)
15819 {
15820 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
15821 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
15822 WLAN_HDD_P2P_GO == pAdapter->device_mode)
15823 {
15824 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
15825 pAdapter->device_mode);
15826 if (VOS_STATUS_SUCCESS !=
15827 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
15828 {
15829 hddLog(LOGE, FL("failed to abort ROC"));
15830 return VOS_STATUS_E_FAILURE;
15831 }
15832 }
15833 }
15834 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15835 pAdapterNode = pNext;
15836 }
15837 return VOS_STATUS_SUCCESS;
15838}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053015839
Mihir Shete0be28772015-02-17 18:42:14 +053015840hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
15841{
15842 hdd_adapter_t *pAdapter;
15843 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15844 hdd_cfg80211_state_t *cfgState;
15845 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
15846 VOS_STATUS vosStatus;
15847
15848 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
15849 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
15850 {
15851 pAdapter = pAdapterNode->pAdapter;
15852 if (NULL != pAdapter)
15853 {
15854 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
15855 pRemainChanCtx = cfgState->remain_on_chan_ctx;
15856 if (pRemainChanCtx)
15857 break;
15858 }
15859 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
15860 pAdapterNode = pNext;
15861 }
15862 return pRemainChanCtx;
15863}
15864
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053015865/**
15866 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
15867 *
15868 * @pHddCtx: HDD context within host driver
15869 * @dfsScanMode: dfsScanMode passed from ioctl
15870 *
15871 */
15872
15873VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
15874 tANI_U8 dfsScanMode)
15875{
15876 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15877 hdd_adapter_t *pAdapter;
15878 VOS_STATUS vosStatus;
15879 hdd_station_ctx_t *pHddStaCtx;
15880 eHalStatus status = eHAL_STATUS_SUCCESS;
15881
15882 if(!pHddCtx)
15883 {
15884 hddLog(LOGE, FL("HDD context is Null"));
15885 return eHAL_STATUS_FAILURE;
15886 }
15887
15888 if (pHddCtx->scan_info.mScanPending)
15889 {
15890 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
15891 pHddCtx->scan_info.sessionId);
15892 hdd_abort_mac_scan(pHddCtx,
15893 pHddCtx->scan_info.sessionId,
15894 eCSR_SCAN_ABORT_DEFAULT);
15895 }
15896
15897 if (!dfsScanMode)
15898 {
15899 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
15900 while ((NULL != pAdapterNode) &&
15901 (VOS_STATUS_SUCCESS == vosStatus))
15902 {
15903 pAdapter = pAdapterNode->pAdapter;
15904
15905 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
15906 {
15907 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15908
15909 if(!pHddStaCtx)
15910 {
15911 hddLog(LOGE, FL("HDD STA context is Null"));
15912 return eHAL_STATUS_FAILURE;
15913 }
15914
15915 /* if STA is already connected on DFS channel,
15916 disconnect immediately*/
15917 if (hdd_connIsConnected(pHddStaCtx) &&
15918 (NV_CHANNEL_DFS ==
15919 vos_nv_getChannelEnabledState(
15920 pHddStaCtx->conn_info.operationChannel)))
15921 {
15922 status = sme_RoamDisconnect(pHddCtx->hHal,
15923 pAdapter->sessionId,
15924 eCSR_DISCONNECT_REASON_UNSPECIFIED);
15925 hddLog(LOG1, FL("Client connected on DFS channel %d,"
15926 "sme_RoamDisconnect returned with status: %d"
15927 "for sessionid: %d"), pHddStaCtx->conn_info.
15928 operationChannel, status, pAdapter->sessionId);
15929 }
15930 }
15931
15932 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
15933 &pNext);
15934 pAdapterNode = pNext;
15935 }
15936 }
15937
15938 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
15939 sme_UpdateDFSRoamMode(pHddCtx->hHal,
15940 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
15941
15942 status = sme_HandleDFSChanScan(pHddCtx->hHal);
15943 if (!HAL_STATUS_SUCCESS(status))
15944 {
15945 hddLog(LOGE,
15946 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
15947 return status;
15948 }
15949
15950 return status;
15951}
15952
Nirav Shah7e3c8132015-06-22 23:51:42 +053015953static int hdd_log2_ceil(unsigned value)
15954{
15955 /* need to switch to unsigned math so that negative values
15956 * will right-shift towards 0 instead of -1
15957 */
15958 unsigned tmp = value;
15959 int log2 = -1;
15960
15961 if (value == 0)
15962 return 0;
15963
15964 while (tmp) {
15965 log2++;
15966 tmp >>= 1;
15967 }
15968 if (1U << log2 != value)
15969 log2++;
15970
15971 return log2;
15972}
15973
15974/**
15975 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
15976 * @pAdapter: adapter handle
15977 *
15978 * Return: vos status
15979 */
15980VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
15981{
15982 int hash_elem, log2, i;
15983
15984 spin_lock_bh( &pAdapter->sta_hash_lock);
15985 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
15986 spin_unlock_bh( &pAdapter->sta_hash_lock);
15987 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15988 "%s: hash already attached for session id %d",
15989 __func__, pAdapter->sessionId);
15990 return VOS_STATUS_SUCCESS;
15991 }
15992 spin_unlock_bh( &pAdapter->sta_hash_lock);
15993
15994 hash_elem = WLAN_MAX_STA_COUNT;
15995 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
15996 log2 = hdd_log2_ceil(hash_elem);
15997 hash_elem = 1 << log2;
15998
15999 pAdapter->sta_id_hash.mask = hash_elem - 1;
16000 pAdapter->sta_id_hash.idx_bits = log2;
16001 pAdapter->sta_id_hash.bins =
16002 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
16003 if (!pAdapter->sta_id_hash.bins) {
16004 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16005 "%s: malloc failed for session %d",
16006 __func__, pAdapter->sessionId);
16007 return VOS_STATUS_E_NOMEM;
16008 }
16009
16010 for (i = 0; i < hash_elem; i++)
16011 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
16012
16013 spin_lock_bh( &pAdapter->sta_hash_lock);
16014 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
16015 spin_unlock_bh( &pAdapter->sta_hash_lock);
16016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16017 "%s: Station ID Hash attached for session id %d",
16018 __func__, pAdapter->sessionId);
16019
16020 return VOS_STATUS_SUCCESS;
16021}
16022
16023/**
16024 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
16025 * @pAdapter: adapter handle
16026 *
16027 * Return: vos status
16028 */
16029VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
16030{
16031 int hash_elem, i;
16032 v_SIZE_t size;
16033
16034 spin_lock_bh( &pAdapter->sta_hash_lock);
16035 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16036 spin_unlock_bh( &pAdapter->sta_hash_lock);
16037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16038 "%s: hash not initialized for session id %d",
16039 __func__, pAdapter->sessionId);
16040 return VOS_STATUS_SUCCESS;
16041 }
16042
16043 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
16044 spin_unlock_bh( &pAdapter->sta_hash_lock);
16045
16046 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
16047
16048 /* free all station info*/
16049 for (i = 0; i < hash_elem; i++) {
16050 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
16051 if (size != 0) {
16052 VOS_STATUS status;
16053 hdd_staid_hash_node_t *sta_info_node = NULL;
16054 hdd_staid_hash_node_t *next_node = NULL;
16055 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
16056 (hdd_list_node_t**) &sta_info_node );
16057
16058 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16059 {
16060 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
16061 &sta_info_node->node);
16062 vos_mem_free(sta_info_node);
16063
16064 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
16065 (hdd_list_node_t*)sta_info_node,
16066 (hdd_list_node_t**)&next_node);
16067 sta_info_node = next_node;
16068 }
16069 }
16070 }
16071
16072 vos_mem_free(pAdapter->sta_id_hash.bins);
16073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16074 "%s: Station ID Hash detached for session id %d",
16075 __func__, pAdapter->sessionId);
16076 return VOS_STATUS_SUCCESS;
16077}
16078
16079/**
16080 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
16081 * @pAdapter: adapter handle
16082 * @mac_addr_in: input mac address
16083 *
16084 * Return: index derived from mac address
16085 */
16086int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
16087 v_MACADDR_t *mac_addr_in)
16088{
16089 uint16 index;
16090 struct hdd_align_mac_addr_t * mac_addr =
16091 (struct hdd_align_mac_addr_t *)mac_addr_in;
16092
16093 index = mac_addr->bytes_ab ^
16094 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
16095 index ^= index >> pAdapter->sta_id_hash.idx_bits;
16096 index &= pAdapter->sta_id_hash.mask;
16097 return index;
16098}
16099
16100/**
16101 * hdd_sta_id_hash_add_entry() - add entry in hash
16102 * @pAdapter: adapter handle
16103 * @sta_id: station id
16104 * @mac_addr: mac address
16105 *
16106 * Return: vos status
16107 */
16108VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
16109 v_U8_t sta_id, v_MACADDR_t *mac_addr)
16110{
16111 uint16 index;
16112 hdd_staid_hash_node_t *sta_info_node = NULL;
16113
Nirav Shah7e3c8132015-06-22 23:51:42 +053016114 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
16115 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
16116 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053016117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16118 "%s: malloc failed", __func__);
16119 return VOS_STATUS_E_NOMEM;
16120 }
16121
16122 sta_info_node->sta_id = sta_id;
16123 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
16124
Nirav Shah303ed5c2015-08-24 10:29:25 +053016125 spin_lock_bh( &pAdapter->sta_hash_lock);
16126 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16127 spin_unlock_bh( &pAdapter->sta_hash_lock);
16128 vos_mem_free(sta_info_node);
16129 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16130 "%s: hash is not initialized for session id %d",
16131 __func__, pAdapter->sessionId);
16132 return VOS_STATUS_E_FAILURE;
16133 }
16134
Nirav Shah7e3c8132015-06-22 23:51:42 +053016135 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
16136 (hdd_list_node_t*) sta_info_node );
16137 spin_unlock_bh( &pAdapter->sta_hash_lock);
16138 return VOS_STATUS_SUCCESS;
16139}
16140
16141/**
16142 * hdd_sta_id_hash_remove_entry() - remove entry from hash
16143 * @pAdapter: adapter handle
16144 * @sta_id: station id
16145 * @mac_addr: mac address
16146 *
16147 * Return: vos status
16148 */
16149VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
16150 v_U8_t sta_id, v_MACADDR_t *mac_addr)
16151{
16152 uint16 index;
16153 VOS_STATUS status;
16154 hdd_staid_hash_node_t *sta_info_node = NULL;
16155 hdd_staid_hash_node_t *next_node = NULL;
16156
16157 spin_lock_bh( &pAdapter->sta_hash_lock);
16158 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16159 spin_unlock_bh( &pAdapter->sta_hash_lock);
16160 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16161 "%s: hash is not initialized for session id %d",
16162 __func__, pAdapter->sessionId);
16163 return VOS_STATUS_E_FAILURE;
16164 }
16165
16166 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
16167 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
16168 (hdd_list_node_t**) &sta_info_node );
16169
16170 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16171 {
16172 if (sta_info_node->sta_id == sta_id) {
16173 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
16174 &sta_info_node->node);
16175 vos_mem_free(sta_info_node);
16176 break;
16177 }
16178 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
16179 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
16180 sta_info_node = next_node;
16181 }
16182 spin_unlock_bh( &pAdapter->sta_hash_lock);
16183 return status;
16184}
16185
16186/**
16187 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
16188 * @pAdapter: adapter handle
16189 * @mac_addr_in: mac address
16190 *
16191 * Return: station id
16192 */
16193int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
16194 v_MACADDR_t *mac_addr_in)
16195{
16196 uint8 is_found = 0;
16197 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
16198 uint16 index;
16199 VOS_STATUS status;
16200 hdd_staid_hash_node_t *sta_info_node = NULL;
16201 hdd_staid_hash_node_t *next_node = NULL;
16202
16203 spin_lock_bh( &pAdapter->sta_hash_lock);
16204 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16205 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053016206 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053016207 FL("hash is not initialized for session id %d"),
16208 pAdapter->sessionId);
16209 return HDD_WLAN_INVALID_STA_ID;
16210 }
16211
16212 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
16213 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
16214 (hdd_list_node_t**) &sta_info_node );
16215
16216 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16217 {
16218 if (vos_mem_compare(&sta_info_node->mac_addr,
16219 mac_addr_in, sizeof(v_MACADDR_t))) {
16220 is_found = 1;
16221 sta_id = sta_info_node->sta_id;
16222 break;
16223 }
16224 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
16225 (hdd_list_node_t*)sta_info_node,
16226 (hdd_list_node_t**)&next_node);
16227 sta_info_node = next_node;
16228 }
16229 spin_unlock_bh( &pAdapter->sta_hash_lock);
16230 return sta_id;
16231}
16232
c_manjeecfd1efb2015-09-25 19:32:34 +053016233/*FW memory dump feature*/
16234/**
16235 * This structure hold information about the /proc file
16236 *
16237 */
16238static struct proc_dir_entry *proc_file, *proc_dir;
16239
16240/**
16241 * memdump_read() - perform read operation in memory dump proc file
16242 *
16243 * @file - handle for the proc file.
16244 * @buf - pointer to user space buffer.
16245 * @count - number of bytes to be read.
16246 * @pos - offset in the from buffer.
16247 *
16248 * This function performs read operation for the memory dump proc file.
16249 *
16250 * Return: number of bytes read on success, error code otherwise.
16251 */
16252static ssize_t memdump_read(struct file *file, char __user *buf,
16253 size_t count, loff_t *pos)
16254{
16255 int status;
16256 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
16257 size_t ret_count;
c_manjeef1495642015-10-13 18:35:01 +053016258 loff_t bytes_left;
c_manjeecfd1efb2015-09-25 19:32:34 +053016259 ENTER();
16260
16261 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
16262 status = wlan_hdd_validate_context(hdd_ctx);
16263 if (0 != status) {
16264 return -EINVAL;
16265 }
16266
16267 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
16268 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
16269 return -EINVAL;
16270 }
16271
16272 /* run fs_read_handler in an atomic context*/
16273 vos_ssr_protect(__func__);
c_manjeef1495642015-10-13 18:35:01 +053016274 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left);
16275 if(bytes_left == 0)
c_manjeecfd1efb2015-09-25 19:32:34 +053016276 {
16277 /*Free the fwr mem dump buffer */
16278 wlan_free_fwr_mem_dump_buffer();
16279 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeef1495642015-10-13 18:35:01 +053016280 ret_count=0;
c_manjeecfd1efb2015-09-25 19:32:34 +053016281 }
16282 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
16283 vos_ssr_unprotect(__func__);
16284 EXIT();
16285 return ret_count;
16286}
16287
16288/**
16289 * struct memdump_fops - file operations for memory dump feature
16290 * @read - read function for memory dump operation.
16291 *
16292 * This structure initialize the file operation handle for memory
16293 * dump feature
16294 */
16295static const struct file_operations memdump_fops = {
16296 read: memdump_read
16297};
16298
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016299struct fw_mem_dump_priv {
16300 uint32_t status;
16301};
16302
c_manjeecfd1efb2015-09-25 19:32:34 +053016303/*
16304* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
16305* To be passed by HDD to WDA and called upon receiving of response
16306* from firmware
16307* @fwMemDumpReqContext : memory dump request context
16308* @dump_rsp : dump response from HAL
16309* Returns none
16310*/
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016311void wlan_hdd_fw_mem_dump_cb(void *context,
c_manjeecfd1efb2015-09-25 19:32:34 +053016312 tAniFwrDumpRsp *dump_rsp)
16313{
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016314 struct hdd_request *request;
16315 struct fw_mem_dump_priv *priv;
c_manjeecfd1efb2015-09-25 19:32:34 +053016316
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016317 request = hdd_request_get(context);
16318 if (!request) {
16319 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
16320 return;
16321 }
c_manjeecfd1efb2015-09-25 19:32:34 +053016322
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016323 ENTER();
16324
16325 priv = hdd_request_priv(request);
16326 priv->status = dump_rsp->dump_status;
16327
16328 /* report the status to requesting function and free mem.*/
16329 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
16330 hddLog(LOGE, FL("fw dump request declined by fwr"));
16331 //set the request completion variable
16332 hdd_request_complete(request);
16333 //Free the allocated fwr dump
16334 wlan_free_fwr_mem_dump_buffer();
16335 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
16336 } else {
16337 hddLog(LOG1, FL("fw dump request accepted by fwr"));
16338 /* register the HDD callback which will be called by SVC */
16339 wlan_set_svc_fw_mem_dump_req_cb(
16340 (void*)wlan_hdd_fw_mem_dump_req_cb,
16341 context);
16342 }
16343
16344 hdd_request_put(request);
16345
16346 EXIT();
c_manjeecfd1efb2015-09-25 19:32:34 +053016347}
16348
16349/**
16350 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
16351 *
16352 * This function removes file/dir under proc file system that was
16353 * processing firmware memory dump
16354 *
16355 * Return: None
16356 */
16357static void memdump_procfs_remove(void)
16358{
16359 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
16360 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
16361 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
16362 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
16363 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
16364}
16365
16366/**
16367 * memdump_procfs_init() - Initialize procfs for memory dump
16368 *
16369 * @vos_ctx - Global vos context.
16370 *
16371 * This function create file under proc file system to be used later for
16372 * processing firmware memory dump
16373 *
16374 * Return: 0 on success, error code otherwise.
16375 */
16376static int memdump_procfs_init(void *vos_ctx)
16377{
16378 hdd_context_t *hdd_ctx;
16379
16380 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16381 if (!hdd_ctx) {
16382 hddLog(LOGE , FL("Invalid HDD context"));
16383 return -EINVAL;
16384 }
16385
16386 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
16387 if (proc_dir == NULL) {
16388 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
16389 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
16390 PROCFS_MEMDUMP_DIR);
16391 return -ENOMEM;
16392 }
16393
16394 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
16395 S_IRUSR | S_IWUSR, proc_dir,
16396 &memdump_fops, hdd_ctx);
16397 if (proc_file == NULL) {
16398 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
16399 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
16400 PROCFS_MEMDUMP_NAME);
16401 return -ENOMEM;
16402 }
16403
16404 hddLog(LOG1 , FL("/proc/%s/%s created"),
16405 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
16406
16407 return 0;
16408}
16409
16410/**
16411 * memdump_init() - Initialization function for memory dump feature
16412 *
16413 * This function creates proc file for memdump feature and registers
16414 * HDD callback function with SME.
16415 *
16416 * Return - 0 on success, error otherwise
16417 */
16418int memdump_init(void)
16419{
16420 hdd_context_t *hdd_ctx;
16421 void *vos_ctx;
16422 int status = 0;
16423
16424 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
16425 if (!vos_ctx) {
16426 hddLog(LOGE, FL("Invalid VOS context"));
16427 return -EINVAL;
16428 }
16429
16430 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16431 if (!hdd_ctx) {
16432 hddLog(LOGE , FL("Invalid HDD context"));
16433 return -EINVAL;
16434 }
16435
16436 status = memdump_procfs_init(vos_ctx);
16437 if (status) {
16438 hddLog(LOGE , FL("Failed to create proc file"));
16439 return status;
16440 }
16441
16442 return 0;
16443}
16444
16445/**
16446 * memdump_deinit() - De initialize memdump feature
16447 *
16448 * This function removes proc file created for memdump feature.
16449 *
16450 * Return: None
16451 */
16452int memdump_deinit(void)
16453{
16454 hdd_context_t *hdd_ctx;
16455 void *vos_ctx;
16456
16457 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
16458 if (!vos_ctx) {
16459 hddLog(LOGE, FL("Invalid VOS context"));
16460 return -EINVAL;
16461 }
16462
16463 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16464 if(!hdd_ctx) {
16465 hddLog(LOGE , FL("Invalid HDD context"));
16466 return -EINVAL;
16467 }
16468
16469 memdump_procfs_remove();
16470 return 0;
16471}
16472
16473/**
16474 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
16475 * Return: HAL status
16476 */
16477
16478int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
16479{
16480 tAniFwrDumpReq fw_mem_dump_req={0};
16481 eHalStatus status = eHAL_STATUS_FAILURE;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016482 int ret=0, dump_status;
16483 void *cookie;
16484 struct hdd_request *request;
16485 struct fw_mem_dump_priv *priv;
16486 static const struct hdd_request_params params = {
16487 .priv_size = sizeof(*priv),
16488 .timeout_ms = FW_MEM_DUMP_TIMEOUT_MS,
16489 };
16490
c_manjeecfd1efb2015-09-25 19:32:34 +053016491 ENTER();
c_manjeef1495642015-10-13 18:35:01 +053016492
c_manjeecfd1efb2015-09-25 19:32:34 +053016493 /*Check whether a dump request is already going on
16494 *Caution this function will free previously held memory if new dump request is allowed*/
16495 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
16496 hddLog(LOGE, FL("Fw memdump already in progress"));
16497 return -EBUSY;
16498 }
16499 //Allocate memory for fw mem dump buffer
16500 ret = wlan_fwr_mem_dump_buffer_allocation();
16501 if(ret == -EFAULT)
16502 {
16503 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
16504 return ret;
16505 }
16506 if (0 != ret) {
16507 hddLog(LOGE, FL("Fwr mem Allocation failed"));
16508 return -ENOMEM;
16509 }
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016510
16511 request = hdd_request_alloc(&params);
16512 if (!request) {
16513 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
16514 return VOS_STATUS_E_NOMEM;
16515 }
16516 cookie = hdd_request_cookie(request);
c_manjeef1495642015-10-13 18:35:01 +053016517
c_manjeecfd1efb2015-09-25 19:32:34 +053016518 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016519 fw_mem_dump_req.fwMemDumpReqContext = cookie;
c_manjeecfd1efb2015-09-25 19:32:34 +053016520 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
16521 if(eHAL_STATUS_SUCCESS != status)
16522 {
16523 hddLog(VOS_TRACE_LEVEL_ERROR,
16524 "%s: fw_mem_dump_req failed ", __func__);
16525 wlan_free_fwr_mem_dump_buffer();
c_manjeef1495642015-10-13 18:35:01 +053016526 ret = -EFAULT;
16527 goto cleanup;
c_manjeecfd1efb2015-09-25 19:32:34 +053016528 }
c_manjeef1495642015-10-13 18:35:01 +053016529 /*wait for fw mem dump completion to send event to userspace*/
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016530 ret = hdd_request_wait_for_response(request);
16531 if (ret)
c_manjeef1495642015-10-13 18:35:01 +053016532 {
16533 hddLog(VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016534 "%s: fw_mem_dump_req timeout %d ", __func__,ret);
Abhishek Singh4eca9822015-12-09 18:07:34 +053016535 ret = -ETIMEDOUT;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016536 }else {
16537 priv = hdd_request_priv(request);
16538 dump_status = priv->status;
c_manjeef1495642015-10-13 18:35:01 +053016539 }
16540cleanup:
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016541 hdd_request_put(request);
16542 if(!ret && !dump_status)
Abhishek Singh4eca9822015-12-09 18:07:34 +053016543 ret = -EFAULT;
c_manjeecfd1efb2015-09-25 19:32:34 +053016544
c_manjeef1495642015-10-13 18:35:01 +053016545 EXIT();
Abhishek Singh4eca9822015-12-09 18:07:34 +053016546 return ret;
c_manjeef1495642015-10-13 18:35:01 +053016547}
16548
16549/**
16550 * HDD callback which will be called by SVC to indicate mem dump completion.
16551 */
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016552void wlan_hdd_fw_mem_dump_req_cb(void *context)
c_manjeef1495642015-10-13 18:35:01 +053016553{
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016554 struct hdd_request *request;
16555 struct fw_mem_dump_priv *priv;
16556
16557 request = hdd_request_get(context);
16558 if (!request) {
16559 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
16560 return;
16561 }
16562
16563 priv = hdd_request_priv(request);
16564 priv->status = true;
16565
16566 hdd_request_complete(request);
16567 hdd_request_put(request);
c_manjeecfd1efb2015-09-25 19:32:34 +053016568}
16569
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053016570void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
16571{
16572 if (NULL == pAdapter)
16573 {
16574 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
16575 return;
16576 }
16577 init_completion(&pAdapter->session_open_comp_var);
16578 init_completion(&pAdapter->session_close_comp_var);
16579 init_completion(&pAdapter->disconnect_comp_var);
16580 init_completion(&pAdapter->linkup_event_var);
16581 init_completion(&pAdapter->cancel_rem_on_chan_var);
16582 init_completion(&pAdapter->rem_on_chan_ready_event);
16583 init_completion(&pAdapter->pno_comp_var);
16584#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16585 init_completion(&pAdapter->offchannel_tx_event);
16586#endif
16587 init_completion(&pAdapter->tx_action_cnf_event);
16588#ifdef FEATURE_WLAN_TDLS
16589 init_completion(&pAdapter->tdls_add_station_comp);
16590 init_completion(&pAdapter->tdls_del_station_comp);
16591 init_completion(&pAdapter->tdls_mgmt_comp);
16592 init_completion(&pAdapter->tdls_link_establish_req_comp);
16593#endif
16594
16595#ifdef WLAN_FEATURE_RMC
16596 init_completion(&pAdapter->ibss_peer_info_comp);
16597#endif /* WLAN_FEATURE_RMC */
16598 init_completion(&pAdapter->ula_complete);
16599 init_completion(&pAdapter->change_country_code);
16600
16601#ifdef FEATURE_WLAN_BATCH_SCAN
16602 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
16603 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
16604#endif
Kapil Gupta2b44acb2016-12-30 16:49:51 +053016605 init_completion(&pAdapter->wlan_suspend_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053016606
16607 return;
16608}
c_manjeecfd1efb2015-09-25 19:32:34 +053016609
Anurag Chouhan0b29de02016-12-16 13:18:40 +053016610#ifdef MDNS_OFFLOAD
16611
16612/**
16613 * hdd_mdns_enable_offload_done() - mdns enable offload response api
16614 * @padapter: holds adapter
16615 * @status: response status
16616 *
16617 * Return - None
16618 */
16619void hdd_mdns_enable_offload_done(void *padapter, VOS_STATUS status)
16620{
16621 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16622
16623 ENTER();
16624
16625 if (NULL == adapter)
16626 {
16627 hddLog(VOS_TRACE_LEVEL_ERROR,
16628 "%s: adapter is NULL",__func__);
16629 return;
16630 }
16631
16632 adapter->mdns_status.mdns_enable_status = status;
16633 vos_event_set(&adapter->mdns_status.vos_event);
16634 return;
16635}
16636
16637/**
16638 * hdd_mdns_fqdn_offload_done() - mdns fqdn offload response api
16639 * @padapter: holds adapter
16640 * @status: responce status
16641 *
16642 * Return - None
16643 */
16644void hdd_mdns_fqdn_offload_done(void *padapter, VOS_STATUS status)
16645{
16646 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16647
16648 ENTER();
16649
16650 if (NULL == adapter)
16651 {
16652 hddLog(VOS_TRACE_LEVEL_ERROR,
16653 "%s: adapter is NULL",__func__);
16654 return;
16655 }
16656
16657 adapter->mdns_status.mdns_fqdn_status = status;
16658 return;
16659}
16660
16661/**
16662 * hdd_mdns_resp_offload_done() - mdns resp offload response api
16663 * @padapter: holds adapter
16664 * @status: responce status
16665 *
16666 * Return - None
16667 */
16668void hdd_mdns_resp_offload_done(void *padapter, VOS_STATUS status)
16669{
16670 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16671
16672 ENTER();
16673
16674 if (NULL == adapter)
16675 {
16676 hddLog(VOS_TRACE_LEVEL_ERROR,
16677 "%s: adapter is NULL",__func__);
16678 return;
16679 }
16680
16681 adapter->mdns_status.mdns_resp_status = status;
16682 return;
16683}
16684
16685/**
16686 * wlan_hdd_mdns_process_response_dname() - Process mDNS domain name
16687 * @response: Pointer to a struct hdd_mdns_resp_info
16688 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16689 *
16690 * This function will pack the whole domain name without compression. It will
16691 * add the leading len for each field and add zero length octet to terminate
16692 * the domain name.
16693 *
16694 * Return: Return boolean. TRUE for success, FALSE for fail.
16695 */
16696static bool
16697wlan_hdd_mdns_process_response_dname(struct hdd_mdns_resp_info *response,
16698 sir_mdns_resp_info resp_info)
16699{
16700 uint8_t num;
16701 uint16_t idx;
16702 uint8_t len = 0;
16703
16704 if ((response == NULL) || (response->data == NULL) ||
16705 (response->offset == NULL)) {
16706 hddLog(LOGE, FL("Either data or offset in response is NULL!"));
16707 return FALSE;
16708 }
16709
16710 if ((resp_info == NULL) ||
16711 (resp_info->resp_len >= MAX_MDNS_RESP_LEN)) {
16712 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16713 return FALSE;
16714 }
16715
16716 for (num = 0; num < response->num_entries; num++) {
16717 response->offset[num] =
16718 resp_info->resp_len + MDNS_HEADER_LEN;
16719 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16720 len = strlen((char *)&response->data[idx]);
16721 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
16722 hddLog(LOGE, FL("resp_len exceeds %d!"),
16723 MAX_MDNS_RESP_LEN);
16724 return FALSE;
16725 }
16726 resp_info->resp_data[resp_info->resp_len] = len;
16727 resp_info->resp_len++;
16728 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
16729 &response->data[idx], len);
16730 resp_info->resp_len += len;
16731 }
16732
16733 /* The domain name terminates with the zero length octet */
16734 if (num == response->num_entries) {
16735 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
16736 hddLog(LOGE, FL("resp_len exceeds %d!"),
16737 MAX_MDNS_RESP_LEN);
16738 return FALSE;
16739 }
16740 resp_info->resp_data[resp_info->resp_len] = 0;
16741 resp_info->resp_len++;
16742 }
16743
16744 return TRUE;
16745}
16746
16747/**
16748 * wlan_hdd_mdns_format_response_u16() - Form uint16_t response data
16749 * @value: The uint16_t value is formed to the struct tSirMDNSResponseInfo
16750 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16751 *
16752 * Return: None
16753 */
16754static void wlan_hdd_mdns_format_response_u16(uint16_t value,
16755 sir_mdns_resp_info resp_info)
16756{
16757 uint8_t val_u8;
16758
16759 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
16760 return;
16761 val_u8 = (value & 0xff00) >> 8;
16762 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16763 val_u8 = value & 0xff;
16764 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16765}
16766
16767/**
16768 * wlan_hdd_mdns_format_response_u32() - Form uint32_t response data
16769 * @value: The uint32_t value is formed to the struct tSirMDNSResponseInfo
16770 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16771 *
16772 * Return: None
16773 */
16774static void wlan_hdd_mdns_format_response_u32(uint32_t value,
16775 sir_mdns_resp_info resp_info)
16776{
16777 uint8_t val_u8;
16778
16779 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
16780 return;
16781 val_u8 = (value & 0xff000000) >> 24;
16782 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16783 val_u8 = (value & 0xff0000) >> 16;
16784 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16785 val_u8 = (value & 0xff00) >> 8;
16786 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16787 val_u8 = value & 0xff;
16788 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16789}
16790
16791/**
16792 * wlan_hdd_mdns_process_response_misc() - Process misc info in mDNS response
16793 * @resp_type: Response type for mDNS
16794 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16795 *
16796 * This function will pack the response type, class and TTL (Time To Live).
16797 *
16798 * Return: Return boolean. TRUE for success, FALSE for fail.
16799 */
16800static bool wlan_hdd_mdns_process_response_misc(uint16_t resp_type,
16801 sir_mdns_resp_info resp_info)
16802{
16803 uint16_t len;
16804
16805 if (resp_info == NULL) {
16806 hddLog(LOGE, FL("resp_info is NULL!"));
16807 return FALSE;
16808 }
16809
16810 len = resp_info->resp_len + (2 * sizeof(uint16_t) + sizeof(uint32_t));
16811 if (len >= MAX_MDNS_RESP_LEN) {
16812 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16813 return FALSE;
16814 }
16815
16816 /* Fill Type, Class, TTL */
16817 wlan_hdd_mdns_format_response_u16(resp_type, resp_info);
16818 wlan_hdd_mdns_format_response_u16(MDNS_CLASS, resp_info);
16819 wlan_hdd_mdns_format_response_u32(MDNS_TTL, resp_info);
16820
16821 return TRUE;
16822}
16823
16824/**
16825 * wlan_hdd_mdns_compress_data() - Compress the domain name in mDNS response
16826 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16827 * @response_dst: The response which domain name is compressed.
16828 * @response_src: The response which domain name is matched with response_dst.
16829 * Its offset is used for data compression.
16830 * @num_matched: The number of matched entries between response_dst and
16831 * response_src
16832 *
16833 * This function will form the different fields of domain name in response_dst
16834 * if any. Then use the offset of the matched domain name in response_src to
16835 * compress the matched domain name.
16836 *
16837 * Return: Return boolean. TRUE for success, FALSE for fail.
16838 */
16839static bool
16840wlan_hdd_mdns_compress_data(sir_mdns_resp_info resp_info,
16841 struct hdd_mdns_resp_info *response_dst,
16842 struct hdd_mdns_resp_info *response_src,
16843 uint8_t num_matched)
16844{
16845 uint8_t num, num_diff;
16846 uint16_t value, idx;
16847 uint8_t len = 0;
16848
16849 if ((response_src == NULL) || (response_dst == NULL) ||
16850 (resp_info == NULL)) {
16851 hddLog(LOGE, FL("response info is NULL!"));
16852 return FALSE;
16853 }
16854
16855 if (response_dst->num_entries < num_matched) {
16856 hddLog(LOGE, FL("num_entries is less than num_matched!"));
16857 return FALSE;
16858 }
16859
16860 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
16861 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16862 return FALSE;
16863 }
16864
16865 num_diff = response_dst->num_entries - num_matched;
16866 if ((num_diff > 0) && (response_dst->data == NULL)) {
16867 hddLog(LOGE, FL("response_dst->data is NULL!"));
16868 return FALSE;
16869 }
16870
16871 /*
16872 * Handle the unmatched string at the beginning
16873 * Store the length of octets and the octets
16874 */
16875 for (num = 0; num < num_diff; num++) {
16876 response_dst->offset[num] =
16877 resp_info->resp_len + MDNS_HEADER_LEN;
16878 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16879 len = strlen((char *)&response_dst->data[idx]);
16880 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
16881 hddLog(LOGE, FL("resp_len exceeds %d!"),
16882 MAX_MDNS_RESP_LEN);
16883 return FALSE;
16884 }
16885 resp_info->resp_data[resp_info->resp_len] = len;
16886 resp_info->resp_len++;
16887 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
16888 &response_dst->data[idx], len);
16889 resp_info->resp_len += len;
16890 }
16891 /*
16892 * Handle the matched string from the end
16893 * Just keep the offset and mask the leading two bit
16894 */
16895 if (response_src->num_entries >= num_matched) {
16896 num_diff = response_src->num_entries - num_matched;
16897 value = response_src->offset[num_diff];
16898 if (value > 0) {
16899 value |= 0xc000;
16900 if ((resp_info->resp_len + sizeof(uint16_t)) >=
16901 MAX_MDNS_RESP_LEN) {
16902 hddLog(LOGE, FL("resp_len exceeds %d!"),
16903 MAX_MDNS_RESP_LEN);
16904 return FALSE;
16905 }
16906 wlan_hdd_mdns_format_response_u16(value, resp_info);
16907 return TRUE;
16908 }
16909 }
16910 return FALSE;
16911}
16912
16913/**
16914 * wlan_hdd_mdns_reset_response() - Reset the response info
16915 * @response: The response which info is reset.
16916 *
16917 * Return: None
16918 */
16919static void wlan_hdd_mdns_reset_response(struct hdd_mdns_resp_info *response)
16920{
16921 if (response == NULL)
16922 return;
16923 response->num_entries = 0;
16924 response->data = NULL;
16925 response->offset = NULL;
16926}
16927
16928/**
16929 * wlan_hdd_mdns_init_response() - Initialize the response info
16930 * @response: The response which info is initiatized.
16931 * @resp_dname: The domain name string which might be tokenized.
16932 *
16933 * This function will allocate the memory for both response->data and
16934 * response->offset. Besides, it will also tokenize the domain name to some
16935 * entries and fill response->num_entries with the num of entries.
16936 *
16937 * Return: Return boolean. TRUE for success, FALSE for fail.
16938 */
16939static bool wlan_hdd_mdns_init_response(struct hdd_mdns_resp_info *response,
16940 uint8_t *resp_dname, char separator)
16941{
16942 uint16_t size;
16943
16944 if ((resp_dname == NULL) || (response == NULL)) {
16945 hddLog(LOGE, FL("resp_dname or response is NULL!"));
16946 return FALSE;
16947 }
16948
16949 size = MAX_NUM_FIELD_DOMAINNAME * MAX_LEN_DOMAINNAME_FIELD;
16950 response->data = vos_mem_malloc(size);
16951 if (response->data) {
16952 vos_mem_zero(response->data, size);
16953 if (VOS_STATUS_SUCCESS !=
16954 hdd_string_to_string_array((char *)resp_dname,
16955 response->data,
16956 separator,
16957 &response->num_entries,
16958 MAX_NUM_FIELD_DOMAINNAME,
16959 MAX_LEN_DOMAINNAME_FIELD)) {
16960 hddLog(LOGE, FL("hdd_string_to_string_array fail!"));
16961 goto err_init_resp;
16962 }
16963
16964 if ((response->num_entries > 0) &&
16965 (strlen((char *)&response->data[0]) > 0)) {
16966 size = sizeof(uint16_t) * response->num_entries;
16967 response->offset = vos_mem_malloc(size);
16968 if (response->offset) {
16969 vos_mem_zero(response->offset, size);
16970 return TRUE;
16971 }
16972 }
16973 }
16974
16975err_init_resp:
16976 if (response->data)
16977 vos_mem_free(response->data);
16978 wlan_hdd_mdns_reset_response(response);
16979 return FALSE;
16980}
16981
16982/**
16983 * wlan_hdd_mdns_find_entries_from_end() - Find the matched entries
16984 * @response1: The response info is used to be compared.
16985 * @response2: The response info is used to be compared.
16986 *
16987 * This function will find the matched entries from the end.
16988 *
16989 * Return: Return the number of the matched entries.
16990 */
16991static uint8_t
16992wlan_hdd_mdns_find_entries_from_end(struct hdd_mdns_resp_info *response1,
16993 struct hdd_mdns_resp_info *response2)
16994{
16995 uint8_t min, len1, i;
16996 uint16_t num1, num2;
16997 uint8_t num_matched = 0;
16998
16999 min = VOS_MIN(response1->num_entries, response2->num_entries);
17000
17001 for (i = 1; i <= min; i++) {
17002 num1 = (response1->num_entries - i);
17003 num1 *= MAX_LEN_DOMAINNAME_FIELD;
17004 num2 = (response2->num_entries - i);
17005 num2 *= MAX_LEN_DOMAINNAME_FIELD;
17006 len1 = strlen((char *)&response1->data[num1]);
17007
17008 if ((len1 == 0) ||
17009 (len1 != strlen((char *)&response2->data[num2])))
17010 break;
17011 if (memcmp(&response1->data[num1],
17012 &response2->data[num2], len1))
17013 break;
17014 else
17015 num_matched++;
17016 }
17017
17018 return num_matched;
17019}
17020
17021/**
17022 * wlan_hdd_mdns_find_max() - Find the maximum number of the matched entries
17023 * @matchedlist: Pointer to the array of struct hdd_mdns_resp_matched
17024 * @numlist: The number of the elements in the array matchedlist.
17025 *
17026 * Find the max number of the matched entries among the array matchedlist.
17027 *
17028 * Return: None
17029 */
17030static void wlan_hdd_mdns_find_max(struct hdd_mdns_resp_matched *matchedlist,
17031 uint8_t numlist)
17032{
17033 int j;
17034 struct hdd_mdns_resp_matched tmp;
17035
17036 /* At least two values are used for sorting */
17037 if ((numlist < 2) || (matchedlist == NULL)) {
17038 hddLog(LOGE, FL("At least two values are used for sorting!"));
17039 return;
17040 }
17041
17042 for (j = 0; j < numlist-1; j++) {
17043 if (matchedlist[j].num_matched >
17044 matchedlist[j+1].num_matched) {
17045 vos_mem_copy(&tmp, &matchedlist[j],
17046 sizeof(struct hdd_mdns_resp_matched));
17047 vos_mem_copy(&matchedlist[j], &matchedlist[j+1],
17048 sizeof(struct hdd_mdns_resp_matched));
17049 vos_mem_copy(&matchedlist[j+1], &tmp,
17050 sizeof(struct hdd_mdns_resp_matched));
17051 }
17052 }
17053}
17054
17055/**
17056 * wlan_hdd_mdns_pack_response_type_a() - Pack Type A response
17057 * @ini_config: Pointer to the struct hdd_config_t
17058 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17059 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17060 *
17061 * Type A response include QName, response type, class, TTL and Ipv4.
17062 *
17063 * Return: Return boolean. TRUE for success, FALSE for fail.
17064 */
17065static bool
17066wlan_hdd_mdns_pack_response_type_a(hdd_config_t *ini_config,
17067 sir_mdns_resp_info resp_info,
17068 struct hdd_mdns_resp_info *resptype_a)
17069{
17070 uint16_t value;
17071 uint32_t len;
17072
17073 ENTER();
17074 if ((ini_config == NULL) || (resp_info == NULL) ||
17075 (resptype_a == NULL)) {
17076 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17077 return FALSE;
17078 }
17079
17080 /* No Type A response */
17081 if (strlen((char *)ini_config->mdns_resp_type_a) <= 0)
17082 return TRUE;
17083
17084 /* Wrong response is assigned, just ignore this response */
17085 if (!wlan_hdd_mdns_init_response(resptype_a,
17086 ini_config->mdns_resp_type_a, '.'))
17087 return TRUE;
17088
17089 /* Process response domain name */
17090 if (!wlan_hdd_mdns_process_response_dname(resptype_a, resp_info)) {
17091 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17092 MDNS_TYPE_A);
17093 return FALSE;
17094 }
17095
17096 /* Process response Type, Class, TTL */
17097 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_A, resp_info)) {
17098 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17099 MDNS_TYPE_A);
17100 return FALSE;
17101 }
17102
17103 /* Process response RDLength, RData */
17104 len = sizeof(uint16_t) + sizeof(uint32_t);
17105 len += resp_info->resp_len;
17106 if (len >= MAX_MDNS_RESP_LEN) {
17107 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17108 return FALSE;
17109 }
17110 value = sizeof(uint32_t);
17111 wlan_hdd_mdns_format_response_u16(value, resp_info);
17112 wlan_hdd_mdns_format_response_u32(ini_config->mdns_resp_type_a_ipv4,
17113 resp_info);
17114
17115 EXIT();
17116 return TRUE;
17117}
17118
17119/**
17120 * wlan_hdd_mdns_pack_response_type_txt() - Pack Type Txt response
17121 * @ini_config: Pointer to the struct hdd_config_t
17122 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17123 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type txt
17124 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17125 *
17126 * Type Txt response include QName, response type, class, TTL and text content.
17127 * Also, it will find the matched QName from resptype_A and compress the data.
17128 *
17129 * Return: Return boolean. TRUE for success, FALSE for fail.
17130 */
17131static bool
17132wlan_hdd_mdns_pack_response_type_txt(hdd_config_t *ini_config,
17133 sir_mdns_resp_info resp_info,
17134 struct hdd_mdns_resp_info *resptype_txt,
17135 struct hdd_mdns_resp_info *resptype_a)
17136{
17137 uint8_t num_matched;
17138 uint8_t num;
17139 uint16_t idx;
17140 uint16_t value = 0;
17141 uint32_t len;
17142 uint32_t total_len;
17143 bool status;
17144 struct hdd_mdns_resp_info resptype_content;
17145
17146 ENTER();
17147
17148 if ((ini_config == NULL) || (resp_info == NULL) ||
17149 (resptype_txt == NULL)) {
17150 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17151 return FALSE;
17152 }
17153
17154 /* No Type Txt response */
17155 if (strlen((char *)ini_config->mdns_resp_type_txt) <= 0)
17156 return TRUE;
17157
17158 /* Wrong response is assigned, just ignore this response */
17159 if (!wlan_hdd_mdns_init_response(resptype_txt,
17160 ini_config->mdns_resp_type_txt, '.'))
17161 return TRUE;
17162
17163 /*
17164 * For data compression
17165 * Check if any strings are matched with Type A response
17166 */
17167 if (resptype_a && (resptype_a->num_entries > 0)) {
17168 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_txt,
17169 resptype_a);
17170 if (num_matched > 0) {
17171 if (!wlan_hdd_mdns_compress_data(resp_info,
17172 resptype_txt, resptype_a, num_matched)) {
17173 hddLog(LOGE, FL("Fail to compress mDNS "
17174 "response (%d)!"), MDNS_TYPE_TXT);
17175 return FALSE;
17176 }
17177 } else {
17178 /*
17179 * num_matched is zero. Error!
17180 * At least ".local" is needed.
17181 */
17182 hddLog(LOGE, FL("No matched string! Fail to pack mDNS "
17183 "response (%d)!"), MDNS_TYPE_TXT);
17184 return FALSE;
17185 }
17186 } else {
17187 /* no TypeA response, so show the whole data */
17188 if (!wlan_hdd_mdns_process_response_dname(resptype_txt,
17189 resp_info)) {
17190 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17191 MDNS_TYPE_TXT);
17192 return FALSE;
17193 }
17194 }
17195
17196 /* Process response Type, Class, TTL */
17197 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_TXT, resp_info)) {
17198 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17199 MDNS_TYPE_TXT);
17200 return FALSE;
17201 }
17202
17203 /*
17204 * Process response RDLength, RData.
17205 * TypeTxt RData include len.
17206 */
17207 status = wlan_hdd_mdns_init_response(&resptype_content,
17208 ini_config->mdns_resp_type_txt_content,
17209 '/');
17210 if (status == FALSE) {
17211 hddLog(LOGE, FL("wlan_hdd_mdns_init_response FAIL"));
17212 return FALSE;
17213 }
17214
17215 for (num = 0; num < resptype_content.num_entries; num++) {
17216 idx = num * MAX_LEN_DOMAINNAME_FIELD;
17217 value += strlen((char *)&resptype_content.data[idx]);
17218 }
17219
17220 /* content len is uint16_t */
17221 total_len = sizeof(uint16_t);
17222 total_len += resp_info->resp_len + value +
17223 resptype_content.num_entries;
17224
17225 if (total_len >= MAX_MDNS_RESP_LEN) {
17226 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17227 return FALSE;
17228 }
17229 wlan_hdd_mdns_format_response_u16(value + resptype_content.num_entries,
17230 resp_info);
17231
17232 for (num = 0; num < resptype_content.num_entries; num++) {
17233 idx = num * MAX_LEN_DOMAINNAME_FIELD;
17234 len = strlen((char *)&resptype_content.data[idx]);
17235 resp_info->resp_data[resp_info->resp_len] = len;
17236 resp_info->resp_len++;
17237
17238 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
17239 &resptype_content.data[idx], len);
17240
17241 resp_info->resp_len += len;
17242 hddLog(LOG1, FL("index = %d, len = %d, str = %s"),
17243 num, len, &resptype_content.data[idx]);
17244 }
17245
17246 EXIT();
17247 return TRUE;
17248}
17249
17250/**
17251 * wlan_hdd_mdns_pack_response_type_ptr_dname() - Pack Type PTR domain name
17252 * @ini_config: Pointer to the struct hdd_config_t
17253 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17254 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17255 * domain name
17256 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17257 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17258 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17259 *
17260 * The Type Ptr response include Type PTR domain name in its data field.
17261 * Also, it will find the matched QName from the existing resptype_ptr,
17262 * resptype_txt, resptype_a and then compress the data.
17263 *
17264 * Return: Return boolean. TRUE for success, FALSE for fail.
17265 */
17266static bool
17267wlan_hdd_mdns_pack_response_type_ptr_dname(hdd_config_t *ini_config,
17268 sir_mdns_resp_info resp_info,
17269 struct hdd_mdns_resp_info *resptype_ptr_dn,
17270 struct hdd_mdns_resp_info *resptype_ptr,
17271 struct hdd_mdns_resp_info *resptype_txt,
17272 struct hdd_mdns_resp_info *resptype_a)
17273{
17274 uint8_t num_matched, numlist, size;
17275 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17276 struct hdd_mdns_resp_info *resp;
17277
17278 if ((ini_config == NULL) || (resp_info == NULL) ||
17279 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
17280 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17281 return FALSE;
17282 }
17283
17284 /* No Type Ptr domain name response */
17285 if (strlen((char *)ini_config->mdns_resp_type_ptr_dname) <= 0)
17286 return TRUE;
17287
17288 /* Wrong response is assigned, just ignore this response */
17289 if (!wlan_hdd_mdns_init_response(resptype_ptr_dn,
17290 ini_config->mdns_resp_type_ptr_dname, '.'))
17291 return TRUE;
17292
17293 /*
17294 * For data compression
17295 * Check if any strings are matched with previous
17296 * response.
17297 */
17298 numlist = 0;
17299 size = (MAX_MDNS_RESP_TYPE-1);
17300 size *= sizeof(struct hdd_mdns_resp_matched);
17301 vos_mem_zero(matchedlist, size);
17302 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr_dn,
17303 resptype_ptr);
17304 if (num_matched > 0) {
17305 matchedlist[numlist].num_matched = num_matched;
17306 matchedlist[numlist].type = MDNS_TYPE_PTR;
17307 numlist++;
17308 }
17309 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17310 num_matched = wlan_hdd_mdns_find_entries_from_end(
17311 resptype_ptr_dn, resptype_txt);
17312 if (num_matched > 0) {
17313 matchedlist[numlist].num_matched = num_matched;
17314 matchedlist[numlist].type = MDNS_TYPE_TXT;
17315 numlist++;
17316 }
17317 }
17318 if (resptype_a && (resptype_a->num_entries > 0)) {
17319 num_matched = wlan_hdd_mdns_find_entries_from_end(
17320 resptype_ptr_dn,resptype_a);
17321 if (num_matched > 0) {
17322 matchedlist[numlist].num_matched = num_matched;
17323 matchedlist[numlist].type = MDNS_TYPE_A;
17324 numlist++;
17325 }
17326 }
17327 if (numlist > 0) {
17328 if (numlist > 1)
17329 wlan_hdd_mdns_find_max(matchedlist, numlist);
17330 resp = NULL;
17331 switch (matchedlist[numlist-1].type) {
17332 case MDNS_TYPE_A:
17333 resp = resptype_a;
17334 break;
17335 case MDNS_TYPE_TXT:
17336 resp = resptype_txt;
17337 break;
17338 case MDNS_TYPE_PTR:
17339 resp = resptype_ptr;
17340 break;
17341 default:
17342 hddLog(LOGE, FL("Fail to compress mDNS response "
17343 "(%d)!"), MDNS_TYPE_PTR_DNAME);
17344 return FALSE;
17345 }
17346 num_matched = matchedlist[numlist-1].num_matched;
17347 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_ptr_dn,
17348 resp, num_matched)) {
17349 hddLog(LOGE, FL("Fail to compress mDNS response "
17350 "(%d)!"), MDNS_TYPE_PTR_DNAME);
17351 return FALSE;
17352 }
17353 } else {
17354 /* num = 0 -> no matched string */
17355 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr_dn,
17356 resp_info)) {
17357 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17358 MDNS_TYPE_PTR_DNAME);
17359 return FALSE;
17360 }
17361 }
17362
17363 return TRUE;
17364}
17365
17366/**
17367 * wlan_hdd_mdns_pack_response_type_ptr() - Pack Type PTR response
17368 * @ini_config: Pointer to the struct hdd_config_t
17369 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17370 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17371 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17372 * domain name
17373 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17374 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17375 *
17376 * The Type Ptr response include QName, response type, class, TTL and
17377 * Type PTR domain name. Also, it will find the matched QName from the
17378 * existing resptype_txt, resptype_a and then compress the data.
17379 *
17380 * Return: Return boolean. TRUE for success, FALSE for fail.
17381 */
17382static bool
17383wlan_hdd_mdns_pack_response_type_ptr(hdd_config_t *ini_config,
17384 sir_mdns_resp_info resp_info,
17385 struct hdd_mdns_resp_info *resptype_ptr,
17386 struct hdd_mdns_resp_info *resptype_ptr_dn,
17387 struct hdd_mdns_resp_info *resptype_txt,
17388 struct hdd_mdns_resp_info *resptype_a)
17389{
17390 uint8_t num_matched, num_matched1;
17391 uint16_t value;
17392 uint8_t val_u8;
17393 uint32_t offset_data_len, len;
17394
17395 ENTER();
17396 if ((ini_config == NULL) || (resp_info == NULL) ||
17397 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
17398 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17399 return FALSE;
17400 }
17401
17402 /* No Type Ptr response */
17403 if (strlen((char *)ini_config->mdns_resp_type_ptr) <= 0)
17404 return TRUE;
17405
17406 /* Wrong response is assigned, just ignore this response */
17407 if (!wlan_hdd_mdns_init_response(resptype_ptr,
17408 ini_config->mdns_resp_type_ptr, '.'))
17409 return TRUE;
17410
17411 /*
17412 * For data compression
17413 * Check if any strings are matched with Type A response
17414 */
17415 num_matched = 0;
17416 num_matched1 = 0;
17417 if (resptype_a && (resptype_a->num_entries > 0)) {
17418 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr,
17419 resptype_a);
17420 }
17421 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17422 num_matched1 = wlan_hdd_mdns_find_entries_from_end(
17423 resptype_ptr, resptype_txt);
17424 }
17425 if ((num_matched != num_matched1) ||
17426 ((num_matched > 0) && (num_matched1 > 0))) {
17427 if (num_matched >= num_matched1) {
17428 if (!wlan_hdd_mdns_compress_data(resp_info,
17429 resptype_ptr, resptype_a, num_matched)) {
17430 hddLog(LOGE, FL("Fail to compress mDNS "
17431 "response (%d)!"), MDNS_TYPE_PTR);
17432 return FALSE;
17433 }
17434 } else {
17435 /* num_matched is less than num_matched1 */
17436 if (!wlan_hdd_mdns_compress_data(resp_info,
17437 resptype_ptr, resptype_txt, num_matched1)) {
17438 hddLog(LOGE, FL("Fail to compress mDNS "
17439 "response (%d)!"), MDNS_TYPE_PTR);
17440 return FALSE;
17441 }
17442 }
17443 } else {
17444 /*
17445 * Both num_matched and num_matched1 are zero.
17446 * no TypeA & TypeTxt
17447 */
17448 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr,
17449 resp_info)) {
17450 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17451 MDNS_TYPE_PTR);
17452 return FALSE;
17453 }
17454 }
17455
17456 /* Process response Type, Class, TTL */
17457 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_PTR, resp_info)) {
17458 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17459 MDNS_TYPE_PTR);
17460 return FALSE;
17461 }
17462
17463 /*
17464 * Process response RDLength, RData (Ptr domain name)
17465 * Save the offset of RData length
17466 */
17467 offset_data_len = resp_info->resp_len;
17468 resp_info->resp_len += sizeof(uint16_t);
17469
17470 if (!wlan_hdd_mdns_pack_response_type_ptr_dname(ini_config, resp_info,
17471 resptype_ptr_dn, resptype_ptr,
17472 resptype_txt, resptype_a)) {
17473 return FALSE;
17474 }
17475 /* Set the RData length */
17476 len = offset_data_len + sizeof(uint16_t);
17477 if ((resptype_ptr_dn->num_entries > 0) &&
17478 (resp_info->resp_len > len)) {
17479 value = resp_info->resp_len - len;
17480 val_u8 = (value & 0xff00) >> 8;
17481 resp_info->resp_data[offset_data_len] = val_u8;
17482 val_u8 = value & 0xff;
17483 resp_info->resp_data[offset_data_len+1] = val_u8;
17484 } else {
17485 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17486 MDNS_TYPE_PTR);
17487 return FALSE;
17488 }
17489
17490 EXIT();
17491 return TRUE;
17492}
17493
17494/**
17495 * wlan_hdd_mdns_pack_response_type_srv_target()- Pack Type Service Target
17496 * @ini_config: Pointer to the struct hdd_config_t
17497 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17498 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
17499 * target
17500 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
17501 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17502 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17503 * domain name
17504 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17505 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17506 *
17507 * The Type service target is one of the data field in the Type SRV response.
17508 * Also, it will find the matched QName from the existing resptype_srv,
17509 * resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and then compress
17510 * the data.
17511 *
17512 * Return: Return boolean. TRUE for success, FALSE for fail.
17513 */
17514static bool
17515wlan_hdd_mdns_pack_response_type_srv_target(hdd_config_t *ini_config,
17516 sir_mdns_resp_info resp_info,
17517 struct hdd_mdns_resp_info *resptype_srv_tgt,
17518 struct hdd_mdns_resp_info *resptype_srv,
17519 struct hdd_mdns_resp_info *resptype_ptr,
17520 struct hdd_mdns_resp_info *resptype_ptr_dn,
17521 struct hdd_mdns_resp_info *resptype_txt,
17522 struct hdd_mdns_resp_info *resptype_a)
17523{
17524 uint8_t num_matched, num, size;
17525 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17526 struct hdd_mdns_resp_info *resp;
17527
17528 if ((ini_config == NULL) || (resp_info == NULL) ||
17529 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
17530 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17531 return FALSE;
17532 }
17533
17534 /* No Type Srv Target response */
17535 if (strlen((char *)ini_config->mdns_resp_type_srv_target) <= 0)
17536 return TRUE;
17537
17538 /* Wrong response is assigned, just ignore this response */
17539 if (!wlan_hdd_mdns_init_response(resptype_srv_tgt,
17540 ini_config->mdns_resp_type_srv_target, '.'))
17541 return TRUE;
17542
17543 /*
17544 * For data compression
17545 * Check if any strings are matched with previous response.
17546 */
17547 num = 0;
17548 size = (MAX_MDNS_RESP_TYPE-1);
17549 size *= sizeof(struct hdd_mdns_resp_matched);
17550 vos_mem_zero(matchedlist, size);
17551 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv_tgt,
17552 resptype_srv);
17553 if (num_matched > 0) {
17554 matchedlist[num].num_matched = num_matched;
17555 matchedlist[num].type = MDNS_TYPE_SRV;
17556 num++;
17557 }
17558 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
17559 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
17560 num_matched = wlan_hdd_mdns_find_entries_from_end(
17561 resptype_srv_tgt, resptype_ptr_dn);
17562 if (num_matched > 0) {
17563 matchedlist[num].num_matched = num_matched;
17564 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
17565 num++;
17566 }
17567 }
17568 num_matched = wlan_hdd_mdns_find_entries_from_end(
17569 resptype_srv_tgt, resptype_ptr);
17570 if (num_matched > 0) {
17571 matchedlist[num].num_matched = num_matched;
17572 matchedlist[num].type = MDNS_TYPE_PTR;
17573 num++;
17574 }
17575 }
17576 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17577 num_matched = wlan_hdd_mdns_find_entries_from_end(
17578 resptype_srv_tgt, resptype_txt);
17579 if (num_matched > 0) {
17580 matchedlist[num].num_matched = num_matched;
17581 matchedlist[num].type = MDNS_TYPE_TXT;
17582 num++;
17583 }
17584 }
17585 if (resptype_a && (resptype_a->num_entries > 0)) {
17586 num_matched = wlan_hdd_mdns_find_entries_from_end(
17587 resptype_srv_tgt, resptype_a);
17588 if (num_matched > 0) {
17589 matchedlist[num].num_matched = num_matched;
17590 matchedlist[num].type = MDNS_TYPE_A;
17591 num++;
17592 }
17593 }
17594 if (num > 0) {
17595 if (num > 1)
17596 wlan_hdd_mdns_find_max(matchedlist, num);
17597 resp = NULL;
17598 switch (matchedlist[num-1].type) {
17599 case MDNS_TYPE_A:
17600 resp = resptype_a;
17601 break;
17602 case MDNS_TYPE_TXT:
17603 resp = resptype_txt;
17604 break;
17605 case MDNS_TYPE_PTR:
17606 resp = resptype_ptr;
17607 break;
17608 case MDNS_TYPE_PTR_DNAME:
17609 resp = resptype_ptr_dn;
17610 break;
17611 case MDNS_TYPE_SRV:
17612 resp = resptype_srv;
17613 break;
17614 default:
17615 hddLog(LOGE, FL("Fail to compress mDNS response "
17616 "(%d)!"), MDNS_TYPE_SRV_TARGET);
17617 return FALSE;
17618 }
17619 num_matched = matchedlist[num-1].num_matched;
17620 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv_tgt,
17621 resp, num_matched)) {
17622 hddLog(LOGE, FL("Fail to compress mDNS response "
17623 "(%d)!"), MDNS_TYPE_SRV_TARGET);
17624 return FALSE;
17625 }
17626 } else {
17627 /* num = 0 -> no matched string */
17628 if (!wlan_hdd_mdns_process_response_dname(resptype_srv_tgt,
17629 resp_info)) {
17630 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17631 MDNS_TYPE_SRV_TARGET);
17632 return FALSE;
17633 }
17634 }
17635
17636 return TRUE;
17637}
17638
17639/**
17640 * wlan_hdd_mdns_pack_response_type_srv()- Pack Type Service response
17641 * @ini_config: Pointer to the struct hdd_config_t
17642 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17643 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
17644 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
17645 * target
17646 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17647 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17648 * domain name
17649 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17650 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17651 *
17652 * The Type SRV (Service) response include QName, response type, class, TTL
17653 * and four kinds of data fields. Also, it will find the matched QName from
17654 * the existing resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and
17655 * then compress the data.
17656 *
17657 * Return: Return boolean. TRUE for success, FALSE for fail.
17658 */
17659static bool
17660wlan_hdd_mdns_pack_response_type_srv(hdd_config_t *ini_config,
17661 sir_mdns_resp_info resp_info,
17662 struct hdd_mdns_resp_info *resptype_srv,
17663 struct hdd_mdns_resp_info *resptype_srv_tgt,
17664 struct hdd_mdns_resp_info *resptype_ptr,
17665 struct hdd_mdns_resp_info *resptype_ptr_dn,
17666 struct hdd_mdns_resp_info *resptype_txt,
17667 struct hdd_mdns_resp_info *resptype_a)
17668{
17669 uint8_t num_matched, num, size;
17670 uint16_t value;
17671 uint8_t val_u8;
17672 uint32_t offset_data_len, len;
17673 struct hdd_mdns_resp_info *resp;
17674 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17675
17676 ENTER();
17677
17678 if ((ini_config == NULL) || (resp_info == NULL) ||
17679 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
17680 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17681 return FALSE;
17682 }
17683
17684 /* No Type Srv response */
17685 if (strlen((char *)ini_config->mdns_resp_type_srv) <= 0)
17686 return TRUE;
17687
17688 /* Wrong response is assigned, just ignore this response */
17689 if (!wlan_hdd_mdns_init_response(resptype_srv,
17690 ini_config->mdns_resp_type_srv, '.'))
17691 return TRUE;
17692
17693 /*
17694 * For data compression
17695 * Check if any strings are matched with Type A response
17696 */
17697 num = 0;
17698 size = (MAX_MDNS_RESP_TYPE-1);
17699 size *= sizeof(struct hdd_mdns_resp_matched);
17700 vos_mem_zero(matchedlist, size);
17701 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
17702 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
17703 num_matched = wlan_hdd_mdns_find_entries_from_end(
17704 resptype_srv,
17705 resptype_ptr_dn);
17706 if (num_matched > 0) {
17707 matchedlist[num].num_matched = num_matched;
17708 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
17709 num++;
17710 }
17711 }
17712 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17713 resptype_ptr);
17714 if (num_matched > 0) {
17715 matchedlist[num].num_matched = num_matched;
17716 matchedlist[num].type = MDNS_TYPE_PTR;
17717 num++;
17718 }
17719 }
17720 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17721 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17722 resptype_txt);
17723 if (num_matched > 0) {
17724 matchedlist[num].num_matched =num_matched;
17725 matchedlist[num].type = MDNS_TYPE_TXT;
17726 num++;
17727 }
17728 }
17729 if (resptype_a && (resptype_a->num_entries > 0)) {
17730 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17731 resptype_a);
17732 if (num_matched > 0) {
17733 matchedlist[num].num_matched = num_matched;
17734 matchedlist[num].type = MDNS_TYPE_A;
17735 num++;
17736 }
17737 }
17738 if (num > 0) {
17739 if (num > 1)
17740 wlan_hdd_mdns_find_max(matchedlist, num);
17741 resp = NULL;
17742 switch (matchedlist[num-1].type) {
17743 case MDNS_TYPE_A:
17744 resp = resptype_a;
17745 break;
17746 case MDNS_TYPE_TXT:
17747 resp = resptype_txt;
17748 break;
17749 case MDNS_TYPE_PTR:
17750 resp = resptype_ptr;
17751 break;
17752 case MDNS_TYPE_PTR_DNAME:
17753 resp = resptype_ptr_dn;
17754 break;
17755 default:
17756 hddLog(LOGE, FL("Fail to compress mDNS response "
17757 "(%d)!"), MDNS_TYPE_SRV);
17758 return FALSE;
17759 }
17760 num_matched = matchedlist[num-1].num_matched;
17761 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv,
17762 resp, num_matched)) {
17763 hddLog(LOGE, FL("Fail to compress mDNS response "
17764 "(%d)!"), MDNS_TYPE_SRV);
17765 return FALSE;
17766 }
17767 } else {
17768 /* num = 0 -> no matched string */
17769 if (!wlan_hdd_mdns_process_response_dname(resptype_srv,
17770 resp_info)) {
17771 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17772 MDNS_TYPE_SRV);
17773 return FALSE;
17774 }
17775 }
17776
17777 /* Process response Type, Class, TTL */
17778 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_SRV, resp_info)) {
17779 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17780 MDNS_TYPE_SRV);
17781 return FALSE;
17782 }
17783
17784 /*
17785 * Process response RDLength, RData (Srv target name)
17786 * Save the offset of RData length
17787 */
17788 offset_data_len = resp_info->resp_len;
17789 resp_info->resp_len += sizeof(uint16_t);
17790
17791 len = resp_info->resp_len + (3 * sizeof(uint16_t));
17792 if (len >= MAX_MDNS_RESP_LEN) {
17793 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17794 return FALSE;
17795 }
17796
17797 /* set Srv Priority */
17798 value = ini_config->mdns_resp_type_srv_priority;
17799 wlan_hdd_mdns_format_response_u16(value, resp_info);
17800 /* set Srv Weight */
17801 value = ini_config->mdns_resp_type_srv_weight;
17802 wlan_hdd_mdns_format_response_u16(value, resp_info);
17803 /* set Srv Port */
17804 value = ini_config->mdns_resp_type_srv_port;
17805 wlan_hdd_mdns_format_response_u16(value, resp_info);
17806
17807 if (!wlan_hdd_mdns_pack_response_type_srv_target(ini_config, resp_info,
17808 resptype_srv_tgt, resptype_srv,
17809 resptype_ptr, resptype_ptr_dn,
17810 resptype_txt, resptype_a)) {
17811 return FALSE;
17812 }
17813 /* Set the RData length */
17814 len = offset_data_len + sizeof(uint16_t);
17815 if ((resptype_srv_tgt->num_entries > 0) &&
17816 (resp_info->resp_len > len)) {
17817 value = resp_info->resp_len - len;
17818 val_u8 = (value & 0xff00) >> 8;
17819 resp_info->resp_data[offset_data_len] = val_u8;
17820 val_u8 = value & 0xff;
17821 resp_info->resp_data[offset_data_len+1] = val_u8;
17822 } else {
17823 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17824 MDNS_TYPE_SRV);
17825 return FALSE;
17826 }
17827
17828 EXIT();
17829 return TRUE;
17830}
17831
17832/**
17833 * wlan_hdd_mdns_free_mem() - Free the allocated memory
17834 * @response: Pointer to the struct hdd_mdns_resp_info
17835 *
17836 * Return: None
17837 */
17838static void wlan_hdd_mdns_free_mem(struct hdd_mdns_resp_info *response)
17839{
17840 if (response && response->data)
17841 vos_mem_free(response->data);
17842 if (response && response->offset)
17843 vos_mem_free(response->offset);
17844}
17845
17846/**
17847 * wlan_hdd_mdns_pack_response() - Pack mDNS response
17848 * @ini_config: Pointer to the struct hdd_config_t
17849 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17850 *
17851 * This function will pack four types of responses (Type A, Type Txt, Type Ptr
17852 * and Type Service). Each response contains QName, response type, class, TTL
17853 * and data fields.
17854 *
17855 * Return: Return boolean. TRUE for success, FALSE for fail.
17856 */
17857static bool wlan_hdd_mdns_pack_response(hdd_config_t *ini_config,
17858 sir_mdns_resp_info resp_info)
17859{
17860 struct hdd_mdns_resp_info resptype_a, resptype_txt;
17861 struct hdd_mdns_resp_info resptype_ptr, resptype_ptr_dn;
17862 struct hdd_mdns_resp_info resptype_srv, resptype_srv_tgt;
17863 uint32_t num_res_records = 0;
17864 bool status = FALSE;
17865
17866 ENTER();
17867
17868 wlan_hdd_mdns_reset_response(&resptype_a);
17869 wlan_hdd_mdns_reset_response(&resptype_txt);
17870 wlan_hdd_mdns_reset_response(&resptype_ptr);
17871 wlan_hdd_mdns_reset_response(&resptype_ptr_dn);
17872 wlan_hdd_mdns_reset_response(&resptype_srv);
17873 wlan_hdd_mdns_reset_response(&resptype_srv_tgt);
17874
17875 resp_info->resp_len = 0;
17876
17877 /* Process Type A response */
17878 if (!wlan_hdd_mdns_pack_response_type_a(ini_config, resp_info,
17879 &resptype_a))
17880 goto err_resptype_a;
17881
17882 if ((resptype_a.num_entries > 0) &&
17883 (strlen((char *)&resptype_a.data[0]) > 0))
17884 num_res_records++;
17885
17886 /* Process Type TXT response */
17887 if (!wlan_hdd_mdns_pack_response_type_txt(ini_config, resp_info,
17888 &resptype_txt, &resptype_a))
17889 goto err_resptype_txt;
17890
17891 if ((resptype_txt.num_entries > 0) &&
17892 (strlen((char *)&resptype_txt.data[0]) > 0))
17893 num_res_records++;
17894
17895 /* Process Type PTR response */
17896 if (!wlan_hdd_mdns_pack_response_type_ptr(ini_config, resp_info,
17897 &resptype_ptr, &resptype_ptr_dn,
17898 &resptype_txt, &resptype_a))
17899 goto err_resptype_ptr;
17900
17901 if ((resptype_ptr.num_entries > 0) &&
17902 (strlen((char *)&resptype_ptr.data[0]) > 0))
17903 num_res_records++;
17904
17905 /* Process Type SRV response */
17906 if (!wlan_hdd_mdns_pack_response_type_srv(ini_config, resp_info,
17907 &resptype_srv, &resptype_srv_tgt,
17908 &resptype_ptr, &resptype_ptr_dn,
17909 &resptype_txt, &resptype_a))
17910 goto err_resptype_srv;
17911
17912 if ((resptype_srv.num_entries > 0) &&
17913 (strlen((char *)&resptype_srv.data[0]) > 0))
17914 num_res_records++;
17915
17916 resp_info->resourceRecord_count = num_res_records;
17917 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
17918 "%s: Pack mDNS response data successfully!", __func__);
17919 status = TRUE;
17920
17921err_resptype_srv:
17922 wlan_hdd_mdns_free_mem(&resptype_srv);
17923 wlan_hdd_mdns_free_mem(&resptype_srv_tgt);
17924
17925err_resptype_ptr:
17926 wlan_hdd_mdns_free_mem(&resptype_ptr);
17927 wlan_hdd_mdns_free_mem(&resptype_ptr_dn);
17928
17929err_resptype_txt:
17930 wlan_hdd_mdns_free_mem(&resptype_txt);
17931
17932err_resptype_a:
17933 wlan_hdd_mdns_free_mem(&resptype_a);
17934
17935 EXIT();
17936 return status;
17937}
17938
17939/**
17940 * wlan_hdd_set_mdns_offload() - Enable mDNS offload
17941 * @hostapd_adapter: Pointer to the struct hdd_adapter_t
17942 *
17943 * This function will set FQDN/unique FQDN (full qualified domain name)
17944 * and the mDNS response. Then send them to SME.
17945 *
17946 * Return: Return boolean. TRUE for success, FALSE for fail.
17947 */
17948bool wlan_hdd_set_mdns_offload(hdd_adapter_t *hostapd_adapter)
17949{
17950 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
17951 sir_mdns_offload_info mdns_offload_info;
17952 sir_mdns_fqdn_info mdns_fqdn_info;
17953 sir_mdns_resp_info mdns_resp_info;
17954 uint32_t fqdn_len, ufqdn_len;
17955
17956 ENTER();
17957
17958 /* 1. Prepare the MDNS fqdn request to send to SME */
17959 fqdn_len = strlen(hdd_ctx->cfg_ini->mdns_fqdn);
17960 ufqdn_len = strlen(hdd_ctx->cfg_ini->mdns_uniquefqdn);
17961 if ((fqdn_len == 0) && (ufqdn_len == 0)) {
17962 hddLog(LOGE, FL("No mDNS FQDN or UFQDN is assigned fqdn_len %d,"
17963 "ufqdn_len %d!"), fqdn_len, ufqdn_len);
17964 return FALSE;
17965 }
17966
17967 mdns_fqdn_info = vos_mem_malloc(sizeof(*mdns_fqdn_info));
17968 if (NULL == mdns_fqdn_info) {
17969 hddLog(LOGE, FL("could not allocate tSirMDNSFqdnInfo!"));
17970 return FALSE;
17971 }
17972 /* MDNS fqdn request */
17973 if (fqdn_len > 0) {
17974 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
17975 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
17976 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_GENERAL;
17977 mdns_fqdn_info->fqdn_len = fqdn_len;
17978 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
17979 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
17980 vos_mem_copy(mdns_fqdn_info->fqdn_data,
17981 hdd_ctx->cfg_ini->mdns_fqdn,
17982 mdns_fqdn_info->fqdn_len);
17983
17984 if (eHAL_STATUS_SUCCESS !=
17985 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
17986 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
17987 vos_mem_free(mdns_fqdn_info);
17988 return FALSE;
17989 }
17990 }
17991 /* MDNS unique fqdn request */
17992 if (ufqdn_len > 0) {
17993 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
17994 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
17995 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_UNIQUE;
17996 mdns_fqdn_info->fqdn_len = ufqdn_len;
17997 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
17998 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
17999 vos_mem_copy(mdns_fqdn_info->fqdn_data,
18000 hdd_ctx->cfg_ini->mdns_uniquefqdn,
18001 mdns_fqdn_info->fqdn_len);
18002 if (eHAL_STATUS_SUCCESS !=
18003 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
18004 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
18005 vos_mem_free(mdns_fqdn_info);
18006 return FALSE;
18007 }
18008 }
18009 vos_mem_free(mdns_fqdn_info);
18010
18011 /* 2. Prepare the MDNS response request to send to SME */
18012 mdns_resp_info = vos_mem_malloc(sizeof(*mdns_resp_info));
18013 if (NULL == mdns_resp_info) {
18014 hddLog(LOGE, FL("could not allocate tSirMDNSResponseInfo!"));
18015 return FALSE;
18016 }
18017
18018 vos_mem_zero(mdns_resp_info, sizeof(*mdns_resp_info));
18019 mdns_resp_info->bss_idx = hostapd_adapter->sessionId;
18020 mdns_resp_info->mdns_resp_callback = hdd_mdns_resp_offload_done;
18021 mdns_resp_info->mdns_resp_cb_context = hostapd_adapter;
18022 if (!wlan_hdd_mdns_pack_response(hdd_ctx->cfg_ini, mdns_resp_info)) {
18023 hddLog(LOGE, FL("wlan_hdd_pack_mdns_response fail!"));
18024 vos_mem_free(mdns_resp_info);
18025 return FALSE;
18026 }
18027 if (eHAL_STATUS_SUCCESS !=
18028 sme_set_mdns_resp(hdd_ctx->hHal, mdns_resp_info)) {
18029 hddLog(LOGE, FL("sme_set_mdns_resp fail!"));
18030 vos_mem_free(mdns_resp_info);
18031 return FALSE;
18032 }
18033 vos_mem_free(mdns_resp_info);
18034
18035 /* 3. Prepare the MDNS Enable request to send to SME */
18036 mdns_offload_info = vos_mem_malloc(sizeof(*mdns_offload_info));
18037 if (NULL == mdns_offload_info) {
18038 hddLog(LOGE, FL("could not allocate tSirMDNSOffloadInfo!"));
18039 return FALSE;
18040 }
18041
18042 vos_mem_zero(mdns_offload_info, sizeof(*mdns_offload_info));
18043
18044 mdns_offload_info->bss_idx = hostapd_adapter->sessionId;
18045 mdns_offload_info->enable = hdd_ctx->cfg_ini->enable_mdns_offload;
18046 mdns_offload_info->mdns_enable_callback = hdd_mdns_enable_offload_done;
18047 mdns_offload_info->mdns_enable_cb_context = hostapd_adapter;
18048 if (eHAL_STATUS_SUCCESS !=
18049 sme_set_mdns_offload(hdd_ctx->hHal, mdns_offload_info)) {
18050 hddLog(LOGE, FL("sme_set_mdns_offload fail!"));
18051 vos_mem_free(mdns_offload_info);
18052 return FALSE;
18053 }
18054
18055 vos_mem_free(mdns_offload_info);
18056 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
18057 "%s: enable mDNS offload successfully!", __func__);
18058 return TRUE;
18059}
Manjeet Singh3ed79242017-01-11 19:04:32 +053018060
18061
Anurag Chouhan0b29de02016-12-16 13:18:40 +053018062#endif /* MDNS_OFFLOAD */
c_manjeecfd1efb2015-09-25 19:32:34 +053018063
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053018064/**
18065 * wlan_hdd_start_sap() - This function starts bss of SAP.
18066 * @ap_adapter: SAP adapter
18067 *
18068 * This function will process the starting of sap adapter.
18069 *
18070 * Return: void.
18071 */
18072void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter)
18073{
18074 hdd_ap_ctx_t *hdd_ap_ctx;
18075 hdd_hostapd_state_t *hostapd_state;
18076 VOS_STATUS vos_status;
18077 hdd_context_t *hdd_ctx;
18078 tsap_Config_t *pConfig;
18079
18080 if (NULL == ap_adapter) {
18081 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18082 FL("ap_adapter is NULL here"));
18083 return;
18084 }
18085
18086 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
18087 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
18088 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
18089 pConfig = &ap_adapter->sessionCtx.ap.sapConfig;
18090
18091 mutex_lock(&hdd_ctx->sap_lock);
18092 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
18093 goto end;
18094
18095 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
18096 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
18097 goto end;
18098 }
18099
18100 vos_event_reset(&hostapd_state->vosEvent);
18101 if (WLANSAP_StartBss(hdd_ctx->pvosContext, hdd_hostapd_SAPEventCB,
18102 &hdd_ap_ctx->sapConfig, (v_PVOID_t)ap_adapter->dev)
18103 != VOS_STATUS_SUCCESS) {
18104 goto end;
18105 }
18106
18107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
18108 FL("Waiting for SAP to start"));
18109 vos_status = vos_wait_single_event(&hostapd_state->vosEvent, 10000);
18110 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
18111 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18112 FL("SAP Start failed"));
18113 goto end;
18114 }
18115 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
18116 FL("SAP Start Success"));
18117 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
18118
18119 wlan_hdd_incr_active_session(hdd_ctx, ap_adapter->device_mode);
18120 hostapd_state->bCommit = TRUE;
18121
18122end:
18123 mutex_unlock(&hdd_ctx->sap_lock);
18124 return;
18125}
18126
Manjeet Singh3ed79242017-01-11 19:04:32 +053018127#ifdef WLAN_FEATURE_TSF
18128
18129/**
18130 * hdd_tsf_cb() - handle tsf request callback
18131 *
18132 * @pcb_cxt: pointer to the hdd_contex
18133 * @ptsf: pointer to struct stsf
18134 *
18135 * Based on the request sent .
18136 *
18137 * Return: Describe the execute result of this routine
18138 */
18139static int hdd_tsf_cb(void *pcb_ctx, struct stsf *ptsf)
18140{
18141 hdd_context_t *hddctx;
18142 int status;
18143 hdd_adapter_t* adapter = (hdd_adapter_t*)pcb_ctx;
18144
18145 if (pcb_ctx == NULL || ptsf == NULL) {
18146 hddLog(VOS_TRACE_LEVEL_ERROR,
18147 FL("HDD context is not valid"));
18148 return -EINVAL;
18149 }
18150
18151 hddctx = (hdd_context_t *)pcb_ctx;
18152 status = wlan_hdd_validate_context(hddctx);
18153 if (0 != status)
18154 return -EINVAL;
18155
18156 if (NULL == adapter) {
18157 hddLog(VOS_TRACE_LEVEL_ERROR,
18158 FL("failed to find adapter"));
18159 return -EINVAL;
18160 }
18161
18162 hddLog(VOS_TRACE_LEVEL_INFO,
18163 FL("tsf cb handle event, device_mode is %d"),
18164 adapter->device_mode);
18165
18166 /* copy the return value to hdd_tsf_ctx in adapter*/
18167 if (ptsf->tsf_req_status) {
18168
18169 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18170 adapter->tsf_cap_ctx.tsf_get_state = TSF_NOT_RETURNED_BY_FW;
18171 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18172 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
18173 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18174
18175 hddLog(VOS_TRACE_LEVEL_ERROR, FL("tsf req failure :%d"),
18176 ptsf->tsf_req_status);
18177 return ptsf->tsf_req_status;
18178 }
18179 /* If this is a get request.Store the tsf values in adapter. */
18180 if (!ptsf->set_tsf_req) {
18181 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18182 adapter->tsf_cap_ctx.tsf_low = ptsf->tsf_low;
18183 adapter->tsf_cap_ctx.tsf_high = ptsf->tsf_high;
18184 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
18185 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18186 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18187
18188 hddLog(VOS_TRACE_LEVEL_INFO,
18189 FL("hdd_get_tsf_cb sta=%u, tsf_low=%u, tsf_high=%u"),
18190 adapter->sessionId, ptsf->tsf_low, ptsf->tsf_high);
18191 }
18192 else {
18193 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18194 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
18195 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
18196 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18197 }
18198 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18199 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
18200 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18201
18202 /* free allocated mem */
18203 vos_mem_free(ptsf);
18204
18205 return 0;
18206}
18207
18208/**
18209 * hdd_capture_tsf() - capture tsf
18210 *
18211 * @adapter: pointer to adapter
18212 * @buf: pointer to upper layer buf
18213 * @len : the length of buf
18214 *
18215 * This function returns tsf value to uplayer.
18216 *
18217 * Return: Describe the execute result of this routine
18218 */
18219int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
18220{
18221 int ret = 0;
18222 hdd_station_ctx_t *hdd_sta_ctx;
18223 hdd_context_t *hdd_ctx;
18224 tSirCapTsfParams cap_tsf_params;
18225 VOS_STATUS status;
18226
18227 if (adapter == NULL || buf == NULL) {
18228 hddLog(VOS_TRACE_LEVEL_ERROR,
18229 FL("invalid pointer"));
18230 return -EINVAL;
18231 }
18232 if (len != 1)
18233 return -EINVAL;
18234
18235 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
18236
18237 if (wlan_hdd_validate_context(hdd_ctx)) {
18238 hddLog(VOS_TRACE_LEVEL_ERROR,
18239 FL("invalid hdd ctx"));
18240 return -EINVAL;
18241 }
18242 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18243 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
18244 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18245 if (hdd_sta_ctx->conn_info.connState !=
18246 eConnectionState_Associated) {
18247
18248 hddLog(VOS_TRACE_LEVEL_INFO,
18249 FL("failed to cap tsf, not connect with ap"));
18250 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
18251 return ret;
18252 }
18253 }
18254 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
18255 adapter->device_mode == WLAN_HDD_P2P_GO) &&
18256 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
18257 hddLog(VOS_TRACE_LEVEL_INFO,
18258 FL("Soft AP / P2p GO not beaconing"));
18259 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
18260 return ret;
18261 }
18262 if (adapter->tsf_cap_ctx.tsf_capture_state == TSF_CAP_STATE) {
18263 hddLog(VOS_TRACE_LEVEL_INFO,
18264 FL("current in capture state, pls reset"));
18265 buf[0] = TSF_CURRENT_IN_CAP_STATE;
18266 } else {
18267 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
18268 buf[0] = TSF_RETURN;
18269 cap_tsf_params.session_id = adapter->sessionId;
18270 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
18271 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
18272
18273 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18274 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
18275 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
18276 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18277
18278 ret = sme_capture_tsf_req(hdd_ctx->hHal, cap_tsf_params);
18279
18280 if (ret != VOS_STATUS_SUCCESS) {
18281 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
18282 buf[0] = TSF_CAPTURE_FAIL;
18283 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18284 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18285 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18286 return -EINVAL;
18287 }
18288 /* wait till we get a response from fw */
18289 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
18290 tsf_capture_done_event,
18291 HDD_TSF_CAP_REQ_TIMEOUT);
18292
18293 if (!VOS_IS_STATUS_SUCCESS(status)) {
18294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18295 ("capture tsf vos wait for single_event failed!! %d"),
18296 adapter->tsf_cap_ctx.tsf_get_state);
18297
18298 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18299 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18300 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18301
18302 return -EINVAL;
18303 }
18304 }
18305 buf[0] = TSF_RETURN;
18306 hddLog(VOS_TRACE_LEVEL_INFO,
18307 FL("ioctl return cap tsf cmd, ret = %d"), ret);
18308 return ret;
18309}
18310
18311/**
18312 * hdd_indicate_tsf() - return tsf to uplayer
18313 *
18314 * @adapter: pointer to adapter
18315 * @buf: pointer to uplayer buf
18316 * @len : the length of buf
18317 *
18318 * This function returns tsf value to uplayer.
18319 *
18320 * Return: Describe the execute result of this routine
18321 */
18322int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
18323{
18324 int ret = 0;
18325 hdd_station_ctx_t *hdd_sta_ctx;
18326 hdd_context_t *hdd_ctx;
18327 tSirCapTsfParams cap_tsf_params;
18328 VOS_STATUS status;
18329
18330 if (adapter == NULL || buf == NULL) {
18331 hddLog(VOS_TRACE_LEVEL_ERROR,
18332 FL("invalid pointer"));
18333 return -EINVAL;
18334 }
18335 if (len != 3)
18336 return -EINVAL;
18337
18338 buf [1] = 0;
18339 buf [2] = 0;
18340 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
18341
18342 if (wlan_hdd_validate_context(hdd_ctx)) {
18343 hddLog(VOS_TRACE_LEVEL_ERROR,
18344 FL("invalid hdd ctx"));
18345 return -EINVAL;
18346 }
18347 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18348 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
18349 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18350 if (hdd_sta_ctx->conn_info.connState !=
18351 eConnectionState_Associated) {
18352
18353 hddLog(VOS_TRACE_LEVEL_INFO,
18354 FL("failed to cap tsf, not connect with ap"));
18355 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
18356 return ret;
18357 }
18358 }
18359 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
18360 adapter->device_mode == WLAN_HDD_P2P_GO) &&
18361 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
18362 hddLog(VOS_TRACE_LEVEL_INFO,
18363 FL("Soft AP / P2p GO not beaconing"));
18364 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
18365 return ret;
18366 }
18367
18368 if (adapter->tsf_cap_ctx.tsf_capture_state != TSF_CAP_STATE ||
18369 adapter->tsf_cap_ctx.tsf_get_state != TSF_CURRENT_IN_CAP_STATE ) {
18370 hddLog(VOS_TRACE_LEVEL_INFO,
18371 FL("Not in capture state,Enter capture state first"));
18372 buf[0] = TSF_GET_FAIL;
18373 } else {
18374 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
18375 cap_tsf_params.session_id = adapter->sessionId;
18376 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
18377 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
18378
18379 ret = sme_get_tsf_req(hdd_ctx->hHal, cap_tsf_params);
18380
18381 if (ret != VOS_STATUS_SUCCESS) {
18382 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
18383 buf[0] = TSF_CAPTURE_FAIL;
18384 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18385 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18386 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18387 return -EINVAL;
18388 }
18389 /* wait till we get a response from fw */
18390 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
18391 tsf_capture_done_event,
18392 HDD_TSF_GET_REQ_TIMEOUT);
18393
18394 if (!VOS_IS_STATUS_SUCCESS(status)) {
18395 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18396 ("capture tsf vos wait for single_event failed!! %d"),
18397 status);
18398
18399 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18400 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18401 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18402 return status;
18403 }
18404 buf[1] = adapter->tsf_cap_ctx.tsf_low;
18405 buf[2] = adapter->tsf_cap_ctx.tsf_high;
18406
18407 hddLog(VOS_TRACE_LEVEL_INFO,
18408 FL("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u"),
18409 buf[0], buf[1], buf[2]);
18410 }
18411 hddLog(VOS_TRACE_LEVEL_INFO,
18412 FL("ioctl return cap tsf cmd, ret = %d"), ret);
18413 return ret;
18414}
18415
18416void wlan_hdd_tsf_init(hdd_adapter_t *adapter)
18417{
18418
18419 if (adapter == NULL) {
18420 hddLog(VOS_TRACE_LEVEL_ERROR,
18421 FL("TSF init on a null adapter!"));
18422 return;
18423 }
18424
18425 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
18426 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18427 vos_event_init(&adapter->tsf_cap_ctx.tsf_capture_done_event);
18428 vos_spin_lock_init(&adapter->tsf_cap_ctx.tsf_lock);
18429 adapter->tsf_cap_ctx.tsf_high = 0;
18430 adapter->tsf_cap_ctx.tsf_low = 0;
18431}
18432
18433#endif
18434
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +053018435bool hdd_is_memdump_supported(void)
18436{
18437#ifdef WLAN_FEATURE_MEMDUMP
18438 return true;
18439#endif
18440 return false;
18441}
18442
Hanumanth Reddy Pothula972e1df2018-06-14 13:33:47 +053018443bool hdd_is_cli_iface_up(hdd_context_t *hdd_ctx)
18444{
18445 hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
18446 hdd_adapter_t *adapter;
18447 VOS_STATUS status;
18448
18449 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
18450 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
18451 adapter = adapter_node->pAdapter;
18452 if ((adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18453 adapter->device_mode == WLAN_HDD_P2P_CLIENT) &&
18454 test_bit(DEVICE_IFACE_OPENED,
18455 &adapter->event_flags)){
18456 return true;
18457 }
18458 status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
18459 adapter_node = next;
18460 }
18461
18462 return false;
18463}
18464
Jeff Johnson295189b2012-06-20 16:38:30 -070018465//Register the module init/exit functions
18466module_init(hdd_module_init);
18467module_exit(hdd_module_exit);
18468
18469MODULE_LICENSE("Dual BSD/GPL");
18470MODULE_AUTHOR("Qualcomm Atheros, Inc.");
18471MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
18472
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018473static const struct kernel_param_ops con_mode_ops = {
18474 .set = con_mode_handler,
18475 .get = param_get_int,
18476};
18477
18478static const struct kernel_param_ops fwpath_ops = {
18479 .set = fwpath_changed_handler,
18480 .get = param_get_string,
18481};
18482
Hanumanth Reddy Pothula99219872018-06-08 14:45:18 +053018483#ifdef MODULE
18484module_param(con_mode, int, 0);
18485#else
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018486module_param_cb(con_mode, &con_mode_ops, &con_mode,
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070018487 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Hanumanth Reddy Pothula99219872018-06-08 14:45:18 +053018488#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -070018489
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018490module_param_cb(fwpath, &fwpath_ops, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070018491 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080018492
18493module_param(enable_dfs_chan_scan, int,
18494 S_IRUSR | S_IRGRP | S_IROTH);
18495
18496module_param(enable_11d, int,
18497 S_IRUSR | S_IRGRP | S_IROTH);
18498
18499module_param(country_code, charp,
18500 S_IRUSR | S_IRGRP | S_IROTH);