blob: d9ef048c01b29db2b62d58d52f1ebdb3441c20ce [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;
c_hpothu92367912014-05-01 15:18:17 +0530154static int gbcnMissRate = -1;
Arif Hussain66559122013-11-21 10:11:40 -0800155
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700156#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700157static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700158#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700159
Jeff Johnsone7245742012-09-05 17:12:55 -0700160/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800161 * spinlock for synchronizing asynchronous request/response
162 * (full description of use in wlan_hdd_main.h)
163 */
164DEFINE_SPINLOCK(hdd_context_lock);
165
166/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700167 * The rate at which the driver sends RESTART event to supplicant
168 * once the function 'vos_wlanRestart()' is called
169 *
170 */
171#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
172#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700173
174/*
175 * Size of Driver command strings from upper layer
176 */
177#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
178#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
179
Abhishek Singh00b71972016-01-07 10:51:04 +0530180#ifdef WLAN_FEATURE_RMC
181/*
182 * Ibss prop IE from command will be of size:
183 * size = sizeof(oui) + sizeof(oui_data) + 1(Element ID) + 1(EID Length)
184 * OUI_DATA should be at least 3 bytes long
185 */
186#define WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH (3)
187#endif
188
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800189#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700190#define TID_MIN_VALUE 0
191#define TID_MAX_VALUE 15
192static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
193 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800194static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
195 tCsrEseBeaconReq *pEseBcnReq);
196#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700197
Atul Mittal1d722422014-03-19 11:15:07 +0530198/*
199 * Maximum buffer size used for returning the data back to user space
200 */
201#define WLAN_MAX_BUF_SIZE 1024
202#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700203
Abhishek Singh00b71972016-01-07 10:51:04 +0530204/*
205 * When ever we need to print IBSSPEERINFOALL for morethan 16 STA
206 * we will split the printing.
207 */
208#define NUM_OF_STA_DATA_TO_PRINT 16
209
210#ifdef WLAN_FEATURE_RMC
211#define WLAN_NLINK_CESIUM 30
212#endif
213
c_hpothu92367912014-05-01 15:18:17 +0530214//wait time for beacon miss rate.
215#define BCN_MISS_RATE_TIME 500
216
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +0530217/*
218 * Android DRIVER command structures
219 */
220struct android_wifi_reassoc_params {
221 unsigned char bssid[18];
222 int channel;
223};
224
Sushant Kaushik83392fa2015-05-05 17:44:40 +0530225static vos_wake_lock_t wlan_wake_lock;
226
Jeff Johnson295189b2012-06-20 16:38:30 -0700227/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700228static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700229
230//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700231static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
232static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
233static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
Abhishek Singh00b71972016-01-07 10:51:04 +0530234
235#ifdef WLAN_FEATURE_RMC
236static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo);
237
238static int hdd_open_cesium_nl_sock(void);
239static void hdd_close_cesium_nl_sock(void);
240static struct sock *cesium_nl_srv_sock;
241static v_U16_t cesium_pid;
242
243static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
244 tANI_U8 *tx_fail_count,
245 tANI_U16 *pid);
246
247static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg);
248
249#endif /* WLAN_FEATURE_RMC */
Jeff Johnsone7245742012-09-05 17:12:55 -0700250void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800251void hdd_set_wlan_suspend_mode(bool suspend);
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530252void hdd_set_vowifi_mode(hdd_context_t *hdd_ctx, bool enable);
Jeff Johnsone7245742012-09-05 17:12:55 -0700253
Jeff Johnson295189b2012-06-20 16:38:30 -0700254v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +0530255 struct sk_buff *skb
256#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
257 , void *accel_priv
258#endif
259#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
260 , select_queue_fallback_t fallback
261#endif
262);
Jeff Johnson295189b2012-06-20 16:38:30 -0700263
264#ifdef WLAN_FEATURE_PACKET_FILTERING
265static void hdd_set_multicast_list(struct net_device *dev);
266#endif
267
268void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
269
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800270#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800271void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
272static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700273static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
274 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
275 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +0530276static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
277 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800278#endif
Ratheesh S P21280412015-05-19 14:21:52 +0530279
280/* Store WLAN driver info in a global variable such that crash debugger
281 can extract it from driver debug symbol and crashdump for post processing */
282tANI_U8 g_wlan_driver[ ] = "pronto_driver";
283
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800284#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700285VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800286#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700287
Mihir Shetee1093ba2014-01-21 20:13:32 +0530288static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530289const char * hdd_device_modetoString(v_U8_t device_mode)
290{
291 switch(device_mode)
292 {
293 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
294 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
295 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
296 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
297 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
298 CASE_RETURN_STRING( WLAN_HDD_FTM );
299 CASE_RETURN_STRING( WLAN_HDD_IBSS );
300 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
301 default:
302 return "device_mode Unknown";
303 }
304}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530305
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530306static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700307 unsigned long state,
308 void *ndev)
309{
310 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700311 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700312 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700313#ifdef WLAN_BTAMP_FEATURE
314 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700315#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530316 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700317
318 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700319 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700320 (strncmp(dev->name, "p2p", 3)))
321 return NOTIFY_DONE;
322
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700324 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700325
Jeff Johnson27cee452013-03-27 11:10:24 -0700326 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700327 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800328 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700329 VOS_ASSERT(0);
330 return NOTIFY_DONE;
331 }
332
Jeff Johnson27cee452013-03-27 11:10:24 -0700333 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
334 if (NULL == pHddCtx)
335 {
336 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
337 VOS_ASSERT(0);
338 return NOTIFY_DONE;
339 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800340 if (pHddCtx->isLogpInProgress)
341 return NOTIFY_DONE;
342
Jeff Johnson27cee452013-03-27 11:10:24 -0700343
344 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
345 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700346
347 switch (state) {
348 case NETDEV_REGISTER:
349 break;
350
351 case NETDEV_UNREGISTER:
352 break;
353
354 case NETDEV_UP:
355 break;
356
357 case NETDEV_DOWN:
358 break;
359
360 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700361 if(TRUE == pAdapter->isLinkUpSvcNeeded)
362 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700363 break;
364
365 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530366 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530367 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530368 {
369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
370 "%s: Timeout occurred while waiting for abortscan %ld",
371 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700372 }
373 else
374 {
375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530376 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700377 }
378#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700379 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700380 status = WLANBAP_StopAmp();
381 if(VOS_STATUS_SUCCESS != status )
382 {
383 pHddCtx->isAmpAllowed = VOS_TRUE;
384 hddLog(VOS_TRACE_LEVEL_FATAL,
385 "%s: Failed to stop AMP", __func__);
386 }
387 else
388 {
389 //a state m/c implementation in PAL is TBD to avoid this delay
390 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700391 if ( pHddCtx->isAmpAllowed )
392 {
393 WLANBAP_DeregisterFromHCI();
394 pHddCtx->isAmpAllowed = VOS_FALSE;
395 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700396 }
397#endif //WLAN_BTAMP_FEATURE
398 break;
399
400 default:
401 break;
402 }
403
404 return NOTIFY_DONE;
405}
406
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530407static int hdd_netdev_notifier_call(struct notifier_block * nb,
408 unsigned long state,
409 void *ndev)
410{
411 int ret;
412 vos_ssr_protect(__func__);
413 ret = __hdd_netdev_notifier_call( nb, state, ndev);
414 vos_ssr_unprotect(__func__);
415 return ret;
416}
417
Jeff Johnson295189b2012-06-20 16:38:30 -0700418struct notifier_block hdd_netdev_notifier = {
419 .notifier_call = hdd_netdev_notifier_call,
420};
421
422/*---------------------------------------------------------------------------
423 * Function definitions
424 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700425void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
426void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700427//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700428static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700429#ifndef MODULE
430/* current con_mode - used only for statically linked driver
431 * con_mode is changed by userspace to indicate a mode change which will
432 * result in calling the module exit and init functions. The module
433 * exit function will clean up based on the value of con_mode prior to it
434 * being changed by userspace. So curr_con_mode records the current con_mode
435 * for exit when con_mode becomes the next mode for init
436 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700437static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700438#endif
439
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +0530440#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
441/**
442 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
443 * @hdd_ctx: hdd global context
444 *
445 * Return: none
446 */
447static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
448{
449 uint8_t i;
450
451 mutex_init(&hdd_ctx->op_ctx.op_lock);
452 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
453 {
454 hdd_ctx->op_ctx.op_table[i].request_id = 0;
455 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
456 }
457}
458#else
459static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
460{
461}
462#endif
463
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800464/**---------------------------------------------------------------------------
465
466 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
467
468 Called immediately after the cfg.ini is read in order to configure
469 the desired trace levels.
470
471 \param - moduleId - module whose trace level is being configured
472 \param - bitmask - bitmask of log levels to be enabled
473
474 \return - void
475
476 --------------------------------------------------------------------------*/
477static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
478{
479 wpt_tracelevel level;
480
481 /* if the bitmask is the default value, then a bitmask was not
482 specified in cfg.ini, so leave the logging level alone (it
483 will remain at the "compiled in" default value) */
484 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
485 {
486 return;
487 }
488
489 /* a mask was specified. start by disabling all logging */
490 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
491
492 /* now cycle through the bitmask until all "set" bits are serviced */
493 level = VOS_TRACE_LEVEL_FATAL;
494 while (0 != bitmask)
495 {
496 if (bitmask & 1)
497 {
498 vos_trace_setValue(moduleId, level, 1);
499 }
500 level++;
501 bitmask >>= 1;
502 }
503}
504
505
Jeff Johnson295189b2012-06-20 16:38:30 -0700506/**---------------------------------------------------------------------------
507
508 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
509
510 Called immediately after the cfg.ini is read in order to configure
511 the desired trace levels in the WDI.
512
513 \param - moduleId - module whose trace level is being configured
514 \param - bitmask - bitmask of log levels to be enabled
515
516 \return - void
517
518 --------------------------------------------------------------------------*/
519static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
520{
521 wpt_tracelevel level;
522
523 /* if the bitmask is the default value, then a bitmask was not
524 specified in cfg.ini, so leave the logging level alone (it
525 will remain at the "compiled in" default value) */
526 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
527 {
528 return;
529 }
530
531 /* a mask was specified. start by disabling all logging */
532 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
533
534 /* now cycle through the bitmask until all "set" bits are serviced */
535 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
536 while (0 != bitmask)
537 {
538 if (bitmask & 1)
539 {
540 wpalTraceSetLevel(moduleId, level, 1);
541 }
542 level++;
543 bitmask >>= 1;
544 }
545}
Jeff Johnson295189b2012-06-20 16:38:30 -0700546
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530547/*
548 * FUNCTION: wlan_hdd_validate_context
549 * This function is used to check the HDD context
550 */
551int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
552{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530553
554 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
555 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530557 "%s: HDD context is Null", __func__);
558 return -ENODEV;
559 }
560
561 if (pHddCtx->isLogpInProgress)
562 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530564 "%s: LOGP %s. Ignore!!", __func__,
565 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
566 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530567 return -EAGAIN;
568 }
569
Mihir Shete18156292014-03-11 15:38:30 +0530570 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530571 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530573 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
574 return -EAGAIN;
575 }
576 return 0;
577}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700578#ifdef CONFIG_ENABLE_LINUX_REG
579void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
580{
581 hdd_adapter_t *pAdapter = NULL;
582 hdd_station_ctx_t *pHddStaCtx = NULL;
583 eCsrPhyMode phyMode;
584 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530585
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700586 if (NULL == pHddCtx)
587 {
588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
589 "HDD Context is null !!");
590 return ;
591 }
592
593 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
594 if (NULL == pAdapter)
595 {
596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
597 "pAdapter is null !!");
598 return ;
599 }
600
601 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
602 if (NULL == pHddStaCtx)
603 {
604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
605 "pHddStaCtx is null !!");
606 return ;
607 }
608
609 cfg_param = pHddCtx->cfg_ini;
610 if (NULL == cfg_param)
611 {
612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
613 "cfg_params not available !!");
614 return ;
615 }
616
617 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
618
619 if (!pHddCtx->isVHT80Allowed)
620 {
621 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
622 (eCSR_DOT11_MODE_11ac == phyMode) ||
623 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
624 {
625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
626 "Setting phymode to 11n!!");
627 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
628 }
629 }
630 else
631 {
632 /*New country Supports 11ac as well resetting value back from .ini*/
633 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
634 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
635 return ;
636 }
637
638 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
639 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
640 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
641 {
642 VOS_STATUS vosStatus;
643
644 // need to issue a disconnect to CSR.
645 INIT_COMPLETION(pAdapter->disconnect_comp_var);
646 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
647 pAdapter->sessionId,
648 eCSR_DISCONNECT_REASON_UNSPECIFIED );
649
650 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530651 {
652 long ret;
653
654 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700655 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530656 if (0 >= ret)
657 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
658 ret);
659 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700660
661 }
662}
663#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530664void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
665{
666 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
667 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
668 hdd_config_t *cfg_param;
669 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530670 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530671
672 if (NULL == pHddCtx)
673 {
674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
675 "HDD Context is null !!");
676 return ;
677 }
678
679 cfg_param = pHddCtx->cfg_ini;
680
681 if (NULL == cfg_param)
682 {
683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
684 "cfg_params not available !!");
685 return ;
686 }
687
688 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
689
690 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
691 {
692 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
693 (eCSR_DOT11_MODE_11ac == phyMode) ||
694 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
695 {
696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
697 "Setting phymode to 11n!!");
698 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
699 }
700 }
701 else
702 {
703 /*New country Supports 11ac as well resetting value back from .ini*/
704 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
705 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
706 return ;
707 }
708
709 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
710 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
711 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
712 {
713 VOS_STATUS vosStatus;
714
715 // need to issue a disconnect to CSR.
716 INIT_COMPLETION(pAdapter->disconnect_comp_var);
717 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
718 pAdapter->sessionId,
719 eCSR_DISCONNECT_REASON_UNSPECIFIED );
720
721 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530722 {
723 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530724 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530725 if (ret <= 0)
726 {
727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
728 "wait on disconnect_comp_var is failed %ld", ret);
729 }
730 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530731
732 }
733}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700734#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530735
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700736void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
737{
738 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
739 hdd_config_t *cfg_param;
740
741 if (NULL == pHddCtx)
742 {
743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
744 "HDD Context is null !!");
745 return ;
746 }
747
748 cfg_param = pHddCtx->cfg_ini;
749
750 if (NULL == cfg_param)
751 {
752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
753 "cfg_params not available !!");
754 return ;
755 }
756
Agarwal Ashish738843c2014-09-25 12:27:56 +0530757 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
758 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700759 {
760 /*New country doesn't support DFS */
761 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
762 }
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700763
764}
765
Abhishek Singh00b71972016-01-07 10:51:04 +0530766#ifdef WLAN_FEATURE_RMC
767static int hdd_parse_setrmcenable_command(tANI_U8 *pValue, tANI_U8 *pRmcEnable)
768{
769 tANI_U8 *inPtr = pValue;
770 int tempInt;
771 int v = 0;
772 char buf[32];
773 *pRmcEnable = 0;
774
775 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
776 /*no argument after the command*/
777 if (NULL == inPtr)
778 {
779 return 0;
780 }
781
782 /*no space after the command*/
783 else if (SPACE_ASCII_VALUE != *inPtr)
784 {
785 return 0;
786 }
787
788 /*removing empty spaces*/
789 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
790
791 /*no argument followed by spaces*/
792 if ('\0' == *inPtr)
793 {
794 return 0;
795 }
796
797 /* getting the first argument which enables or disables RMC
798 * for input IP v4 address*/
Ashish Kumar Dhanotiya54d31a32017-08-04 17:12:44 +0530799 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530800 v = kstrtos32(buf, 10, &tempInt);
801 if ( v < 0)
802 {
803 return -EINVAL;
804 }
805
806 *pRmcEnable = tempInt;
807
808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
809 "ucRmcEnable: %d", *pRmcEnable);
810
811 return 0;
812}
813
814/* Function header left blank Intentionally */
815static int hdd_parse_setrmcactionperiod_command(tANI_U8 *pValue,
816 tANI_U32 *pActionPeriod)
817{
818 tANI_U8 *inPtr = pValue;
819 int tempInt;
820 int v = 0;
821 char buf[32];
822 *pActionPeriod = 0;
823
824 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
825 /*no argument after the command*/
826 if (NULL == inPtr)
827 {
828 return -EINVAL;
829 }
830
831 /*no space after the command*/
832 else if (SPACE_ASCII_VALUE != *inPtr)
833 {
834 return -EINVAL;
835 }
836
837 /*removing empty spaces*/
838 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
839
840 /*no argument followed by spaces*/
841 if ('\0' == *inPtr)
842 {
843 return 0;
844 }
845
846 /* getting the first argument which enables or disables RMC
847 * for input IP v4 address*/
Ashish Kumar Dhanotiya54d31a32017-08-04 17:12:44 +0530848 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530849 v = kstrtos32(buf, 10, &tempInt);
850 if ( v < 0)
851 {
852 return -EINVAL;
853 }
854
855 /* Range checking for passed paramter */
856 if (tempInt < WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN ||
857 tempInt > WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX)
858 {
859 return -EINVAL;
860 }
861
862 *pActionPeriod = tempInt;
863
864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
865 "uActionPeriod: %d", *pActionPeriod);
866
867 return 0;
868}
Dundi Ravitejae110a042018-04-18 13:11:37 +0530869
870/**
871 * hdd_set_vowifi_mode() - Process VOWIFI command.
872 * @hdd_ctx: context handler
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530873 * @enable: Value to be sent as a part of the VOWIFI command
874 *
Dundi Ravitejae110a042018-04-18 13:11:37 +0530875 * Invoke the SME api if station is connected in 2.4 GHz band.
876 * Also start split scan if VOWIFIMODE and dynamic split scan
877 * both are enabled.
878
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530879 * Return: void
880 */
881void hdd_set_vowifi_mode(hdd_context_t *hdd_ctx, bool enable)
882{
883 tANI_U8 sta_chan;
884
Dundi Ravitejaab9d3092018-04-05 18:24:40 +0530885 if (!hdd_ctx->cfg_ini) {
886 hddLog(LOGE, "cfg_ini got NULL");
887 return;
888 }
889
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530890 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
891
Dundi Ravitejae110a042018-04-18 13:11:37 +0530892 if (CSR_IS_CHANNEL_24GHZ(sta_chan))
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530893 sme_set_vowifi_mode(hdd_ctx->hHal, enable);
Dundi Ravitejae110a042018-04-18 13:11:37 +0530894 else
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530895 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
896 "VoWiFi command rejected as not connected in 2.4GHz");
Dundi Ravitejae110a042018-04-18 13:11:37 +0530897
898 if (enable && hdd_ctx->cfg_ini->dynSplitscan) {
899 hdd_ctx->is_vowifi_enabled = true;
900 hdd_ctx->issplitscan_enabled = TRUE;
901 sme_enable_disable_split_scan(hdd_ctx->hHal,
902 hdd_ctx->cfg_ini->nNumStaChanCombinedConc,
903 hdd_ctx->cfg_ini->nNumP2PChanCombinedConc);
904 } else {
905 hdd_ctx->is_vowifi_enabled = false;
Dundi Ravitejaab9d3092018-04-05 18:24:40 +0530906 }
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530907}
Abhishek Singh00b71972016-01-07 10:51:04 +0530908
909/* Function header left blank Intentionally */
910static int hdd_parse_setrmcrate_command(tANI_U8 *pValue,
911 tANI_U32 *pRate, tTxrateinfoflags *pTxFlags)
912{
913 tANI_U8 *inPtr = pValue;
914 int tempInt;
915 int v = 0;
916 char buf[32];
917 *pRate = 0;
918 *pTxFlags = 0;
919
920 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
921 /*no argument after the command*/
922 if (NULL == inPtr)
923 {
924 return -EINVAL;
925 }
926
927 /*no space after the command*/
928 else if (SPACE_ASCII_VALUE != *inPtr)
929 {
930 return -EINVAL;
931 }
932
933 /*removing empty spaces*/
934 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
935
936 /*no argument followed by spaces*/
937 if ('\0' == *inPtr)
938 {
939 return 0;
940 }
941
942 /*
943 * getting the first argument which sets multicast rate.
944 */
Ashish Kumar Dhanotiya06f9f202017-08-04 15:26:27 +0530945 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530946 v = kstrtos32(buf, 10, &tempInt);
947 if ( v < 0)
948 {
949 return -EINVAL;
950 }
951
952 /*
953 * Validate the multicast rate.
954 */
955 switch (tempInt)
956 {
957 default:
958 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
959 "Unsupported rate: %d", tempInt);
960 return -EINVAL;
961 case 0:
962 case 6:
963 case 9:
964 case 12:
965 case 18:
966 case 24:
967 case 36:
968 case 48:
969 case 54:
970 *pTxFlags = eHAL_TX_RATE_LEGACY;
971 *pRate = tempInt * 10;
972 break;
973 case 65:
974 *pTxFlags = eHAL_TX_RATE_HT20;
975 *pRate = tempInt * 10;
976 break;
977 case 72:
978 *pTxFlags = eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;
979 *pRate = 722; /* fractional rate 72.2 Mbps */
980 break;
981 }
982
983 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
984 "Rate: %d", *pRate);
985
986 return 0;
987}
988
989/**---------------------------------------------------------------------------
990
991 \brief hdd_cfg80211_get_ibss_peer_info_cb() - Callback function for IBSS
992 Peer Info request
993
994 This is an asynchronous callback function from SME when the peer info
995 is received
996
997 \pUserData -> Adapter private data
998 \pPeerInfoRsp -> Peer info response
999
1000 \return - 0 for success non-zero for failure
1001 --------------------------------------------------------------------------*/
1002static void
1003hdd_cfg80211_get_ibss_peer_info_cb(v_VOID_t *pUserData, v_VOID_t *pPeerInfoRsp)
1004{
1005 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pUserData;
1006 tSirPeerInfoRspParams *pPeerInfo = (tSirPeerInfoRspParams *)pPeerInfoRsp;
1007 hdd_station_ctx_t *pStaCtx;
1008 v_U8_t i;
1009
1010 /*Sanity check*/
1011 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
1012 {
1013 hddLog(LOGE,
1014 FL("invalid adapter or adapter has invalid magic"));
1015 return;
1016 }
1017
1018 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1019 if (NULL != pStaCtx && NULL != pPeerInfo &&
1020 eHAL_STATUS_SUCCESS == pPeerInfo->status)
1021 {
1022 pStaCtx->ibss_peer_info.status = pPeerInfo->status;
1023 pStaCtx->ibss_peer_info.numIBSSPeers = pPeerInfo->numPeers;
1024
1025 /* Paranoia check */
1026 if (pPeerInfo->numPeers < HDD_MAX_NUM_IBSS_STA)
1027 {
1028 for (i = 0; i < pPeerInfo->numPeers; i++)
1029 {
1030 memcpy(&pStaCtx->ibss_peer_info.ibssPeerList[i],
1031 &pPeerInfo->peerInfoParams[i],
1032 sizeof(hdd_ibss_peer_info_params_t));
1033 }
1034 hddLog(LOG1,
1035 FL("Peer Info copied in HDD"));
1036 }
1037 else
1038 {
1039 hddLog(LOGE,
1040 FL(" Number of peers %d returned is more than limit %d"),
1041 pPeerInfo->numPeers, HDD_MAX_NUM_IBSS_STA);
1042 }
1043 }
1044 else
1045 {
1046 hddLog(LOG1,
1047 FL("peerInfo returned is NULL"));
1048 }
1049
1050 complete(&pAdapter->ibss_peer_info_comp);
1051}
1052
1053/**---------------------------------------------------------------------------
1054
1055 \brief hdd_cfg80211_get_ibss_peer_info_all() -
1056
1057 Request function to get IBSS peer info from lower layers
1058
1059 \pAdapter -> Adapter context
1060
1061 \return - 0 for success non-zero for failure
1062 --------------------------------------------------------------------------*/
1063static
1064VOS_STATUS hdd_cfg80211_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
1065{
1066 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1067 long status;
1068 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1069
1070 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1071
1072 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1073 hdd_cfg80211_get_ibss_peer_info_cb,
1074 VOS_TRUE, 0xFF);
1075
1076 if (VOS_STATUS_SUCCESS == retStatus)
1077 {
1078 status = wait_for_completion_interruptible_timeout
1079 (&pAdapter->ibss_peer_info_comp,
1080 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1081
1082 /* status will be 0 if timed out */
1083 if (status <= 0)
1084 {
1085 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1086 __func__, status);
1087 retStatus = VOS_STATUS_E_FAILURE;
1088 return retStatus;
1089 }
1090 }
1091 else
1092 {
1093 hddLog(VOS_TRACE_LEVEL_WARN,
1094 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1095 }
1096
1097 return retStatus;
1098}
1099
1100/**---------------------------------------------------------------------------
1101
1102 \brief hdd_cfg80211_get_ibss_peer_info() -
1103
1104 Request function to get IBSS peer info from lower layers
1105
1106 \pAdapter -> Adapter context
1107 \staIdx -> Sta index for which the peer info is requested
1108
1109 \return - 0 for success non-zero for failure
1110 --------------------------------------------------------------------------*/
1111static VOS_STATUS
1112hdd_cfg80211_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx)
1113{
1114 long status;
1115 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1116 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1117
1118 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1119
1120 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1121 hdd_cfg80211_get_ibss_peer_info_cb,
1122 VOS_FALSE, staIdx);
1123
1124 if (VOS_STATUS_SUCCESS == retStatus)
1125 {
1126 status = wait_for_completion_interruptible_timeout
1127 (&pAdapter->ibss_peer_info_comp,
1128 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1129
1130 /* status = 0 on timeout */
1131 if (status <= 0)
1132 {
1133 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1134 __func__, status);
1135 retStatus = VOS_STATUS_E_FAILURE;
1136 return retStatus;
1137 }
1138 }
1139 else
1140 {
1141 hddLog(VOS_TRACE_LEVEL_WARN,
1142 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1143 }
1144
1145 return retStatus;
1146}
1147
1148/* Function header left blank Intentionally */
1149VOS_STATUS
1150hdd_parse_get_ibss_peer_info(tANI_U8 *pValue, v_MACADDR_t *pPeerMacAddr)
1151{
1152 tANI_U8 *inPtr = pValue;
1153 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1154
1155 /*no argument after the command*/
1156 if (NULL == inPtr)
1157 {
1158 return VOS_STATUS_E_FAILURE;;
1159 }
1160
1161 /*no space after the command*/
1162 else if (SPACE_ASCII_VALUE != *inPtr)
1163 {
1164 return VOS_STATUS_E_FAILURE;;
1165 }
1166
1167 /*removing empty spaces*/
1168 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
1169
1170 /*no argument followed by spaces*/
1171 if ('\0' == *inPtr)
1172 {
1173 return VOS_STATUS_E_FAILURE;;
1174 }
1175
1176 /*getting the first argument ie the peer mac address */
1177 if (inPtr[2] != ':' || inPtr[5] != ':' || inPtr[8] != ':' ||
1178 inPtr[11] != ':' || inPtr[14] != ':')
1179 {
1180 return VOS_STATUS_E_FAILURE;;
1181 }
1182 sscanf(inPtr, "%2x:%2x:%2x:%2x:%2x:%2x",
1183 (unsigned int *)&pPeerMacAddr->bytes[0],
1184 (unsigned int *)&pPeerMacAddr->bytes[1],
1185 (unsigned int *)&pPeerMacAddr->bytes[2],
1186 (unsigned int *)&pPeerMacAddr->bytes[3],
1187 (unsigned int *)&pPeerMacAddr->bytes[4],
1188 (unsigned int *)&pPeerMacAddr->bytes[5]);
1189
1190 /* The command buffer seems to be fine */
1191 return VOS_STATUS_SUCCESS;
1192}
1193
1194/* Function header left blank Intentionally */
1195static int hdd_parse_set_ibss_oui_data_command(tANI_U8 *command, tANI_U8 *ie,
1196 tANI_U32 limit)
1197{
1198 tANI_U8 len;
1199 tANI_U8 data;
1200
1201 /* skip white space */
1202 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1203 {
1204 command++;
1205 limit--;
1206 }
1207
1208 /* skip element id and element length */
1209 len = 2;
1210
1211 /* extract oui */
1212 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1213 (limit > 1))
1214 {
1215 /* Convert ASCII to decimal */
1216 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1217 ie[len++] = data;
1218 command += 2;
1219 limit -= 2;
1220 }
1221
1222 /* skip white space */
1223 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1224 {
1225 command++;
1226 limit--;
1227 }
1228
1229 /* extract data */
1230 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1231 (limit > 1))
1232 {
1233 /* Convert ASCII to decimal */
1234 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1235 ie[len++] = data;
1236 command += 2;
1237 limit -= 2;
1238 }
1239
1240 /* fill element id and element length */
1241 ie[0] = IE_EID_VENDOR;
1242 ie[1] = len - 2;
1243
1244 return len;
1245}
1246
1247static tANI_U32 hdd_find_ibss_wpa_ie_pos(tANI_U8 *addIePtr, tANI_U32 addIeLen)
1248{
1249 tANI_U32 ieLenPresent = 0;
1250 int left = addIeLen;
1251 v_U8_t *ptr = addIePtr;
1252 v_U8_t elem_id,elem_len;
1253
1254 while(left >= 2)
1255 {
1256 elem_id = ptr[0];
1257 elem_len = ptr[1];
1258 left -= 2;
1259 if(elem_len > left)
1260 {
1261 hddLog(LOGE,
1262 FL("****Invalid elem_len=%d left=%d*****"),
1263 elem_len,left);
1264 return 0;
1265 }
1266 if ((elem_id == IE_EID_VENDOR) &&
1267 (left >= WPA_OUI_TYPE_SIZE))
1268 {
1269 if (!memcmp(&ptr[2], WPA_OUI_TYPE,
1270 WPA_OUI_TYPE_SIZE))
1271 {
1272 ieLenPresent += elem_len + 2;
1273 return ieLenPresent;
1274 }
1275 }
1276 ieLenPresent += (elem_len + 2);
1277 left -= elem_len;
1278 ptr += (elem_len + 2);
1279 }
1280 return 0;
1281}
1282
1283#endif /* WLAN_FEATURE_RMC */
1284
Rajeev79dbe4c2013-10-05 11:03:42 +05301285#ifdef FEATURE_WLAN_BATCH_SCAN
1286
1287/**---------------------------------------------------------------------------
1288
1289 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
1290 input string
1291
1292 This function extracts assigned integer from string in below format:
1293 "STRING=10" : extracts integer 10 from this string
1294
1295 \param - pInPtr Pointer to input string
1296 \param - base Base for string to int conversion(10 for decimal 16 for hex)
1297 \param - pOutPtr Pointer to variable in which extracted integer needs to be
1298 assigned
1299 \param - pLastArg to tell whether it is last arguement in input string or
1300 not
1301
1302 \return - NULL for failure cases
1303 pointer to next arguement in input string for success cases
1304 --------------------------------------------------------------------------*/
1305static tANI_U8 *
1306hdd_extract_assigned_int_from_str
1307(
1308 tANI_U8 *pInPtr,
1309 tANI_U8 base,
1310 tANI_U32 *pOutPtr,
1311 tANI_U8 *pLastArg
1312)
1313{
1314 int tempInt;
1315 int v = 0;
1316 char buf[32];
1317 int val = 0;
1318 *pLastArg = FALSE;
1319
1320 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1321 if (NULL == pInPtr)
1322 {
1323 return NULL;
1324 }
1325
1326 pInPtr++;
1327
1328 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1329
1330 val = sscanf(pInPtr, "%32s ", buf);
1331 if (val < 0 && val > strlen(pInPtr))
1332 {
1333 return NULL;
1334 }
1335 pInPtr += val;
1336 v = kstrtos32(buf, base, &tempInt);
1337 if (v < 0)
1338 {
1339 return NULL;
1340 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -08001341 if (tempInt < 0)
1342 {
1343 tempInt = 0;
1344 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301345 *pOutPtr = tempInt;
1346
1347 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1348 if (NULL == pInPtr)
1349 {
1350 *pLastArg = TRUE;
1351 return NULL;
1352 }
1353 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1354
1355 return pInPtr;
1356}
1357
1358/**---------------------------------------------------------------------------
1359
1360 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
1361 input string
1362
1363 This function extracts assigned character from string in below format:
1364 "STRING=A" : extracts char 'A' from this string
1365
1366 \param - pInPtr Pointer to input string
1367 \param - pOutPtr Pointer to variable in which extracted char needs to be
1368 assigned
1369 \param - pLastArg to tell whether it is last arguement in input string or
1370 not
1371
1372 \return - NULL for failure cases
1373 pointer to next arguement in input string for success cases
1374 --------------------------------------------------------------------------*/
1375static tANI_U8 *
1376hdd_extract_assigned_char_from_str
1377(
1378 tANI_U8 *pInPtr,
1379 tANI_U8 *pOutPtr,
1380 tANI_U8 *pLastArg
1381)
1382{
1383 *pLastArg = FALSE;
1384
1385 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1386 if (NULL == pInPtr)
1387 {
1388 return NULL;
1389 }
1390
1391 pInPtr++;
1392
1393 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1394
1395 *pOutPtr = *pInPtr;
1396
1397 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1398 if (NULL == pInPtr)
1399 {
1400 *pLastArg = TRUE;
1401 return NULL;
1402 }
1403 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1404
1405 return pInPtr;
1406}
1407
1408
1409/**---------------------------------------------------------------------------
1410
1411 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
1412
1413 This function parses set batch scan command in below format:
1414 WLS_BATCHING_SET <space> followed by below arguements
1415 "SCANFREQ=XX" : Optional defaults to 30 sec
1416 "MSCAN=XX" : Required number of scans to attempt to batch
1417 "BESTN=XX" : Best Network (RSSI) defaults to 16
1418 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
1419 A. implies only 5 GHz , B. implies only 2.4GHz
1420 "RTT=X" : optional defaults to 0
1421 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
1422 error
1423
1424 For example input commands:
1425 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
1426 translated into set batch scan with following parameters:
1427 a) Frequence 60 seconds
1428 b) Batch 10 scans together
1429 c) Best RSSI to be 20
1430 d) 5GHz band only
1431 e) RTT is equal to 0
1432
1433 \param - pValue Pointer to input channel list
1434 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
1435
1436 \return - 0 for success non-zero for failure
1437
1438 --------------------------------------------------------------------------*/
1439static int
1440hdd_parse_set_batchscan_command
1441(
1442 tANI_U8 *pValue,
1443 tSirSetBatchScanReq *pHddSetBatchScanReq
1444)
1445{
1446 tANI_U8 *inPtr = pValue;
1447 tANI_U8 val = 0;
1448 tANI_U8 lastArg = 0;
Abhishek Singh00b71972016-01-07 10:51:04 +05301449 tANI_U32 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001450 tANI_U32 nMscan;
Abhishek Singh00b71972016-01-07 10:51:04 +05301451 tANI_U32 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
1452 tANI_U8 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1453 tANI_U32 nRtt = 0;
Rajeev Kumarc933d982013-11-18 20:04:20 -08001454 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +05301455
Rajeev79dbe4c2013-10-05 11:03:42 +05301456 /*go to space after WLS_BATCHING_SET command*/
1457 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1458 /*no argument after the command*/
1459 if (NULL == inPtr)
1460 {
1461 return -EINVAL;
1462 }
1463
1464 /*no space after the command*/
1465 else if (SPACE_ASCII_VALUE != *inPtr)
1466 {
1467 return -EINVAL;
1468 }
1469
1470 /*removing empty spaces*/
1471 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
1472
1473 /*no argument followed by spaces*/
1474 if ('\0' == *inPtr)
1475 {
1476 return -EINVAL;
1477 }
1478
1479 /*check and parse SCANFREQ*/
1480 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
1481 {
1482 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001483 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001484
Rajeev Kumarc933d982013-11-18 20:04:20 -08001485 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001486 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001487 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001488 }
1489
Rajeev79dbe4c2013-10-05 11:03:42 +05301490 if ( (NULL == inPtr) || (TRUE == lastArg))
1491 {
1492 return -EINVAL;
1493 }
1494 }
1495
1496 /*check and parse MSCAN*/
1497 if ((strncmp(inPtr, "MSCAN", 5) == 0))
1498 {
1499 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001500 &nMscan, &lastArg);
1501
1502 if (0 == nMscan)
1503 {
1504 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1505 "invalid MSCAN=%d", nMscan);
1506 return -EINVAL;
1507 }
1508
Rajeev79dbe4c2013-10-05 11:03:42 +05301509 if (TRUE == lastArg)
1510 {
1511 goto done;
1512 }
1513 else if (NULL == inPtr)
1514 {
1515 return -EINVAL;
1516 }
1517 }
1518 else
1519 {
1520 return -EINVAL;
1521 }
1522
1523 /*check and parse BESTN*/
1524 if ((strncmp(inPtr, "BESTN", 5) == 0))
1525 {
1526 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001527 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001528
Rajeev Kumarc933d982013-11-18 20:04:20 -08001529 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001530 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001531 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001532 }
1533
Rajeev79dbe4c2013-10-05 11:03:42 +05301534 if (TRUE == lastArg)
1535 {
1536 goto done;
1537 }
1538 else if (NULL == inPtr)
1539 {
1540 return -EINVAL;
1541 }
1542 }
1543
1544 /*check and parse CHANNEL*/
1545 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
1546 {
1547 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -08001548
Rajeev79dbe4c2013-10-05 11:03:42 +05301549 if (('A' == val) || ('a' == val))
1550 {
c_hpothuebf89732014-02-25 13:00:24 +05301551 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301552 }
1553 else if (('B' == val) || ('b' == val))
1554 {
c_hpothuebf89732014-02-25 13:00:24 +05301555 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301556 }
1557 else
1558 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001559 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1560 }
1561
1562 if (TRUE == lastArg)
1563 {
1564 goto done;
1565 }
1566 else if (NULL == inPtr)
1567 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301568 return -EINVAL;
1569 }
1570 }
1571
1572 /*check and parse RTT*/
1573 if ((strncmp(inPtr, "RTT", 3) == 0))
1574 {
1575 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001576 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +05301577 if (TRUE == lastArg)
1578 {
1579 goto done;
1580 }
1581 if (NULL == inPtr)
1582 {
1583 return -EINVAL;
1584 }
1585 }
1586
1587
1588done:
1589
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001590 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1591 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1592 pHddSetBatchScanReq->bestNetwork = nBestN;
1593 pHddSetBatchScanReq->rfBand = ucRfBand;
1594 pHddSetBatchScanReq->rtt = nRtt;
1595
Rajeev79dbe4c2013-10-05 11:03:42 +05301596 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1597 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1598 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1599 pHddSetBatchScanReq->scanFrequency,
1600 pHddSetBatchScanReq->numberOfScansToBatch,
1601 pHddSetBatchScanReq->bestNetwork,
1602 pHddSetBatchScanReq->rfBand,
1603 pHddSetBatchScanReq->rtt);
1604
1605 return 0;
1606}/*End of hdd_parse_set_batchscan_command*/
1607
1608/**---------------------------------------------------------------------------
1609
1610 \brief hdd_set_batch_scan_req_callback () - This function is called after
1611 receiving set batch scan response from FW and it saves set batch scan
1612 response data FW to HDD context and sets the completion event on
1613 which hdd_ioctl is waiting
1614
1615 \param - callbackContext Pointer to HDD adapter
1616 \param - pRsp Pointer to set batch scan response data received from FW
1617
1618 \return - nothing
1619
1620 --------------------------------------------------------------------------*/
1621static void hdd_set_batch_scan_req_callback
1622(
1623 void *callbackContext,
1624 tSirSetBatchScanRsp *pRsp
1625)
1626{
1627 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1628 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1629
1630 /*sanity check*/
1631 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1632 {
1633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1634 "%s: Invalid pAdapter magic", __func__);
1635 VOS_ASSERT(0);
1636 return;
1637 }
1638 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1639
1640 /*save set batch scan response*/
1641 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1642
1643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1644 "Received set batch scan rsp from FW with nScansToBatch=%d",
1645 pHddSetBatchScanRsp->nScansToBatch);
1646
1647 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1648 complete(&pAdapter->hdd_set_batch_scan_req_var);
1649
1650 return;
1651}/*End of hdd_set_batch_scan_req_callback*/
1652
1653
1654/**---------------------------------------------------------------------------
1655
1656 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1657 info in hdd batch scan response queue
1658
1659 \param - pAdapter Pointer to hdd adapter
1660 \param - pAPMetaInfo Pointer to access point meta info
1661 \param - scanId scan ID of batch scan response
1662 \param - isLastAp tells whether AP is last AP in batch scan response or not
1663
1664 \return - nothing
1665
1666 --------------------------------------------------------------------------*/
1667static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1668 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1669{
1670 tHddBatchScanRsp *pHead;
1671 tHddBatchScanRsp *pNode;
1672 tHddBatchScanRsp *pPrev;
1673 tHddBatchScanRsp *pTemp;
1674 tANI_U8 ssidLen;
1675
1676 /*head of hdd batch scan response queue*/
1677 pHead = pAdapter->pBatchScanRsp;
1678
1679 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1680 if (NULL == pNode)
1681 {
1682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1683 "%s: Could not allocate memory", __func__);
1684 VOS_ASSERT(0);
1685 return;
1686 }
1687
1688 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1689 sizeof(pNode->ApInfo.bssid));
1690 ssidLen = strlen(pApMetaInfo->ssid);
1691 if (SIR_MAX_SSID_SIZE < ssidLen)
1692 {
1693 /*invalid scan result*/
1694 vos_mem_free(pNode);
1695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1696 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1697 return;
1698 }
1699 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1700 /*null terminate ssid*/
1701 pNode->ApInfo.ssid[ssidLen] = '\0';
1702 pNode->ApInfo.ch = pApMetaInfo->ch;
1703 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1704 pNode->ApInfo.age = pApMetaInfo->timestamp;
1705 pNode->ApInfo.batchId = scanId;
1706 pNode->ApInfo.isLastAp = isLastAp;
1707
1708 pNode->pNext = NULL;
1709 if (NULL == pHead)
1710 {
1711 pAdapter->pBatchScanRsp = pNode;
1712 }
1713 else
1714 {
1715 pTemp = pHead;
1716 while (NULL != pTemp)
1717 {
1718 pPrev = pTemp;
1719 pTemp = pTemp->pNext;
1720 }
1721 pPrev->pNext = pNode;
1722 }
1723
1724 return;
1725}/*End of hdd_populate_batch_scan_rsp_queue*/
1726
1727/**---------------------------------------------------------------------------
1728
1729 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1730 receiving batch scan response indication from FW. It saves get batch scan
1731 response data in HDD batch scan response queue. This callback sets the
1732 completion event on which hdd_ioctl is waiting only after getting complete
1733 batch scan response data from FW
1734
1735 \param - callbackContext Pointer to HDD adapter
1736 \param - pRsp Pointer to get batch scan response data received from FW
1737
1738 \return - nothing
1739
1740 --------------------------------------------------------------------------*/
1741static void hdd_batch_scan_result_ind_callback
1742(
1743 void *callbackContext,
1744 void *pRsp
1745)
1746{
1747 v_BOOL_t isLastAp;
1748 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001749 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301750 tANI_U32 numberScanList;
1751 tANI_U32 nextScanListOffset;
1752 tANI_U32 nextApMetaInfoOffset;
1753 hdd_adapter_t* pAdapter;
1754 tpSirBatchScanList pScanList;
1755 tpSirBatchScanNetworkInfo pApMetaInfo;
1756 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1757 tSirSetBatchScanReq *pReq;
1758
1759 pAdapter = (hdd_adapter_t *)callbackContext;
1760 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001761 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301762 {
1763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1764 "%s: Invalid pAdapter magic", __func__);
1765 VOS_ASSERT(0);
1766 return;
1767 }
1768
1769 /*initialize locals*/
1770 pReq = &pAdapter->hddSetBatchScanReq;
1771 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1772 isLastAp = FALSE;
1773 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001774 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301775 numberScanList = 0;
1776 nextScanListOffset = 0;
1777 nextApMetaInfoOffset = 0;
1778 pScanList = NULL;
1779 pApMetaInfo = NULL;
1780
1781 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1782 {
1783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001784 "%s: pBatchScanRsp is %pK pReq %pK", __func__, pBatchScanRsp, pReq);
Rajeev79dbe4c2013-10-05 11:03:42 +05301785 isLastAp = TRUE;
1786 goto done;
1787 }
1788
1789 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1791 "Batch scan rsp: numberScalList %d", numberScanList);
1792
1793 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1794 {
1795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1796 "%s: numberScanList %d", __func__, numberScanList);
1797 isLastAp = TRUE;
1798 goto done;
1799 }
1800
1801 while (numberScanList)
1802 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001803 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301804 nextScanListOffset);
1805 if (NULL == pScanList)
1806 {
1807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001808 "%s: pScanList is %pK", __func__, pScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301809 isLastAp = TRUE;
1810 goto done;
1811 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001812 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001814 "Batch scan rsp: numApMetaInfo %d scanId %d",
1815 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301816
1817 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1818 {
1819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1820 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1821 isLastAp = TRUE;
1822 goto done;
1823 }
1824
Rajeev Kumarce651e42013-10-21 18:57:15 -07001825 /*Initialize next AP meta info offset for next scan list*/
1826 nextApMetaInfoOffset = 0;
1827
Rajeev79dbe4c2013-10-05 11:03:42 +05301828 while (numApMetaInfo)
1829 {
1830 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1831 nextApMetaInfoOffset);
1832 if (NULL == pApMetaInfo)
1833 {
1834 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001835 "%s: pApMetaInfo is %pK", __func__, pApMetaInfo);
Rajeev79dbe4c2013-10-05 11:03:42 +05301836 isLastAp = TRUE;
1837 goto done;
1838 }
1839 /*calculate AP age*/
1840 pApMetaInfo->timestamp =
1841 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1842
1843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001844 "%s: bssId "MAC_ADDRESS_STR
1845 " ch %d rssi %d timestamp %d", __func__,
1846 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1847 pApMetaInfo->ch, pApMetaInfo->rssi,
1848 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301849
1850 /*mark last AP in batch scan response*/
1851 if ((TRUE == pBatchScanRsp->isLastResult) &&
1852 (1 == numberScanList) && (1 == numApMetaInfo))
1853 {
1854 isLastAp = TRUE;
1855 }
1856
1857 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1858 /*store batch scan repsonse in hdd queue*/
1859 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1860 pScanList->scanId, isLastAp);
1861 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1862
1863 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1864 numApMetaInfo--;
1865 }
1866
Rajeev Kumarce651e42013-10-21 18:57:15 -07001867 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1868 + (sizeof(tSirBatchScanNetworkInfo)
1869 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301870 numberScanList--;
1871 }
1872
1873done:
1874
1875 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1876 requested from hdd_ioctl*/
1877 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1878 (TRUE == isLastAp))
1879 {
1880 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1881 complete(&pAdapter->hdd_get_batch_scan_req_var);
1882 }
1883
1884 return;
1885}/*End of hdd_batch_scan_result_ind_callback*/
1886
1887/**---------------------------------------------------------------------------
1888
1889 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1890 response as per batch scan FR request format by putting proper markers
1891
1892 \param - pDest pointer to destination buffer
1893 \param - cur_len current length
1894 \param - tot_len total remaining size which can be written to user space
1895 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1896 \param - pAdapter Pointer to HDD adapter
1897
1898 \return - ret no of characters written
1899
1900 --------------------------------------------------------------------------*/
1901static tANI_U32
1902hdd_format_batch_scan_rsp
1903(
1904 tANI_U8 *pDest,
1905 tANI_U32 cur_len,
1906 tANI_U32 tot_len,
1907 tHddBatchScanRsp *pApMetaInfo,
1908 hdd_adapter_t* pAdapter
1909)
1910{
1911 tANI_U32 ret = 0;
1912 tANI_U32 rem_len = 0;
1913 tANI_U8 temp_len = 0;
1914 tANI_U8 temp_total_len = 0;
1915 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1916 tANI_U8 *pTemp = temp;
1917
1918 /*Batch scan reponse needs to be returned to user space in
1919 following format:
1920 "scancount=X\n" where X is the number of scans in current batch
1921 batch
1922 "trunc\n" optional present if current scan truncated
1923 "bssid=XX:XX:XX:XX:XX:XX\n"
1924 "ssid=XXXX\n"
1925 "freq=X\n" frequency in Mhz
1926 "level=XX\n"
1927 "age=X\n" ms
1928 "dist=X\n" cm (-1 if not available)
1929 "errror=X\n" (-1if not available)
1930 "====\n" (end of ap marker)
1931 "####\n" (end of scan marker)
1932 "----\n" (end of results)*/
1933 /*send scan result in above format to user space based on
1934 available length*/
1935 /*The GET response may have more data than the driver can return in its
1936 buffer. In that case the buffer should be filled to the nearest complete
1937 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1938 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1939 The final buffer should end with "----\n"*/
1940
1941 /*sanity*/
1942 if (cur_len > tot_len)
1943 {
1944 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1945 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1946 return 0;
1947 }
1948 else
1949 {
1950 rem_len = (tot_len - cur_len);
1951 }
1952
1953 /*end scan marker*/
1954 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1955 {
1956 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1957 pTemp += temp_len;
1958 temp_total_len += temp_len;
1959 }
1960
1961 /*bssid*/
1962 temp_len = snprintf(pTemp, sizeof(temp),
1963 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1964 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1965 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1966 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1967 pTemp += temp_len;
1968 temp_total_len += temp_len;
1969
1970 /*ssid*/
1971 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1972 pApMetaInfo->ApInfo.ssid);
1973 pTemp += temp_len;
1974 temp_total_len += temp_len;
1975
1976 /*freq*/
1977 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001978 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301979 pTemp += temp_len;
1980 temp_total_len += temp_len;
1981
1982 /*level*/
1983 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1984 pApMetaInfo->ApInfo.rssi);
1985 pTemp += temp_len;
1986 temp_total_len += temp_len;
1987
1988 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001989 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301990 pApMetaInfo->ApInfo.age);
1991 pTemp += temp_len;
1992 temp_total_len += temp_len;
1993
1994 /*dist*/
1995 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1996 pTemp += temp_len;
1997 temp_total_len += temp_len;
1998
1999 /*error*/
2000 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
2001 pTemp += temp_len;
2002 temp_total_len += temp_len;
2003
2004 /*end AP marker*/
2005 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
2006 pTemp += temp_len;
2007 temp_total_len += temp_len;
2008
2009 /*last AP in batch scan response*/
2010 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
2011 {
2012 /*end scan marker*/
2013 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
2014 pTemp += temp_len;
2015 temp_total_len += temp_len;
2016
2017 /*end batch scan result marker*/
2018 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
2019 pTemp += temp_len;
2020 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002021
Rajeev79dbe4c2013-10-05 11:03:42 +05302022 }
2023
2024 if (temp_total_len < rem_len)
2025 {
2026 ret = temp_total_len + 1;
2027 strlcpy(pDest, temp, ret);
2028 pAdapter->isTruncated = FALSE;
2029 }
2030 else
2031 {
2032 pAdapter->isTruncated = TRUE;
2033 if (rem_len >= strlen("%%%%"))
2034 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08002035 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05302036 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08002037 else
Rajeev79dbe4c2013-10-05 11:03:42 +05302038 {
2039 ret = 0;
2040 }
2041 }
2042
2043 return ret;
2044
2045}/*End of hdd_format_batch_scan_rsp*/
2046
2047/**---------------------------------------------------------------------------
2048
2049 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
2050 buffer starting with head of hdd batch scan response queue
2051
2052 \param - pAdapter Pointer to HDD adapter
2053 \param - pDest Pointer to user data buffer
2054 \param - cur_len current offset in user buffer
2055 \param - rem_len remaining no of bytes in user buffer
2056
2057 \return - number of bytes written in user buffer
2058
2059 --------------------------------------------------------------------------*/
2060
2061tANI_U32 hdd_populate_user_batch_scan_rsp
2062(
2063 hdd_adapter_t* pAdapter,
2064 tANI_U8 *pDest,
2065 tANI_U32 cur_len,
2066 tANI_U32 rem_len
2067)
2068{
2069 tHddBatchScanRsp *pHead;
2070 tHddBatchScanRsp *pPrev;
2071 tANI_U32 len;
2072
Rajeev79dbe4c2013-10-05 11:03:42 +05302073 pAdapter->isTruncated = FALSE;
2074
2075 /*head of hdd batch scan response queue*/
2076 pHead = pAdapter->pBatchScanRsp;
2077 while (pHead)
2078 {
2079 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
2080 pAdapter);
2081 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07002082 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05302083 cur_len += len;
2084 if(TRUE == pAdapter->isTruncated)
2085 {
2086 /*result is truncated return rest of scan rsp in next req*/
2087 cur_len = rem_len;
2088 break;
2089 }
2090 pPrev = pHead;
2091 pHead = pHead->pNext;
2092 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08002093 if (TRUE == pPrev->ApInfo.isLastAp)
2094 {
2095 pAdapter->prev_batch_id = 0;
2096 }
2097 else
2098 {
2099 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
2100 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302101 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002102 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05302103 }
2104
2105 return cur_len;
2106}/*End of hdd_populate_user_batch_scan_rsp*/
2107
2108/**---------------------------------------------------------------------------
2109
2110 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
2111 scan response data from HDD queue to user space
2112 It does following in detail:
2113 a) if HDD has enough data in its queue then it 1st copies data to user
2114 space and then send get batch scan indication message to FW. In this
2115 case it does not wait on any event and batch scan response data will
2116 be populated in HDD response queue in MC thread context after receiving
2117 indication from FW
2118 b) else send get batch scan indication message to FW and wait on an event
2119 which will be set once HDD receives complete batch scan response from
2120 FW and then this function returns batch scan response to user space
2121
2122 \param - pAdapter Pointer to HDD adapter
2123 \param - pPrivData Pointer to priv_data
2124
2125 \return - 0 for success -EFAULT for failure
2126
2127 --------------------------------------------------------------------------*/
2128
2129int hdd_return_batch_scan_rsp_to_user
2130(
2131 hdd_adapter_t* pAdapter,
2132 hdd_priv_data_t *pPrivData,
2133 tANI_U8 *command
2134)
2135{
2136 tANI_U8 *pDest;
2137 tANI_U32 count = 0;
2138 tANI_U32 len = 0;
2139 tANI_U32 cur_len = 0;
2140 tANI_U32 rem_len = 0;
2141 eHalStatus halStatus;
2142 unsigned long rc;
2143 tSirTriggerBatchScanResultInd *pReq;
2144
2145 pReq = &pAdapter->hddTriggerBatchScanResultInd;
2146 pReq->param = 0;/*batch scan client*/
2147 pDest = (tANI_U8 *)(command + pPrivData->used_len);
2148 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
2149
2150 cur_len = pPrivData->used_len;
2151 if (pPrivData->total_len > pPrivData->used_len)
2152 {
2153 rem_len = pPrivData->total_len - pPrivData->used_len;
2154 }
2155 else
2156 {
2157 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2158 "%s: Invalid user data buffer total_len %d used_len %d",
2159 __func__, pPrivData->total_len, pPrivData->used_len);
2160 return -EFAULT;
2161 }
2162
2163 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2164 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2165 cur_len, rem_len);
2166 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2167
2168 /*enough scan result available in cache to return to user space or
2169 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08002170 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05302171 {
2172 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
2173 halStatus = sme_TriggerBatchScanResultInd(
2174 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2175 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
2176 pAdapter);
2177 if ( eHAL_STATUS_SUCCESS == halStatus )
2178 {
2179 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
2180 {
2181 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
2182 rc = wait_for_completion_timeout(
2183 &pAdapter->hdd_get_batch_scan_req_var,
2184 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
Abhishek Singh00b71972016-01-07 10:51:04 +05302185 if (0 >= rc)
Rajeev79dbe4c2013-10-05 11:03:42 +05302186 {
2187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Abhishek Singh00b71972016-01-07 10:51:04 +05302188 "%s: wait on hdd_get_batch_scan_req_var failed %ld",
2189 __func__, rc);
Rajeev79dbe4c2013-10-05 11:03:42 +05302190 return -EFAULT;
2191 }
2192 }
2193
2194 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07002195 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05302196 pDest += len;
2197 cur_len += len;
2198
2199 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2200 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2201 cur_len, rem_len);
2202 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2203
2204 count = 0;
2205 len = (len - pPrivData->used_len);
2206 pDest = (command + pPrivData->used_len);
2207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002208 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302209 while(count < len)
2210 {
2211 printk("%c", *(pDest + count));
2212 count++;
2213 }
2214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2215 "%s: copy %d data to user buffer", __func__, len);
2216 if (copy_to_user(pPrivData->buf, pDest, len))
2217 {
2218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2219 "%s: failed to copy data to user buffer", __func__);
2220 return -EFAULT;
2221 }
2222 }
2223 else
2224 {
2225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2226 "sme_GetBatchScanScan returned failure halStatus %d",
2227 halStatus);
2228 return -EINVAL;
2229 }
2230 }
2231 else
2232 {
Rajeev79dbe4c2013-10-05 11:03:42 +05302233 count = 0;
2234 len = (len - pPrivData->used_len);
2235 pDest = (command + pPrivData->used_len);
2236 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002237 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302238 while(count < len)
2239 {
2240 printk("%c", *(pDest + count));
2241 count++;
2242 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08002243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2244 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05302245 if (copy_to_user(pPrivData->buf, pDest, len))
2246 {
2247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2248 "%s: failed to copy data to user buffer", __func__);
2249 return -EFAULT;
2250 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302251 }
2252
2253 return 0;
2254} /*End of hdd_return_batch_scan_rsp_to_user*/
2255
Rajeev Kumar8b373292014-01-08 20:36:55 -08002256/**---------------------------------------------------------------------------
2257
2258 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
2259 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
2260 WLS_BATCHING VERSION
2261 WLS_BATCHING SET
2262 WLS_BATCHING GET
2263 WLS_BATCHING STOP
2264
2265 \param - pAdapter Pointer to HDD adapter
2266 \param - pPrivdata Pointer to priv_data
2267 \param - command Pointer to command
2268
2269 \return - 0 for success -EFAULT for failure
2270
2271 --------------------------------------------------------------------------*/
2272
2273int hdd_handle_batch_scan_ioctl
2274(
2275 hdd_adapter_t *pAdapter,
2276 hdd_priv_data_t *pPrivdata,
2277 tANI_U8 *command
2278)
2279{
2280 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08002281 hdd_context_t *pHddCtx;
2282
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302283 ENTER();
2284
Yue Mae36e3552014-03-05 17:06:20 -08002285 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2286 ret = wlan_hdd_validate_context(pHddCtx);
2287 if (ret)
2288 {
Yue Mae36e3552014-03-05 17:06:20 -08002289 goto exit;
2290 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002291
2292 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
2293 {
2294 char extra[32];
2295 tANI_U8 len = 0;
2296 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
2297
2298 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2299 {
2300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2301 "%s: Batch scan feature is not supported by FW", __func__);
2302 ret = -EINVAL;
2303 goto exit;
2304 }
2305
2306 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
2307 version);
2308 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2309 {
2310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2311 "%s: failed to copy data to user buffer", __func__);
2312 ret = -EFAULT;
2313 goto exit;
2314 }
2315 ret = HDD_BATCH_SCAN_VERSION;
2316 }
2317 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
2318 {
2319 int status;
2320 tANI_U8 *value = (command + 16);
2321 eHalStatus halStatus;
2322 unsigned long rc;
2323 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
2324 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
2325
2326 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2327 {
2328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2329 "%s: Batch scan feature is not supported by FW", __func__);
2330 ret = -EINVAL;
2331 goto exit;
2332 }
2333
2334 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
2335 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
2336 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
2337 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
2338 {
2339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302340 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08002341 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302342 hdd_device_modetoString(pAdapter->device_mode),
2343 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002344 ret = -EINVAL;
2345 goto exit;
2346 }
2347
2348 status = hdd_parse_set_batchscan_command(value, pReq);
2349 if (status)
2350 {
2351 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2352 "Invalid WLS_BATCHING SET command");
2353 ret = -EINVAL;
2354 goto exit;
2355 }
2356
2357
2358 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
2359 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2360 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
2361 pAdapter);
2362
2363 if ( eHAL_STATUS_SUCCESS == halStatus )
2364 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302365 char extra[32];
2366 tANI_U8 len = 0;
2367 tANI_U8 mScan = 0;
2368
Rajeev Kumar8b373292014-01-08 20:36:55 -08002369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2370 "sme_SetBatchScanReq returned success halStatus %d",
2371 halStatus);
2372 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
2373 {
2374 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
2375 rc = wait_for_completion_timeout(
2376 &pAdapter->hdd_set_batch_scan_req_var,
2377 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
2378 if (0 == rc)
2379 {
2380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2381 "%s: Timeout waiting for set batch scan to complete",
2382 __func__);
2383 ret = -EINVAL;
2384 goto exit;
2385 }
2386 }
2387 if ( !pRsp->nScansToBatch )
2388 {
2389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2390 "%s: Received set batch scan failure response from FW",
2391 __func__);
2392 ret = -EINVAL;
2393 goto exit;
2394 }
2395 /*As per the Batch Scan Framework API we should return the MIN of
2396 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302397 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002398
2399 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
2400
2401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2402 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302403 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
2404 len = scnprintf(extra, sizeof(extra), "%d", mScan);
2405 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2406 {
2407 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2408 "%s: failed to copy MSCAN value to user buffer", __func__);
2409 ret = -EFAULT;
2410 goto exit;
2411 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002412 }
2413 else
2414 {
2415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2416 "sme_SetBatchScanReq returned failure halStatus %d",
2417 halStatus);
2418 ret = -EINVAL;
2419 goto exit;
2420 }
2421 }
2422 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
2423 {
2424 eHalStatus halStatus;
2425 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
2426 pInd->param = 0;
2427
2428 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2429 {
2430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2431 "%s: Batch scan feature is not supported by FW", __func__);
2432 ret = -EINVAL;
2433 goto exit;
2434 }
2435
2436 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2437 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002439 "Batch scan is not yet enabled batch scan state %d",
2440 pAdapter->batchScanState);
2441 ret = -EINVAL;
2442 goto exit;
2443 }
2444
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002445 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2446 hdd_deinit_batch_scan(pAdapter);
2447 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2448
Rajeev Kumar8b373292014-01-08 20:36:55 -08002449 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
2450
2451 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
2452 pAdapter->sessionId);
2453 if ( eHAL_STATUS_SUCCESS == halStatus )
2454 {
2455 ret = 0;
2456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2457 "sme_StopBatchScanInd returned success halStatus %d",
2458 halStatus);
2459 }
2460 else
2461 {
2462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2463 "sme_StopBatchScanInd returned failure halStatus %d",
2464 halStatus);
2465 ret = -EINVAL;
2466 goto exit;
2467 }
2468 }
2469 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
2470 {
2471 tANI_U32 remain_len;
2472
2473 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2474 {
2475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2476 "%s: Batch scan feature is not supported by FW", __func__);
2477 ret = -EINVAL;
2478 goto exit;
2479 }
2480
2481 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2482 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002484 "Batch scan is not yet enabled could not return results"
2485 "Batch Scan state %d",
2486 pAdapter->batchScanState);
2487 ret = -EINVAL;
2488 goto exit;
2489 }
2490
2491 pPrivdata->used_len = 16;
2492 remain_len = pPrivdata->total_len - pPrivdata->used_len;
2493 if (remain_len < pPrivdata->total_len)
2494 {
2495 /*Clear previous batch scan response data if any*/
2496 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
2497 }
2498 else
2499 {
2500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2501 "Invalid total length from user space can't fetch batch"
2502 " scan response total_len %d used_len %d remain len %d",
2503 pPrivdata->total_len, pPrivdata->used_len, remain_len);
2504 ret = -EINVAL;
2505 goto exit;
2506 }
2507 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
2508 }
2509
2510exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302511 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08002512 return ret;
2513}
2514
2515
Rajeev79dbe4c2013-10-05 11:03:42 +05302516#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
2517
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302518#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
2519/**
2520 * hdd_assign_handoff_src_reassoc - Set handoff source as REASSOC
2521 * to Handoff request
2522 * @handoffInfo: Pointer to Handoff request
2523 * @src: enum of handoff_src
2524 * Return: None
2525 */
2526#ifndef QCA_WIFI_ISOC
2527static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2528 *handoffInfo, handoff_src src)
2529{
2530 handoffInfo->src = src;
2531}
2532#else
2533static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2534 *handoffInfo, handoff_src src)
2535{
2536}
2537#endif
2538
2539/**
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302540 * hdd_reassoc() - perform a user space-directed reassoc
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302541 *
2542 * @pAdapter: Adapter upon which the command was received
2543 * @bssid: BSSID with which to reassociate
2544 * @channel: channel upon which to reassociate
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302545 * @src: The source for the trigger of this action
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302546 *
2547 * Return: 0 for success non-zero for failure
2548 */
2549#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302550int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302551 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302552{
2553 hdd_station_ctx_t *pHddStaCtx;
2554 tCsrHandoffRequest handoffInfo;
2555 hdd_context_t *pHddCtx = NULL;
2556 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2557
2558 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2559
2560 /* if not associated, no need to proceed with reassoc */
2561 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2562 hddLog(LOG1, FL("Not associated"));
2563 return -EINVAL;
2564 }
2565
2566 /* if the target bssid is same as currently associated AP,
2567 then no need to proceed with reassoc */
2568 if (!memcmp(bssid, pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr))) {
2569 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
2570 return -EINVAL;
2571 }
2572
2573 /* Check channel number is a valid channel number */
2574 if (VOS_STATUS_SUCCESS !=
2575 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
2576 hddLog(LOGE, FL("Invalid Channel %d"), channel);
2577 return -EINVAL;
2578 }
2579
2580 /* Proceed with reassoc */
2581 handoffInfo.channel = channel;
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302582 hdd_assign_handoff_src_reassoc(&handoffInfo, src);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302583 memcpy(handoffInfo.bssid, bssid, sizeof(tSirMacAddr));
2584 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
2585 return 0;
2586}
2587#else
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302588int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302589 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302590{
2591 return -EPERM;
2592}
2593#endif
2594
2595/**
2596 * hdd_parse_reassoc_v1() - parse version 1 of the REASSOC command
2597 * This function parses the v1 REASSOC command with the format
2598 * REASSOC xx:xx:xx:xx:xx:xx CH where "xx:xx:xx:xx:xx:xx" is the
2599 * Hex-ASCII representation of the BSSID and CH is the ASCII
2600 * representation of the channel. For example
2601 * REASSOC 00:0a:0b:11:22:33 48
2602 *
2603 * @pAdapter: Adapter upon which the command was received
2604 * @command: ASCII text command that was received
2605 *
2606 * Return: 0 for success non-zero for failure
2607 */
2608static int
2609hdd_parse_reassoc_v1(hdd_adapter_t *pAdapter, const char *command)
2610{
2611 tANI_U8 channel = 0;
2612 tSirMacAddr bssid;
2613 int ret;
2614
2615 ret = hdd_parse_reassoc_command_v1_data(command, bssid, &channel);
2616 if (ret)
2617 hddLog(LOGE, FL("Failed to parse reassoc command data"));
2618 else
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302619 ret = hdd_reassoc(pAdapter, bssid, channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302620
2621 return ret;
2622}
2623
2624/**
2625 * hdd_parse_reassoc_v2() - parse version 2 of the REASSOC command
2626 * This function parses the v2 REASSOC command with the format
2627 * REASSOC <android_wifi_reassoc_params>
2628 *
2629 * @pAdapter: Adapter upon which the command was received
2630 * @command: command that was received, ASCII command followed
2631 * by binary data
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302632 * @total_len: Total length of the command received
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302633 *
2634 * Return: 0 for success non-zero for failure
2635 */
2636static int
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302637hdd_parse_reassoc_v2(hdd_adapter_t *pAdapter, const char *command,
2638 int total_len)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302639{
2640 struct android_wifi_reassoc_params params;
2641 tSirMacAddr bssid;
2642 int ret;
2643
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302644 if (total_len < sizeof(params) + 8) {
2645 hddLog(LOGE, FL("Invalid command length"));
2646 return -EINVAL;
2647 }
2648
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302649 /* The params are located after "REASSOC " */
2650 memcpy(&params, command + 8, sizeof(params));
2651
2652 if (!mac_pton(params.bssid, (u8 *)&bssid)) {
2653 hddLog(LOGE, FL("MAC address parsing failed"));
2654 ret = -EINVAL;
2655 } else {
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302656 ret = hdd_reassoc(pAdapter, bssid, params.channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302657 }
2658 return ret;
2659}
2660
2661/**
2662 * hdd_parse_reassoc() - parse the REASSOC command
2663 * There are two different versions of the REASSOC command.Version 1
2664 * of the command contains a parameter list that is ASCII characters
2665 * whereas version 2 contains a combination of ASCII and binary
2666 * payload. Determine if a version 1 or a version 2 command is being
2667 * parsed by examining the parameters, and then dispatch the parser
2668 * that is appropriate for the command.
2669 *
2670 * @pAdapter: Adapter upon which the command was received
2671 * @command: command that was received
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302672 * @total_len: Total length of the command received
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302673 *
2674 * Return: 0 for success non-zero for failure
2675 */
2676static int
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302677hdd_parse_reassoc(hdd_adapter_t *pAdapter, const char *command, int total_len)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302678{
2679 int ret;
2680
2681 /*
2682 * both versions start with "REASSOC"
2683 * v1 has a bssid and channel # as an ASCII string
2684 * REASSOC xx:xx:xx:xx:xx:xx CH
2685 * v2 has a C struct
2686 * REASSOC <binary c struct>
2687 *
2688 * The first field in the v2 struct is also the bssid in ASCII.
2689 * But in the case of a v2 message the BSSID is NUL-terminated.
2690 * Hence we can peek at that offset to see if this is V1 or V2
2691 * REASSOC xx:xx:xx:xx:xx:xx*
2692 * 1111111111222222
2693 * 01234567890123456789012345
2694 */
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302695
2696 if (total_len < 26) {
2697 hddLog(LOGE, FL("Invalid command (total_len=%d)"), total_len);
2698 return -EINVAL;
2699 }
2700
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302701 if (command[25])
2702 ret = hdd_parse_reassoc_v1(pAdapter, command);
2703 else
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302704 ret = hdd_parse_reassoc_v2(pAdapter, command, total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302705
2706 return ret;
2707}
2708#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE FEATURE_WLAN_LFR */
2709
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05302710static void get_bcn_miss_rate_cb(VOS_STATUS status, int bcnMissRate, void *data)
c_hpothu92367912014-05-01 15:18:17 +05302711{
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05302712 struct hdd_request *request;
c_hpothu39eb1e32014-06-26 16:31:50 +05302713
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05302714 request = hdd_request_get(data);
2715 if (!request) {
2716 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
2717 return;
2718 }
c_hpothu92367912014-05-01 15:18:17 +05302719
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05302720 if (VOS_STATUS_SUCCESS == status)
2721 gbcnMissRate = bcnMissRate;
2722 else
2723 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
c_hpothu92367912014-05-01 15:18:17 +05302724
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05302725 hdd_request_complete(request);
2726 hdd_request_put(request);
c_hpothu92367912014-05-01 15:18:17 +05302727
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05302728 return;
c_hpothu92367912014-05-01 15:18:17 +05302729}
2730
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05302731struct fw_stats_priv {
2732 tSirFwStatsResult *fw_stats;
2733};
2734
2735void hdd_fw_statis_cb(VOS_STATUS status,
2736 tSirFwStatsResult *fwStatsResult, void *context)
Satyanarayana Dash72806012014-12-02 14:30:08 +05302737{
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05302738 struct hdd_request *request;
2739 struct fw_stats_priv *priv;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302740
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05302741 hddLog(VOS_TRACE_LEVEL_INFO, FL("with status = %d"),status);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302742
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05302743 request = hdd_request_get(context);
2744 if (!request) {
2745 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
2746 return;
2747 }
2748 priv = hdd_request_priv(request);
2749
2750 if (VOS_STATUS_SUCCESS != status)
2751 *priv->fw_stats = *fwStatsResult;
2752 else
2753 priv->fw_stats = NULL;
2754
2755 hdd_request_complete(request);
2756 hdd_request_put(request);
2757 return;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302758}
2759
jge35567202017-06-21 16:39:38 +08002760/*
2761 *hdd_parse_setmaxtxpower_command() - HDD Parse MAXTXPOWER command
2762 *@pValue Pointer to MAXTXPOWER command
2763 *@pTxPower Pointer to tx power
2764 *
2765 *This function parses the MAXTXPOWER command passed in the format
2766 * MAXTXPOWER<space>X(Tx power in dbm)
2767 * For example input commands:
2768 * 1) MAXTXPOWER -8 -> This is translated into set max TX power to -8 dbm
2769 * 2) MAXTXPOWER -23 -> This is translated into set max TX power to -23 dbm
2770 *
2771 *return - 0 for success non-zero for failure
2772 */
2773static int hdd_parse_setmaxtxpower_command(unsigned char *pValue, int *pTxPower)
2774{
2775 unsigned char *inPtr = pValue;
2776 int tempInt;
2777 int v = 0;
2778 *pTxPower = 0;
2779
2780 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
2781 /* no argument after the command */
2782 if (NULL == inPtr)
2783 return -EINVAL;
2784 /* no space after the command */
2785 else if (SPACE_ASCII_VALUE != *inPtr)
2786 return -EINVAL;
2787
2788 /* removing empty spaces */
2789 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
2790
2791 /* no argument followed by spaces */
2792 if ('\0' == *inPtr)
2793 return 0;
2794
2795 v = kstrtos32(inPtr, 10, &tempInt);
2796
2797 /* Range checking for passed parameter */
2798 if ((tempInt < HDD_MIN_TX_POWER) || (tempInt > HDD_MAX_TX_POWER))
2799 return -EINVAL;
2800
2801 *pTxPower = tempInt;
2802
2803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2804 "SETMAXTXPOWER: %d", *pTxPower);
2805
2806 return 0;
2807}
2808
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302809static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2810{
2811 int ret = 0;
2812
2813 if (!pCfg || !command || !extra || !len)
2814 {
2815 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2816 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2817 ret = -EINVAL;
2818 return ret;
2819 }
2820
2821 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2822 {
2823 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2824 (int)pCfg->nActiveMaxChnTime);
2825 return ret;
2826 }
2827 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2828 {
2829 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2830 (int)pCfg->nActiveMinChnTime);
2831 return ret;
2832 }
2833 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2834 {
2835 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2836 (int)pCfg->nPassiveMaxChnTime);
2837 return ret;
2838 }
2839 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2840 {
2841 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2842 (int)pCfg->nPassiveMinChnTime);
2843 return ret;
2844 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302845 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2846 {
2847 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2848 (int)pCfg->nActiveMaxChnTime);
2849 return ret;
2850 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302851 else
2852 {
2853 ret = -EINVAL;
2854 }
2855
2856 return ret;
2857}
2858
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05302859/**
2860 * hdd_btc_get_dwell_time() - Get BTC dwell time parameters
2861 * @pCfg: Pointer to HDD context
2862 * @command: ASCII text command that is received
2863 * @extra: Pointer to copy data sent to user
2864 * @n: size of 'extra' buffer
2865 * @len: length copied to 'extra' buffer
2866 *
2867 * Driver commands:
2868 * wpa_cli DRIVER BTCGETDWELLTIME ESCO MAX
2869 * wpa_cli DRIVER BTCGETDWELLTIME ESCO MIN
2870 * wpa_cli DRIVER BTCGETDWELLTIME SCO MAX
2871 * wpa_cli DRIVER BTCGETDWELLTIME SCO MIN
2872 *
2873 * Return: 0 for success non-zero for failure
2874 */
2875
2876static int hdd_btc_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command,
2877 char *extra, tANI_U8 n, tANI_U8 *len)
2878{
2879 int ret = 0;
2880
2881 if (!pCfg || !command || !extra || !len)
2882 {
2883 hddLog(LOGE, FL("Argument passsed for BTCGETDWELLTIME is incorrect"));
2884 ret = -EINVAL;
2885 return ret;
2886 }
2887
2888 if (strncmp(command, "BTCGETDWELLTIME ESCO MAX", 24) == 0)
2889 {
2890 *len = scnprintf(extra, n, "BTCGETDWELLTIME ESCO MAX %u\n",
2891 (int)pCfg->max_chntime_btc_esco);
2892 return ret;
2893 }
2894 else if (strncmp(command, "BTCGETDWELLTIME ESCO MIN", 24) == 0)
2895 {
2896 *len = scnprintf(extra, n, "BTCGETDWELLTIME ESCO MIN %u\n",
2897 (int)pCfg->min_chntime_btc_esco);
2898 return ret;
2899 }
2900 else if (strncmp(command, "BTCGETDWELLTIME SCO MAX", 23) == 0)
2901 {
2902 *len = scnprintf(extra, n, "BTCGETDWELLTIME SCO MAX %u\n",
2903 (int)pCfg->max_chntime_btc_sco);
2904 return ret;
2905 }
2906 else if (strncmp(command, "BTCGETDWELLTIME SCO MIN", 23) == 0)
2907 {
2908 *len = scnprintf(extra, n, "BTCGETDWELLTIME SCO MIN %u\n",
2909 (int)pCfg->min_chntime_btc_sco);
2910 return ret;
2911 }
2912 else
2913 {
2914 ret = -EINVAL;
2915 }
2916
2917 return ret;
2918}
2919
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302920int hdd_drv_cmd_validate(tANI_U8 *command, int len)
2921{
2922 if (command[len] != ' ')
2923 return -EINVAL;
2924
2925 return 0;
2926}
2927
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05302928#ifdef WLAN_AP_STA_CONCURRENCY
2929
2930/**
2931 * hdd_conc_get_dwell_time() - Get concurrency dwell time parameters
2932 * @pCfg: Pointer to HDD context
2933 * @command: ASCII text command that is received
2934 * @extra: Pointer to copy data sent to user
2935 * @n: size of 'extra' buffer
2936 * @len: length copied to 'extra' buffer
2937 *
2938 * Driver commands:
2939 * wpa_cli DRIVER CONCGETDWELLTIME ACTIVE MAX
2940 * wpa_cli DRIVER CONCGETDWELLTIME ACTIVE MIN
2941 * wpa_cli DRIVER CONCGETDWELLTIME PASSIVE MAX
2942 * wpa_cli DRIVER CONCGETDWELLTIME PASSIVE MIN
2943 *
2944 * Return: 0 for success non-zero for failure
2945 */
2946
2947static int hdd_conc_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command,
2948 char *extra, tANI_U8 n, tANI_U8 *len)
2949{
2950 int ret = 0;
2951
2952 if (!pCfg || !command || !extra || !len)
2953 {
2954 hddLog(LOGE, FL("Argument passsed for CONCGETDWELLTIME is incorrect"));
2955 ret = -EINVAL;
2956 return ret;
2957 }
2958
2959 if (strncmp(command, "CONCGETDWELLTIME ACTIVE MAX", 27) == 0)
2960 {
2961 *len = scnprintf(extra, n, "CONCGETDWELLTIME ACTIVE MAX %u\n",
2962 (int)pCfg->nActiveMaxChnTimeConc);
2963 return ret;
2964 }
2965 else if (strncmp(command, "CONCGETDWELLTIME ACTIVE MIN", 27) == 0)
2966 {
2967 *len = scnprintf(extra, n, "CONCGETDWELLTIME ACTIVE MIN %u\n",
2968 (int)pCfg->nActiveMinChnTimeConc);
2969 return ret;
2970 }
2971 else if (strncmp(command, "CONCGETDWELLTIME PASSIVE MAX", 28) == 0)
2972 {
2973 *len = scnprintf(extra, n, "CONCGETDWELLTIME PASSIVE MAX %u\n",
2974 (int)pCfg->nPassiveMaxChnTimeConc);
2975 return ret;
2976 }
2977 else if (strncmp(command, "CONCGETDWELLTIME PASSIVE MIN", 28) == 0)
2978 {
2979 *len = scnprintf(extra, n, "CONCGETDWELLTIME PASSIVE MIN %u\n",
2980 (int)pCfg->nPassiveMinChnTimeConc);
2981 return ret;
2982 }
2983 else
2984 {
2985 ret = -EINVAL;
2986 }
2987
2988 return ret;
2989}
2990
2991/**
2992 * hdd_conc_set_dwell_time() - Set concurrency dwell time parameters
2993 * @pAdapter: Adapter upon which the command was received
2994 * @command: ASCII text command that is received
2995 *
2996 * Driver commands:
2997 * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MAX <value>
2998 * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MIN <value>
2999 * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MAX <value
3000 * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MIN <value>
3001 *
3002 * Return: 0 for success non-zero for failure
3003 */
3004
3005static int hdd_conc_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3006{
3007 tHalHandle hHal;
3008 hdd_config_t *pCfg;
3009 tANI_U8 *value = command;
3010 int val = 0, ret = 0, temp = 0;
3011 tSmeConfigParams smeConfig;
3012
3013 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3014 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
3015 {
3016 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME is incorrect"));
3017 ret = -EINVAL;
3018 return ret;
3019 }
3020
3021 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3022 sme_GetConfigParam(hHal, &smeConfig);
3023
3024 if (strncmp(command, "CONCSETDWELLTIME ACTIVE MAX", 27) == 0 )
3025 {
3026 if (hdd_drv_cmd_validate(command, 27)) {
3027 hddLog(LOGE, FL("Invalid driver command"));
3028 return -EINVAL;
3029 }
3030
3031 value = value + 28;
3032 temp = kstrtou32(value, 10, &val);
3033 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MIN ||
3034 val > CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MAX)
3035 {
3036 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME ACTIVE MAX is incorrect"));
3037 ret = -EFAULT;
3038 return ret;
3039 }
3040 pCfg->nActiveMaxChnTimeConc = val;
3041 smeConfig.csrConfig.nActiveMaxChnTimeConc = val;
3042 sme_UpdateConfig(hHal, &smeConfig);
3043 }
3044 else if (strncmp(command, "CONCSETDWELLTIME ACTIVE MIN", 27) == 0)
3045 {
3046 if (hdd_drv_cmd_validate(command, 27)) {
3047 hddLog(LOGE, FL("Invalid driver command"));
3048 return -EINVAL;
3049 }
3050
3051 value = value + 28;
3052 temp = kstrtou32(value, 10, &val);
3053 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MIN ||
3054 val > CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MAX)
3055 {
3056 hddLog(LOGE, FL("Argument passsed for CONCSETDWELLTIME ACTIVE MIN is incorrect"));
3057 ret = -EFAULT;
3058 return ret;
3059 }
3060 pCfg->nActiveMinChnTimeConc = val;
3061 smeConfig.csrConfig.nActiveMinChnTimeConc = val;
3062 sme_UpdateConfig(hHal, &smeConfig);
3063 }
3064 else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MAX", 28) == 0)
3065 {
3066 if (hdd_drv_cmd_validate(command, 28)) {
3067 hddLog(LOGE, FL("Invalid driver command"));
3068 return -EINVAL;
3069 }
3070
3071 value = value + 29;
3072 temp = kstrtou32(value, 10, &val);
3073 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MIN ||
3074 val > CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MAX)
3075 {
3076 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME PASSIVE MAX is incorrect"));
3077 ret = -EFAULT;
3078 return ret;
3079 }
3080 pCfg->nPassiveMaxChnTimeConc = val;
3081 smeConfig.csrConfig.nPassiveMaxChnTimeConc = val;
3082 sme_UpdateConfig(hHal, &smeConfig);
3083 }
3084 else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MIN", 28) == 0)
3085 {
3086 if (hdd_drv_cmd_validate(command, 28)) {
3087 hddLog(LOGE, FL("Invalid driver command"));
3088 return -EINVAL;
3089 }
3090
3091 value = value + 29;
3092 temp = kstrtou32(value, 10, &val);
3093 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MIN ||
3094 val > CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MAX )
3095 {
3096 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME PASSIVE MIN is incorrect"));
3097 ret = -EFAULT;
3098 return ret;
3099 }
3100 pCfg->nPassiveMinChnTimeConc = val;
3101 smeConfig.csrConfig.nPassiveMinChnTimeConc = val;
3102 sme_UpdateConfig(hHal, &smeConfig);
3103 }
3104 else
3105 {
3106 ret = -EINVAL;
3107 }
3108
3109 return ret;
3110}
3111
3112#endif
3113
3114/**
3115 * hdd_btc_set_dwell_time() - Set BTC dwell time parameters
3116 * @pAdapter: Adapter upon which the command was received
3117 * @command: ASCII text command that is received
3118 *
3119 * Driver commands:
3120 * wpa_cli DRIVER BTCSETDWELLTIME ESCO MAX <value>
3121 * wpa_cli DRIVER BTCSETDWELLTIME ESCO MIN <value>
3122 * wpa_cli DRIVER BTCSETDWELLTIME SCO MAX <value>
3123 * wpa_cli DRIVER BTCSETDWELLTIME SCO MIN <value>
3124 *
3125 * Return: 0 for success non-zero for failure
3126 */
3127
3128static int hdd_btc_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3129{
3130 tHalHandle hHal;
3131 hdd_config_t *pCfg;
3132 tANI_U8 *value = command;
3133 int val = 0, ret = 0, temp = 0;
3134 tSmeConfigParams smeConfig;
3135
3136 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3137 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
3138 {
3139 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME is incorrect"));
3140 ret = -EINVAL;
3141 return ret;
3142 }
3143
3144 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3145 sme_GetConfigParam(hHal, &smeConfig);
3146
3147 if (strncmp(command, "BTCSETDWELLTIME ESCO MAX", 24) == 0)
3148 {
3149 if (hdd_drv_cmd_validate(command, 24)) {
3150 hddLog(LOGE, FL("Invalid driver command"));
3151 return -EINVAL;
3152 }
3153
3154 value = value + 25;
3155 temp = kstrtou32(value, 10, &val);
3156 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MIN ||
3157 val > CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MAX)
3158 {
3159 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME ESCO MAX is incorrect"));
3160 ret = -EFAULT;
3161 return ret;
3162 }
3163 pCfg->max_chntime_btc_esco = val;
3164 smeConfig.csrConfig.max_chntime_btc_esco = val;
3165 sme_UpdateConfig(hHal, &smeConfig);
3166 }
3167 else if (strncmp(command, "BTCSETDWELLTIME ESCO MIN", 24) == 0)
3168 {
3169 if (hdd_drv_cmd_validate(command, 24)) {
3170 hddLog(LOGE, FL("Invalid driver command"));
3171 return -EINVAL;
3172 }
3173
3174 value = value + 25;
3175 temp = kstrtou32(value, 10, &val);
3176 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MIN ||
3177 val > CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MAX)
3178 {
3179 hddLog(LOGE, FL("Argument passsed for BTCSETDWELLTIME ESCO MIN is incorrect"));
3180 ret = -EFAULT;
3181 return ret;
3182 }
3183 pCfg->min_chntime_btc_esco = val;
3184 smeConfig.csrConfig.min_chntime_btc_esco = val;
3185 sme_UpdateConfig(hHal, &smeConfig);
3186 }
3187 else if (strncmp(command, "BTCSETDWELLTIME SCO MAX", 23) == 0)
3188 {
3189 if (hdd_drv_cmd_validate(command, 23)) {
3190 hddLog(LOGE, FL("Invalid driver command"));
3191 return -EINVAL;
3192 }
3193
3194 value = value + 24;
3195 temp = kstrtou32(value, 10, &val);
3196 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MIN ||
3197 val > CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MAX)
3198 {
3199 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME SCO MAX is incorrect"));
3200 ret = -EFAULT;
3201 return ret;
3202 }
3203 pCfg->max_chntime_btc_sco = val;
3204 smeConfig.csrConfig.max_chntime_btc_sco = val;
3205 sme_UpdateConfig(hHal, &smeConfig);
3206 }
3207 else if (strncmp(command, "BTCSETDWELLTIME SCO MIN", 23) == 0)
3208 {
3209 if (hdd_drv_cmd_validate(command, 23)) {
3210 hddLog(LOGE, FL("Invalid driver command"));
3211 return -EINVAL;
3212 }
3213
3214 value = value + 24;
3215 temp = kstrtou32(value, 10, &val);
3216 if (temp != 0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MIN ||
3217 val > CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MAX)
3218 {
3219 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME SCO MIN is incorrect"));
3220 ret = -EFAULT;
3221 return ret;
3222 }
3223 pCfg->min_chntime_btc_sco = val;
3224 smeConfig.csrConfig.min_chntime_btc_sco = val;
3225 sme_UpdateConfig(hHal, &smeConfig);
3226 }
3227 else
3228 {
3229 ret = -EINVAL;
3230 }
3231
3232 return ret;
3233}
3234
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303235static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3236{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303237 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303238 hdd_config_t *pCfg;
3239 tANI_U8 *value = command;
3240 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303241 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303242
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303243 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3244 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303245 {
3246 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3247 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3248 ret = -EINVAL;
3249 return ret;
3250 }
3251
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303252 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3253 sme_GetConfigParam(hHal, &smeConfig);
3254
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303255 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
3256 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303257 if (hdd_drv_cmd_validate(command, 23))
3258 return -EINVAL;
3259
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303260 value = value + 24;
3261 temp = kstrtou32(value, 10, &val);
3262 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3263 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3264 {
3265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3266 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
3267 ret = -EFAULT;
3268 return ret;
3269 }
3270 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303271 smeConfig.csrConfig.nActiveMaxChnTime = val;
3272 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303273 }
3274 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
3275 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303276 if (hdd_drv_cmd_validate(command, 23))
3277 return -EINVAL;
3278
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303279 value = value + 24;
3280 temp = kstrtou32(value, 10, &val);
3281 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
3282 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
3283 {
3284 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3285 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
3286 ret = -EFAULT;
3287 return ret;
3288 }
3289 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303290 smeConfig.csrConfig.nActiveMinChnTime = val;
3291 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303292 }
3293 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
3294 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303295 if (hdd_drv_cmd_validate(command, 24))
3296 return -EINVAL;
3297
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303298 value = value + 25;
3299 temp = kstrtou32(value, 10, &val);
3300 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
3301 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
3302 {
3303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3304 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
3305 ret = -EFAULT;
3306 return ret;
3307 }
3308 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303309 smeConfig.csrConfig.nPassiveMaxChnTime = val;
3310 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303311 }
3312 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
3313 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303314 if (hdd_drv_cmd_validate(command, 24))
3315 return -EINVAL;
3316
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303317 value = value + 25;
3318 temp = kstrtou32(value, 10, &val);
3319 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
3320 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
3321 {
3322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3323 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
3324 ret = -EFAULT;
3325 return ret;
3326 }
3327 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303328 smeConfig.csrConfig.nPassiveMinChnTime = val;
3329 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303330 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05303331 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3332 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303333 if (hdd_drv_cmd_validate(command, 12))
3334 return -EINVAL;
3335
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05303336 value = value + 13;
3337 temp = kstrtou32(value, 10, &val);
3338 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3339 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3340 {
3341 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3342 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3343 ret = -EFAULT;
3344 return ret;
3345 }
3346 pCfg->nActiveMaxChnTime = val;
3347 smeConfig.csrConfig.nActiveMaxChnTime = val;
3348 sme_UpdateConfig(hHal, &smeConfig);
3349 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303350 else
3351 {
3352 ret = -EINVAL;
3353 }
3354
3355 return ret;
3356}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303357static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
3358 tANI_U8 cmd_len)
3359{
3360 tANI_U8 *value;
3361 tANI_U8 fcc_constraint;
3362
3363 eHalStatus status;
3364 int ret = 0;
3365 value = cmd + cmd_len + 1;
3366
3367 ret = kstrtou8(value, 10, &fcc_constraint);
3368 if ((ret < 0) || (fcc_constraint > 1)) {
3369 /*
3370 * If the input value is greater than max value of datatype,
3371 * then also it is a failure
3372 */
3373 hddLog(VOS_TRACE_LEVEL_ERROR,
3374 "%s: value out of range", __func__);
3375 return -EINVAL;
3376 }
3377
Agrawal Ashish842eea82016-02-04 17:56:16 +05303378 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint,
3379 pHddCtx->scan_info.mScanPending);
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303380 if (status != eHAL_STATUS_SUCCESS)
3381 ret = -EPERM;
3382
3383 return ret;
3384}
3385
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05303386/**---------------------------------------------------------------------------
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303387
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05303388 \brief hdd_enable_disable_ca_event() - When Host sends IOCTL (enabled),
3389 FW will send *ONE* CA ind to Host(even though it is duplicate).
3390 When Host send IOCTL (disable), FW doesn't perform any action.
3391 Whenever any change in CA *and* WLAN is in SAP/P2P-GO mode, FW
3392 sends CA ind to host. (regard less of IOCTL status)
3393 \param - pHddCtx - HDD context
3394 \param - command - command received from framework
3395 \param - cmd_len - len of the command
3396
3397 \return - 0 on success, appropriate error values on failure.
3398
3399 --------------------------------------------------------------------------*/
3400int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, tANI_U8* command, tANI_U8 cmd_len)
3401{
3402 tANI_U8 set_value;
3403 int ret = 0;
3404 eHalStatus status;
3405
3406 ret = wlan_hdd_validate_context(pHddCtx);
3407 if (0 != ret)
3408 {
3409 ret = -EINVAL;
3410 goto exit;
3411 }
3412
3413 if (pHddCtx->cfg_ini->gOptimizeCAevent == 0)
3414 {
3415 hddLog(VOS_TRACE_LEVEL_ERROR, "Enable gOptimizeCAevent"
3416 " ini param to control channel avooidance indication");
3417 ret = 0;
3418 goto exit;
3419 }
3420
3421 set_value = command[cmd_len + 1] - '0';
3422 status = sme_enableDisableChanAvoidIndEvent(pHddCtx->hHal, set_value);
3423 if (status != eHAL_STATUS_SUCCESS)
3424 {
3425 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to send"
3426 " enableDisableChanAoidance command to SME\n", __func__);
3427 ret = -EINVAL;
3428 }
3429
3430exit:
3431 return ret;
3432}
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303433
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303434/**
3435 * wlan_hdd_fastreassoc_handoff_request() - Post Handoff request to SME
3436 * @pHddCtx: Pointer to the HDD context
3437 * @channel: channel to reassociate
3438 * @targetApBssid: Target AP/BSSID to reassociate
3439 *
3440 * Return: None
3441 */
3442#if defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) && !defined(QCA_WIFI_ISOC)
3443static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3444 uint8_t channel, tSirMacAddr targetApBssid)
3445{
3446 tCsrHandoffRequest handoffInfo;
3447 handoffInfo.channel = channel;
3448 handoffInfo.src = FASTREASSOC;
3449 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3450 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3451}
3452#else
3453static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3454 uint8_t channel, tSirMacAddr targetApBssid)
3455{
3456}
3457#endif
3458
3459/**
3460 * csr_fastroam_neighbor_ap_event() - Function to trigger scan/roam
3461 * @pAdapter: Pointer to HDD adapter
3462 * @channel: Channel to scan/roam
3463 * @targetApBssid: BSSID to roam
3464 *
3465 * Return: None
3466 */
3467#ifdef QCA_WIFI_ISOC
3468static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3469 uint8_t channel, tSirMacAddr targetApBssid)
3470{
3471 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3472 &targetApBssid[0], eSME_ROAM_TRIGGER_SCAN, channel);
3473}
3474#else
3475static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3476 uint8_t channel, tSirMacAddr targetApBssid)
3477{
3478}
3479#endif
3480
3481/**
3482 * wlan_hdd_handle_fastreassoc() - Handle fastreassoc command
3483 * @pAdapter: pointer to hdd adapter
3484 * @command: pointer to the command received
3485 *
3486 * Return: VOS_STATUS enum
3487 */
3488static VOS_STATUS wlan_hdd_handle_fastreassoc(hdd_adapter_t *pAdapter,
3489 uint8_t *command)
3490{
3491 tANI_U8 *value = command;
3492 tANI_U8 channel = 0;
3493 tSirMacAddr targetApBssid;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303494 hdd_station_ctx_t *pHddStaCtx = NULL;
3495 hdd_context_t *pHddCtx = NULL;
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303496 int ret;
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303497 tCsrRoamModifyProfileFields mod_profile_fields;
3498 uint32_t roam_id = 0;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303499 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3500 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3501
3502 /* if not associated, no need to proceed with reassoc */
3503 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
3504 hddLog(LOG1, FL("Not associated!"));
3505 return eHAL_STATUS_FAILURE;
3506 }
3507
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303508 ret = hdd_parse_reassoc_command_v1_data(value, targetApBssid, &channel);
3509 if (ret) {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303510 hddLog(LOGE, FL("Failed to parse reassoc command data"));
3511 return eHAL_STATUS_FAILURE;
3512 }
3513
3514 /* if the target bssid is same as currently associated AP,
3515 then no need to proceed with reassoc */
3516 if (vos_mem_compare(targetApBssid,
3517 pHddStaCtx->conn_info.bssId,
3518 sizeof(tSirMacAddr))) {
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303519 sme_GetModifyProfileFields(pHddCtx->hHal, pAdapter->sessionId,
3520 &mod_profile_fields);
3521 sme_RoamReassoc(pHddCtx->hHal, pAdapter->sessionId, NULL,
3522 mod_profile_fields, &roam_id, 1);
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303523 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303524 return eHAL_STATUS_SUCCESS;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303525 }
3526
3527 /* Check channel number is a valid channel number */
3528 if (VOS_STATUS_SUCCESS !=
3529 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
3530 hddLog(LOGE, FL("Invalid Channel [%d]"), channel);
3531 return eHAL_STATUS_FAILURE;
3532 }
3533
3534 /* Proceed with reassoc */
3535 wlan_hdd_fastreassoc_handoff_request(pHddCtx, channel, targetApBssid);
3536
3537 /* Proceed with scan/roam */
3538 csr_fastroam_neighbor_ap_event(pAdapter, channel, targetApBssid);
3539
3540 return eHAL_STATUS_SUCCESS;
3541}
3542
3543/**
3544 * hdd_assign_reassoc_handoff - Set handoff source as REASSOC
3545 * @handoffInfo: Pointer to the csr Handoff Request.
3546 *
3547 * Return: None
3548 */
3549#ifndef QCA_WIFI_ISOC
3550static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3551{
3552 handoffInfo->src = REASSOC;
3553}
3554#else
3555static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3556{
3557}
3558#endif
3559
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303560/**
3561 * wlan_hdd_free_cache_channels() - Free the cache channels list
3562 * @hdd_ctx: Pointer to HDD context
3563 *
3564 * Return: None
3565 */
3566
3567static void wlan_hdd_free_cache_channels(hdd_context_t *hdd_ctx)
3568{
3569 mutex_lock(&hdd_ctx->cache_channel_lock);
3570 hdd_ctx->orginal_channels->num_channels = 0;
3571 vos_mem_free(hdd_ctx->orginal_channels->channel_info);
3572 hdd_ctx->orginal_channels->channel_info = NULL;
3573 vos_mem_free(hdd_ctx->orginal_channels);
3574 hdd_ctx->orginal_channels = NULL;
3575 mutex_unlock(&hdd_ctx->cache_channel_lock);
3576}
3577
3578/**
3579 * hdd_alloc_chan_cache() - Allocate the memory to cache the channel
3580 * info for the channels received in command SET_DISABLE_CHANNEL_LIST
3581 * @hdd_ctx: Pointer to HDD context
3582 * @num_chan: Number of channels for which memory needs to
3583 * be allocated
3584 *
3585 * Return: 0 on success and error code on failure
3586 */
3587
3588int hdd_alloc_chan_cache(hdd_context_t *hdd_ctx, int num_chan)
3589{
3590 if (NULL == hdd_ctx->orginal_channels) {
3591 hdd_ctx->orginal_channels =
3592 vos_mem_malloc(sizeof(struct hdd_cache_channels));
3593 if (NULL == hdd_ctx->orginal_channels) {
3594 hddLog(VOS_TRACE_LEVEL_ERROR,
3595 "In %s, VOS_MALLOC_ERR", __func__);
3596 return -EINVAL;
3597 }
3598 hdd_ctx->orginal_channels->num_channels = num_chan;
3599 hdd_ctx->orginal_channels->channel_info =
3600 vos_mem_malloc(num_chan *
3601 sizeof(struct hdd_cache_channel_info));
3602 if (NULL == hdd_ctx->orginal_channels->channel_info) {
3603 hddLog(VOS_TRACE_LEVEL_ERROR,
3604 "In %s, VOS_MALLOC_ERR", __func__);
3605 hdd_ctx->orginal_channels->num_channels = 0;
3606 vos_mem_free(hdd_ctx->orginal_channels);
3607 hdd_ctx->orginal_channels = NULL;
3608 return -EINVAL;
3609 }
3610 } else {
3611 /* Same command comes multiple times */
3612 struct hdd_cache_channel_info *temp_chan_info;
3613
3614 if (hdd_ctx->orginal_channels->num_channels + num_chan >
3615 MAX_CHANNEL) {
3616 hddLog(VOS_TRACE_LEVEL_ERROR,
3617 "%s: Invalid Number of channel received",
3618 __func__);
3619 return -EINVAL;
3620 }
3621
3622 temp_chan_info = vos_mem_malloc((
3623 hdd_ctx->orginal_channels->
3624 num_channels + num_chan) *
3625 sizeof(struct hdd_cache_channel_info));
3626 if (NULL == temp_chan_info) {
3627 hddLog(VOS_TRACE_LEVEL_ERROR,
3628 "In %s, VOS_MALLOC_ERR",
3629 __func__);
3630 return -EINVAL;
3631 }
3632
3633 vos_mem_copy(temp_chan_info, hdd_ctx->orginal_channels->
3634 channel_info, hdd_ctx->orginal_channels->
3635 num_channels *
3636 sizeof(struct hdd_cache_channel_info));
3637
3638 hdd_ctx->orginal_channels->num_channels += num_chan;
3639 vos_mem_free(hdd_ctx->orginal_channels->channel_info);
3640 hdd_ctx->orginal_channels->channel_info = temp_chan_info;
3641 temp_chan_info = NULL;
3642 }
3643 return 0;
3644
3645}
3646
3647
3648int hdd_parse_disable_chan_cmd(hdd_adapter_t *adapter, tANI_U8 *ptr)
3649{
3650 v_PVOID_t pvosGCtx = vos_get_global_context(VOS_MODULE_ID_HDD, NULL);
3651 hdd_context_t *hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, pvosGCtx);
3652 tANI_U8 *param;
3653 int j, tempInt, index = 0, ret = 0;
3654
3655 if (NULL == pvosGCtx) {
3656 hddLog(VOS_TRACE_LEVEL_FATAL,
3657 "VOS Global Context is NULL");
3658 return -EINVAL;
3659 }
3660
3661 if (NULL == hdd_ctx) {
3662 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
3663 return -EINVAL;
3664 }
3665
3666 param = strchr(ptr, ' ');
3667 /*no argument after the command*/
3668 if (NULL == param)
3669 return -EINVAL;
3670
3671 /*no space after the command*/
3672 else if (SPACE_ASCII_VALUE != *param)
3673 return -EINVAL;
3674
3675 param++;
3676
3677 /*removing empty spaces*/
3678 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3679 param++;
3680
3681 /*no argument followed by spaces*/
3682 if ('\0' == *param)
3683 return -EINVAL;
3684
3685 /*getting the first argument ie the number of channels*/
3686 if (sscanf(param, "%d ", &tempInt) != 1) {
3687 hddLog(VOS_TRACE_LEVEL_ERROR,
3688 "%s: Cannot get number of channels from input",
3689 __func__);
3690 return -EINVAL;
3691 }
3692
3693 if (tempInt < 0 || tempInt > MAX_CHANNEL) {
3694 hddLog(VOS_TRACE_LEVEL_ERROR,
3695 "%s: Invalid Number of channel received", __func__);
3696 return -EINVAL;
3697 }
3698
3699 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3700 "%s: Number of channel to disable are: %d",
3701 __func__, tempInt);
3702
3703 if (!tempInt) {
3704 if (!wlan_hdd_restore_channels(hdd_ctx)) {
3705 /*
3706 * Free the cache channels only when the command is
3707 * received with num channels as 0
3708 */
3709 wlan_hdd_free_cache_channels(hdd_ctx);
3710 }
3711 return 0;
3712 }
3713
3714 mutex_lock(&hdd_ctx->cache_channel_lock);
3715 if (hdd_alloc_chan_cache(hdd_ctx, tempInt)) {
3716 ret = -ENOMEM;
3717 goto parse_done;
3718 }
3719 index = hdd_ctx->orginal_channels->num_channels - tempInt;
3720
3721 for (j = index; j < hdd_ctx->orginal_channels->num_channels; j++) {
3722 /*
3723 * param pointing to the beginning of first space
3724 * after number of channels
3725 */
3726 param = strpbrk(param, " ");
3727 /*no channel list after the number of channels argument*/
3728 if (NULL == param) {
3729 hddLog(VOS_TRACE_LEVEL_ERROR,
3730 "%s, Invalid No of channel provided in the list",
3731 __func__);
3732 ret = -EINVAL;
3733 goto parse_done;
3734 }
3735
3736 param++;
3737
3738 /*removing empty space*/
3739 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3740 param++;
3741
3742 if ('\0' == *param) {
3743 hddLog(VOS_TRACE_LEVEL_ERROR,
3744 "%s, No channel is provided in the list",
3745 __func__);
3746 ret = -EINVAL;
3747 goto parse_done;
3748
3749 }
3750
3751 if (sscanf(param, "%d ", &tempInt) != 1) {
3752 hddLog(VOS_TRACE_LEVEL_ERROR,
3753 "%s: Cannot read channel number",
3754 __func__);
3755 ret = -EINVAL;
3756 goto parse_done;
3757
3758 }
3759
3760 if (!IS_CHANNEL_VALID(tempInt)) {
3761 hddLog(VOS_TRACE_LEVEL_ERROR,
3762 "%s: Invalid channel number received",
3763 __func__);
3764 ret = -EINVAL;
3765 goto parse_done;
3766
3767 }
3768
3769 hddLog(VOS_TRACE_LEVEL_INFO, "%s: channel[%d] = %d", __func__,
3770 j, tempInt);
3771 hdd_ctx->orginal_channels->channel_info[j].channel_num =
3772 tempInt;
3773 }
3774
3775 /*extra arguments check*/
3776 param = strchr(param, ' ');
3777 if (NULL != param) {
3778 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3779 param++;
3780
3781 if ('\0' != *param) {
3782 hddLog(VOS_TRACE_LEVEL_ERROR,
3783 "%s: Invalid argument received", __func__);
3784 ret = -EINVAL;
3785 goto parse_done;
3786 }
3787 }
3788
3789parse_done:
3790 mutex_unlock(&hdd_ctx->cache_channel_lock);
3791 EXIT();
3792
3793 return ret;
3794}
3795
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303796int hdd_get_disable_ch_list(hdd_context_t *hdd_ctx, tANI_U8 *buf,
3797 tANI_U8 buf_len)
3798{
3799 struct hdd_cache_channel_info *ch_list;
3800 unsigned char i, num_ch;
3801 int len = 0;
3802
3803 mutex_lock(&hdd_ctx->cache_channel_lock);
3804 if (hdd_ctx->orginal_channels &&
3805 hdd_ctx->orginal_channels->num_channels) {
3806 num_ch = hdd_ctx->orginal_channels->num_channels;
3807
3808 if (num_ch == 0) {
3809 mutex_unlock(&hdd_ctx->cache_channel_lock);
3810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3811 FL("no disable channels programed"));
3812 return 0;
3813 }
3814
3815 len = scnprintf(buf, buf_len, "%s %hhu",
3816 "GET_DISABLE_CHANNEL_LIST", num_ch);
3817
3818 ch_list = hdd_ctx->orginal_channels->channel_info;
3819 if (!ch_list) {
3820 mutex_unlock(&hdd_ctx->cache_channel_lock);
3821 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3822 FL("disable channel list is NULL"));
3823 return 0;
3824 }
3825
3826 for (i = 0; (i < num_ch) && len <= buf_len; i++) {
3827 len += scnprintf(buf + len, buf_len - len,
3828 " %d", ch_list[i].channel_num);
3829 }
3830 }
3831 mutex_unlock(&hdd_ctx->cache_channel_lock);
3832
3833 return len;
3834}
3835
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003836static int hdd_driver_command(hdd_adapter_t *pAdapter,
3837 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07003838{
Jeff Johnson295189b2012-06-20 16:38:30 -07003839 hdd_priv_data_t priv_data;
3840 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303841 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3842 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003843 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303844 int status;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303845#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3846 struct cfg80211_mgmt_tx_params params;
3847#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303848
3849 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003850 /*
3851 * Note that valid pointers are provided by caller
3852 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003853
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003854 /* copy to local struct to avoid numerous changes to legacy code */
3855 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07003856
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003857 if (priv_data.total_len <= 0 ||
3858 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07003859 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003860 hddLog(VOS_TRACE_LEVEL_WARN,
3861 "%s:invalid priv_data.total_len(%d)!!!", __func__,
3862 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003863 ret = -EINVAL;
3864 goto exit;
3865 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05303866 status = wlan_hdd_validate_context(pHddCtx);
3867 if (0 != status)
3868 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303869 ret = -EINVAL;
3870 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303871 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003872 /* Allocate +1 for '\0' */
3873 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07003874 if (!command)
3875 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003876 hddLog(VOS_TRACE_LEVEL_ERROR,
3877 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003878 ret = -ENOMEM;
3879 goto exit;
3880 }
3881
3882 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
3883 {
3884 ret = -EFAULT;
3885 goto exit;
3886 }
3887
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003888 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003889 command[priv_data.total_len] = '\0';
3890
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003891 /* at one time the following block of code was conditional. braces
3892 * have been retained to avoid re-indenting the legacy code
3893 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003894 {
3895 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
3896
3897 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003898 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07003899
3900 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
3901 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303902 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3903 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
3904 pAdapter->sessionId, (unsigned)
3905 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
3906 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
3907 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
3908 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07003909 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
3910 sizeof(tSirMacAddr)))
3911 {
3912 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003913 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003914 ret = -EFAULT;
3915 }
3916 }
Amar Singhal0974e402013-02-12 14:27:46 -08003917 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07003918 {
Amar Singhal0974e402013-02-12 14:27:46 -08003919 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003920
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303921 ret = hdd_drv_cmd_validate(command, 7);
3922 if (ret)
3923 goto exit;
3924
Jeff Johnson295189b2012-06-20 16:38:30 -07003925 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003926
3927 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07003928 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07003929 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08003930 "%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 +05303931 if(VOS_FTM_MODE != hdd_get_conparam())
3932 {
3933 /* Change band request received */
3934 ret = hdd_setBand_helper(pAdapter->dev, ptr);
3935 if(ret < 0)
3936 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3937 "%s: failed to set band ret=%d", __func__, ret);
3938 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003939 }
Kiet Lamf040f472013-11-20 21:15:23 +05303940 else if(strncmp(command, "SETWMMPS", 8) == 0)
3941 {
3942 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303943
3944 ret = hdd_drv_cmd_validate(command, 8);
3945 if (ret)
3946 goto exit;
3947
Kiet Lamf040f472013-11-20 21:15:23 +05303948 ret = hdd_wmmps_helper(pAdapter, ptr);
3949 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05303950
3951 else if(strncmp(command, "TDLSSCAN", 8) == 0)
3952 {
3953 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303954
3955 ret = hdd_drv_cmd_validate(command, 8);
3956 if (ret)
3957 goto exit;
3958
Agarwal Ashishef54a182014-12-16 15:07:31 +05303959 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
3960 }
3961
Jeff Johnson32d95a32012-09-10 13:15:23 -07003962 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
3963 {
3964 char *country_code;
3965
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303966 ret = hdd_drv_cmd_validate(command, 7);
3967 if (ret)
3968 goto exit;
3969
Jeff Johnson32d95a32012-09-10 13:15:23 -07003970 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07003971
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003972 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07003973 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003974#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05303975 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003976#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003977 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
3978 (void *)(tSmeChangeCountryCallback)
3979 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05303980 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003981 if (eHAL_STATUS_SUCCESS == ret)
3982 {
3983 ret = wait_for_completion_interruptible_timeout(
3984 &pAdapter->change_country_code,
3985 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
3986 if (0 >= ret)
3987 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003988 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303989 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003990 }
3991 }
3992 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07003993 {
3994 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003995 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003996 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07003997 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003998
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003999 }
4000 /*
4001 command should be a string having format
4002 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
4003 */
Amar Singhal0974e402013-02-12 14:27:46 -08004004 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004005 {
Amar Singhal0974e402013-02-12 14:27:46 -08004006 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004007
4008 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004009 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004010
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08004011 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07004012 }
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +05304013
4014 else if (strncmp(command, "VOWIFIMODE", 10) == 0)
4015 {
4016 tANI_U8 *ptr;
4017
4018 ret = hdd_drv_cmd_validate(command, 10);
4019 if (ret)
4020 goto exit;
4021
4022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4023 "Received Command for VOWIFI mode in %s", __func__);
4024
4025 ptr = (tANI_U8*)command + 11;
4026 hdd_set_vowifi_mode(pHddCtx, *ptr - '0');
4027 }
4028
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004029 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
4030 {
4031 int suspend = 0;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304032 tANI_U8 *ptr;
4033
4034 ret = hdd_drv_cmd_validate(command, 14);
4035 if (ret)
4036 goto exit;
4037
4038 ptr = (tANI_U8*)command + 15;
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004039
4040 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304041 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4042 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
4043 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004044 hdd_set_wlan_suspend_mode(suspend);
4045 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004046#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
4047 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
4048 {
4049 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004050 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004051 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
4052 eHalStatus status = eHAL_STATUS_SUCCESS;
4053
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304054 ret = hdd_drv_cmd_validate(command, 14);
4055 if (ret)
4056 goto exit;
4057
Srinivas Girigowdade697412013-02-14 16:31:48 -08004058 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
4059 value = value + 15;
4060
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004061 /* Convert the value from ascii to integer */
4062 ret = kstrtos8(value, 10, &rssi);
4063 if (ret < 0)
4064 {
4065 /* If the input value is greater than max value of datatype, then also
4066 kstrtou8 fails */
4067 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4068 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07004069 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004070 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
4071 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
4072 ret = -EINVAL;
4073 goto exit;
4074 }
4075
Srinivas Girigowdade697412013-02-14 16:31:48 -08004076 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004077
Srinivas Girigowdade697412013-02-14 16:31:48 -08004078 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
4079 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
4080 {
4081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4082 "Neighbor lookup threshold value %d is out of range"
4083 " (Min: %d Max: %d)", lookUpThreshold,
4084 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
4085 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
4086 ret = -EINVAL;
4087 goto exit;
4088 }
4089
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304090 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4091 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
4092 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4094 "%s: Received Command to Set Roam trigger"
4095 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
4096
4097 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
4098 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
4099 if (eHAL_STATUS_SUCCESS != status)
4100 {
4101 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4102 "%s: Failed to set roam trigger, try again", __func__);
4103 ret = -EPERM;
4104 goto exit;
4105 }
4106
4107 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05304108 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004109 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
4110 }
4111 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
4112 {
4113 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
4114 int rssi = (-1) * lookUpThreshold;
4115 char extra[32];
4116 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304117 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4118 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
4119 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004120 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05304121 len = VOS_MIN(priv_data.total_len, len + 1);
4122 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004123 {
4124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4125 "%s: failed to copy data to user buffer", __func__);
4126 ret = -EFAULT;
4127 goto exit;
4128 }
4129 }
4130 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
4131 {
4132 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004133 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004134 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004135
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304136 ret = hdd_drv_cmd_validate(command, 17);
4137 if (ret)
4138 goto exit;
4139
Srinivas Girigowdade697412013-02-14 16:31:48 -08004140 /* input refresh period is in terms of seconds */
4141 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
4142 value = value + 18;
4143 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004144 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004145 if (ret < 0)
4146 {
4147 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004148 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08004149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004150 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08004151 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07004152 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
4153 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004154 ret = -EINVAL;
4155 goto exit;
4156 }
4157
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004158 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
4159 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004160 {
4161 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004162 "Roam scan period value %d is out of range"
4163 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07004164 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
4165 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004166 ret = -EINVAL;
4167 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304168 }
4169 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4170 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
4171 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004172 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004173
4174 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4175 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004176 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004177
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004178 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
4179 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004180 }
4181 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
4182 {
4183 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
4184 char extra[32];
4185 tANI_U8 len = 0;
4186
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304187 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4188 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
4189 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004190 len = scnprintf(extra, sizeof(extra), "%s %d",
4191 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004192 /* Returned value is in units of seconds */
Ratnam Rachuria72ba112015-07-17 13:27:03 +05304193 len = VOS_MIN(priv_data.total_len, len + 1);
4194 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4196 "%s: failed to copy data to user buffer", __func__);
4197 ret = -EFAULT;
4198 goto exit;
4199 }
4200 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004201 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
4202 {
4203 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004204 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004205 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004206
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304207 ret = hdd_drv_cmd_validate(command, 24);
4208 if (ret)
4209 goto exit;
4210
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004211 /* input refresh period is in terms of seconds */
4212 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
4213 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004214
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004215 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004216 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004217 if (ret < 0)
4218 {
4219 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004220 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004221 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004222 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004223 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004224 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
4225 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
4226 ret = -EINVAL;
4227 goto exit;
4228 }
4229
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004230 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
4231 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
4232 {
4233 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4234 "Neighbor scan results refresh period value %d is out of range"
4235 " (Min: %d Max: %d)", roamScanRefreshPeriod,
4236 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
4237 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
4238 ret = -EINVAL;
4239 goto exit;
4240 }
4241 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
4242
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4244 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004245 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004246
4247 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
4248 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
4249 }
4250 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
4251 {
4252 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
4253 char extra[32];
4254 tANI_U8 len = 0;
4255
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004256 len = scnprintf(extra, sizeof(extra), "%s %d",
4257 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004258 /* Returned value is in units of seconds */
Ratnam Rachuri2c9d6702015-07-17 13:25:16 +05304259 len = VOS_MIN(priv_data.total_len, len + 1);
4260 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004261 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4262 "%s: failed to copy data to user buffer", __func__);
4263 ret = -EFAULT;
4264 goto exit;
4265 }
4266 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004267#ifdef FEATURE_WLAN_LFR
4268 /* SETROAMMODE */
4269 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
4270 {
4271 tANI_U8 *value = command;
4272 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
4273
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05304274 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
4275 hddLog(LOGE,
4276 FL("Roaming is always disabled in STA + MON concurrency"));
4277 ret = -EINVAL;
4278 goto exit;
4279 }
4280
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304281 ret = hdd_drv_cmd_validate(command, SIZE_OF_SETROAMMODE);
4282 if (ret)
4283 goto exit;
4284
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004285 /* Move pointer to ahead of SETROAMMODE<delimiter> */
4286 value = value + SIZE_OF_SETROAMMODE + 1;
4287
4288 /* Convert the value from ascii to integer */
4289 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
4290 if (ret < 0)
4291 {
4292 /* If the input value is greater than max value of datatype, then also
4293 kstrtou8 fails */
4294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4295 "%s: kstrtou8 failed range [%d - %d]", __func__,
4296 CFG_LFR_FEATURE_ENABLED_MIN,
4297 CFG_LFR_FEATURE_ENABLED_MAX);
4298 ret = -EINVAL;
4299 goto exit;
4300 }
4301 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
4302 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
4303 {
4304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4305 "Roam Mode value %d is out of range"
4306 " (Min: %d Max: %d)", roamMode,
4307 CFG_LFR_FEATURE_ENABLED_MIN,
4308 CFG_LFR_FEATURE_ENABLED_MAX);
4309 ret = -EINVAL;
4310 goto exit;
4311 }
4312
4313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4314 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
4315 /*
4316 * Note that
4317 * SETROAMMODE 0 is to enable LFR while
4318 * SETROAMMODE 1 is to disable LFR, but
4319 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
4320 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
4321 */
4322 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
4323 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
4324 else
4325 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
4326
4327 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
4328 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
4329 }
4330 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304331 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004332 {
4333 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4334 char extra[32];
4335 tANI_U8 len = 0;
4336
4337 /*
4338 * roamMode value shall be inverted because the sementics is different.
4339 */
4340 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
4341 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
4342 else
4343 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
4344
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004345 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Ratnam Rachuri28693eb2015-07-17 13:23:42 +05304346 len = VOS_MIN(priv_data.total_len, len + 1);
4347 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004348 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4349 "%s: failed to copy data to user buffer", __func__);
4350 ret = -EFAULT;
4351 goto exit;
4352 }
4353 }
4354#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08004355#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004356#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004357 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
4358 {
4359 tANI_U8 *value = command;
4360 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
4361
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304362 ret = hdd_drv_cmd_validate(command, 12);
4363 if (ret)
4364 goto exit;
4365
Srinivas Girigowdade697412013-02-14 16:31:48 -08004366 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
4367 value = value + 13;
4368 /* Convert the value from ascii to integer */
4369 ret = kstrtou8(value, 10, &roamRssiDiff);
4370 if (ret < 0)
4371 {
4372 /* If the input value is greater than max value of datatype, then also
4373 kstrtou8 fails */
4374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4375 "%s: kstrtou8 failed range [%d - %d]", __func__,
4376 CFG_ROAM_RSSI_DIFF_MIN,
4377 CFG_ROAM_RSSI_DIFF_MAX);
4378 ret = -EINVAL;
4379 goto exit;
4380 }
4381
4382 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
4383 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
4384 {
4385 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4386 "Roam rssi diff value %d is out of range"
4387 " (Min: %d Max: %d)", roamRssiDiff,
4388 CFG_ROAM_RSSI_DIFF_MIN,
4389 CFG_ROAM_RSSI_DIFF_MAX);
4390 ret = -EINVAL;
4391 goto exit;
4392 }
4393
4394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4395 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
4396
4397 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
4398 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
4399 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304400 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004401 {
4402 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
4403 char extra[32];
4404 tANI_U8 len = 0;
4405
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304406 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4407 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
4408 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004409 len = scnprintf(extra, sizeof(extra), "%s %d",
4410 command, roamRssiDiff);
Ratnam Rachuri22a3b402015-07-17 13:21:49 +05304411 len = VOS_MIN(priv_data.total_len, len + 1);
4412 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004413 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4414 "%s: failed to copy data to user buffer", __func__);
4415 ret = -EFAULT;
4416 goto exit;
4417 }
4418 }
4419#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004420#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004421 else if (strncmp(command, "GETBAND", 7) == 0)
4422 {
4423 int band = -1;
4424 char extra[32];
4425 tANI_U8 len = 0;
4426 hdd_getBand_helper(pHddCtx, &band);
4427
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304428 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4429 TRACE_CODE_HDD_GETBAND_IOCTL,
4430 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004431 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Ratnam Rachuri52139592015-07-17 13:17:29 +05304432 len = VOS_MIN(priv_data.total_len, len + 1);
4433 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004434 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4435 "%s: failed to copy data to user buffer", __func__);
4436 ret = -EFAULT;
4437 goto exit;
4438 }
4439 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004440 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
4441 {
4442 tANI_U8 *value = command;
4443 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4444 tANI_U8 numChannels = 0;
4445 eHalStatus status = eHAL_STATUS_SUCCESS;
4446
4447 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4448 if (eHAL_STATUS_SUCCESS != status)
4449 {
4450 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4451 "%s: Failed to parse channel list information", __func__);
4452 ret = -EINVAL;
4453 goto exit;
4454 }
4455
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304456 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4457 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
4458 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004459 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4460 {
4461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4462 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4463 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4464 ret = -EINVAL;
4465 goto exit;
4466 }
4467 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
4468 numChannels);
4469 if (eHAL_STATUS_SUCCESS != status)
4470 {
4471 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4472 "%s: Failed to update channel list information", __func__);
4473 ret = -EINVAL;
4474 goto exit;
4475 }
4476 }
4477 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
4478 {
4479 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4480 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07004481 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004482 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07004483 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004484
4485 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
4486 ChannelList, &numChannels ))
4487 {
4488 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4489 "%s: failed to get roam scan channel list", __func__);
4490 ret = -EFAULT;
4491 goto exit;
4492 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304493 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4494 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
4495 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004496 /* output channel list is of the format
4497 [Number of roam scan channels][Channel1][Channel2]... */
4498 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004499 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Sushant Kaushika08ca192015-09-16 15:52:04 +05304500 for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004501 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004502 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
4503 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004504 }
4505
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05304506 len = VOS_MIN(priv_data.total_len, len + 1);
4507 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004508 {
4509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4510 "%s: failed to copy data to user buffer", __func__);
4511 ret = -EFAULT;
4512 goto exit;
4513 }
4514 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004515 else if (strncmp(command, "GETCCXMODE", 10) == 0)
4516 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004517 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004518 char extra[32];
4519 tANI_U8 len = 0;
4520
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004521 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004522 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004523 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004524 hdd_is_okc_mode_enabled(pHddCtx) &&
4525 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4526 {
4527 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004528 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004529 " hence this operation is not permitted!", __func__);
4530 ret = -EPERM;
4531 goto exit;
4532 }
4533
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004534 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004535 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05304536 len = VOS_MIN(priv_data.total_len, len + 1);
4537 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004538 {
4539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4540 "%s: failed to copy data to user buffer", __func__);
4541 ret = -EFAULT;
4542 goto exit;
4543 }
4544 }
4545 else if (strncmp(command, "GETOKCMODE", 10) == 0)
4546 {
4547 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
4548 char extra[32];
4549 tANI_U8 len = 0;
4550
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004551 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004552 then this operation is not permitted (return FAILURE) */
4553 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004554 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004555 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4556 {
4557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004558 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004559 " hence this operation is not permitted!", __func__);
4560 ret = -EPERM;
4561 goto exit;
4562 }
4563
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004564 len = scnprintf(extra, sizeof(extra), "%s %d",
4565 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05304566 len = VOS_MIN(priv_data.total_len, len + 1);
4567 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004568 {
4569 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4570 "%s: failed to copy data to user buffer", __func__);
4571 ret = -EFAULT;
4572 goto exit;
4573 }
4574 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004575 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004576 {
4577 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4578 char extra[32];
4579 tANI_U8 len = 0;
4580
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004581 len = scnprintf(extra, sizeof(extra), "%s %d",
4582 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05304583 len = VOS_MIN(priv_data.total_len, len + 1);
4584 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004585 {
4586 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4587 "%s: failed to copy data to user buffer", __func__);
4588 ret = -EFAULT;
4589 goto exit;
4590 }
4591 }
4592 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
4593 {
4594 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4595 char extra[32];
4596 tANI_U8 len = 0;
4597
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004598 len = scnprintf(extra, sizeof(extra), "%s %d",
4599 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05304600 len = VOS_MIN(priv_data.total_len, len + 1);
4601 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004602 {
4603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4604 "%s: failed to copy data to user buffer", __func__);
4605 ret = -EFAULT;
4606 goto exit;
4607 }
4608 }
4609 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
4610 {
4611 tANI_U8 *value = command;
4612 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
4613
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304614 ret = hdd_drv_cmd_validate(command, 25);
4615 if (ret)
4616 goto exit;
4617
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004618 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
4619 value = value + 26;
4620 /* Convert the value from ascii to integer */
4621 ret = kstrtou8(value, 10, &minTime);
4622 if (ret < 0)
4623 {
4624 /* If the input value is greater than max value of datatype, then also
4625 kstrtou8 fails */
4626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4627 "%s: kstrtou8 failed range [%d - %d]", __func__,
4628 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
4629 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
4630 ret = -EINVAL;
4631 goto exit;
4632 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004633 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
4634 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
4635 {
4636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4637 "scan min channel time value %d is out of range"
4638 " (Min: %d Max: %d)", minTime,
4639 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
4640 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
4641 ret = -EINVAL;
4642 goto exit;
4643 }
4644
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304645 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4646 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
4647 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4649 "%s: Received Command to change channel min time = %d", __func__, minTime);
4650
4651 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
4652 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
4653 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004654 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
4655 {
4656 tANI_U8 *value = command;
4657 tANI_U8 channel = 0;
4658 tANI_U8 dwellTime = 0;
4659 tANI_U8 bufLen = 0;
4660 tANI_U8 *buf = NULL;
4661 tSirMacAddr targetApBssid;
4662 eHalStatus status = eHAL_STATUS_SUCCESS;
4663 struct ieee80211_channel chan;
4664 tANI_U8 finalLen = 0;
4665 tANI_U8 *finalBuf = NULL;
4666 tANI_U8 temp = 0;
4667 u64 cookie;
4668 hdd_station_ctx_t *pHddStaCtx = NULL;
4669 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4670
4671 /* if not associated, no need to send action frame */
4672 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4673 {
4674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
4675 ret = -EINVAL;
4676 goto exit;
4677 }
4678
4679 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
4680 &dwellTime, &buf, &bufLen);
4681 if (eHAL_STATUS_SUCCESS != status)
4682 {
4683 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4684 "%s: Failed to parse send action frame data", __func__);
4685 ret = -EINVAL;
4686 goto exit;
4687 }
4688
4689 /* if the target bssid is different from currently associated AP,
4690 then no need to send action frame */
4691 if (VOS_TRUE != vos_mem_compare(targetApBssid,
4692 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
4693 {
4694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
4695 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004696 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004697 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004698 goto exit;
4699 }
4700
4701 /* if the channel number is different from operating channel then
4702 no need to send action frame */
4703 if (channel != pHddStaCtx->conn_info.operationChannel)
4704 {
4705 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4706 "%s: channel(%d) is different from operating channel(%d)",
4707 __func__, channel, pHddStaCtx->conn_info.operationChannel);
4708 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004709 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004710 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004711 goto exit;
4712 }
4713 chan.center_freq = sme_ChnToFreq(channel);
4714
4715 finalLen = bufLen + 24;
4716 finalBuf = vos_mem_malloc(finalLen);
4717 if (NULL == finalBuf)
4718 {
4719 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
4720 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07004721 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004722 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004723 goto exit;
4724 }
4725 vos_mem_zero(finalBuf, finalLen);
4726
4727 /* Fill subtype */
4728 temp = SIR_MAC_MGMT_ACTION << 4;
4729 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
4730
4731 /* Fill type */
4732 temp = SIR_MAC_MGMT_FRAME;
4733 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
4734
4735 /* Fill destination address (bssid of the AP) */
4736 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
4737
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004738 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004739 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
4740
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004741 /* Fill BSSID (AP mac address) */
4742 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004743
4744 /* Fill received buffer from 24th address */
4745 vos_mem_copy(finalBuf + 24, buf, bufLen);
4746
Jeff Johnson11c33152013-04-16 17:52:40 -07004747 /* done with the parsed buffer */
4748 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004749 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004750
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304751#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
4752 params.chan = &chan;
4753 params.offchan = 0;
4754 params.wait = dwellTime;
4755 params.buf = finalBuf;
4756 params.len = finalLen;
4757 params.no_cck = 1;
4758 params.dont_wait_for_ack = 1;
4759 ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
4760#else
DARAM SUDHA39eede62014-02-12 11:16:40 +05304761 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07004762#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4763 &(pAdapter->wdev),
4764#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004765 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07004766#endif
4767 &chan, 0,
4768#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4769 NL80211_CHAN_HT20, 1,
4770#endif
4771 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004772 1, &cookie );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304773#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004774 vos_mem_free(finalBuf);
4775 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004776 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
4777 {
4778 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
4779 char extra[32];
4780 tANI_U8 len = 0;
4781
4782 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004783 len = scnprintf(extra, sizeof(extra), "%s %d",
4784 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304785 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4786 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
4787 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05304788 len = VOS_MIN(priv_data.total_len, len + 1);
4789 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004790 {
4791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4792 "%s: failed to copy data to user buffer", __func__);
4793 ret = -EFAULT;
4794 goto exit;
4795 }
4796 }
4797 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
4798 {
4799 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004800 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004801
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304802 ret = hdd_drv_cmd_validate(command, 18);
4803 if (ret)
4804 goto exit;
4805
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004806 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
4807 value = value + 19;
4808 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004809 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004810 if (ret < 0)
4811 {
4812 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004813 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004815 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004816 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4817 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4818 ret = -EINVAL;
4819 goto exit;
4820 }
4821
4822 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
4823 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
4824 {
4825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4826 "lfr mode value %d is out of range"
4827 " (Min: %d Max: %d)", maxTime,
4828 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4829 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4830 ret = -EINVAL;
4831 goto exit;
4832 }
4833
4834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4835 "%s: Received Command to change channel max time = %d", __func__, maxTime);
4836
4837 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
4838 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
4839 }
4840 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
4841 {
4842 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
4843 char extra[32];
4844 tANI_U8 len = 0;
4845
4846 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004847 len = scnprintf(extra, sizeof(extra), "%s %d",
4848 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05304849 len = VOS_MIN(priv_data.total_len, len + 1);
4850 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004851 {
4852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4853 "%s: failed to copy data to user buffer", __func__);
4854 ret = -EFAULT;
4855 goto exit;
4856 }
4857 }
4858 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
4859 {
4860 tANI_U8 *value = command;
4861 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
4862
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304863 ret = hdd_drv_cmd_validate(command, 15);
4864 if (ret)
4865 goto exit;
4866
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004867 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
4868 value = value + 16;
4869 /* Convert the value from ascii to integer */
4870 ret = kstrtou16(value, 10, &val);
4871 if (ret < 0)
4872 {
4873 /* If the input value is greater than max value of datatype, then also
4874 kstrtou16 fails */
4875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4876 "%s: kstrtou16 failed range [%d - %d]", __func__,
4877 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4878 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4879 ret = -EINVAL;
4880 goto exit;
4881 }
4882
4883 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
4884 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
4885 {
4886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4887 "scan home time value %d is out of range"
4888 " (Min: %d Max: %d)", val,
4889 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4890 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4891 ret = -EINVAL;
4892 goto exit;
4893 }
4894
4895 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4896 "%s: Received Command to change scan home time = %d", __func__, val);
4897
4898 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
4899 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
4900 }
4901 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
4902 {
4903 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
4904 char extra[32];
4905 tANI_U8 len = 0;
4906
4907 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004908 len = scnprintf(extra, sizeof(extra), "%s %d",
4909 "GETSCANHOMETIME", val);
Ratheesh S P728d7c62015-07-16 15:38:58 +05304910 len = VOS_MIN(priv_data.total_len, len + 1);
4911 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004912 {
4913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4914 "%s: failed to copy data to user buffer", __func__);
4915 ret = -EFAULT;
4916 goto exit;
4917 }
4918 }
4919 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
4920 {
4921 tANI_U8 *value = command;
4922 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
4923
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304924 ret = hdd_drv_cmd_validate(command, 16);
4925 if (ret)
4926 goto exit;
4927
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004928 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
4929 value = value + 17;
4930 /* Convert the value from ascii to integer */
4931 ret = kstrtou8(value, 10, &val);
4932 if (ret < 0)
4933 {
4934 /* If the input value is greater than max value of datatype, then also
4935 kstrtou8 fails */
4936 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4937 "%s: kstrtou8 failed range [%d - %d]", __func__,
4938 CFG_ROAM_INTRA_BAND_MIN,
4939 CFG_ROAM_INTRA_BAND_MAX);
4940 ret = -EINVAL;
4941 goto exit;
4942 }
4943
4944 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
4945 (val > CFG_ROAM_INTRA_BAND_MAX))
4946 {
4947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4948 "intra band mode value %d is out of range"
4949 " (Min: %d Max: %d)", val,
4950 CFG_ROAM_INTRA_BAND_MIN,
4951 CFG_ROAM_INTRA_BAND_MAX);
4952 ret = -EINVAL;
4953 goto exit;
4954 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4956 "%s: Received Command to change intra band = %d", __func__, val);
4957
4958 pHddCtx->cfg_ini->nRoamIntraBand = val;
4959 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
4960 }
4961 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
4962 {
4963 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
4964 char extra[32];
4965 tANI_U8 len = 0;
4966
4967 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004968 len = scnprintf(extra, sizeof(extra), "%s %d",
4969 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +05304970 len = VOS_MIN(priv_data.total_len, len + 1);
4971 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004972 {
4973 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4974 "%s: failed to copy data to user buffer", __func__);
4975 ret = -EFAULT;
4976 goto exit;
4977 }
4978 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004979 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
4980 {
4981 tANI_U8 *value = command;
4982 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
4983
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304984 ret = hdd_drv_cmd_validate(command, 14);
4985 if (ret)
4986 goto exit;
4987
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004988 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
4989 value = value + 15;
4990 /* Convert the value from ascii to integer */
4991 ret = kstrtou8(value, 10, &nProbes);
4992 if (ret < 0)
4993 {
4994 /* If the input value is greater than max value of datatype, then also
4995 kstrtou8 fails */
4996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4997 "%s: kstrtou8 failed range [%d - %d]", __func__,
4998 CFG_ROAM_SCAN_N_PROBES_MIN,
4999 CFG_ROAM_SCAN_N_PROBES_MAX);
5000 ret = -EINVAL;
5001 goto exit;
5002 }
5003
5004 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
5005 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
5006 {
5007 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5008 "NProbes value %d is out of range"
5009 " (Min: %d Max: %d)", nProbes,
5010 CFG_ROAM_SCAN_N_PROBES_MIN,
5011 CFG_ROAM_SCAN_N_PROBES_MAX);
5012 ret = -EINVAL;
5013 goto exit;
5014 }
5015
5016 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5017 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
5018
5019 pHddCtx->cfg_ini->nProbes = nProbes;
5020 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
5021 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305022 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005023 {
5024 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
5025 char extra[32];
5026 tANI_U8 len = 0;
5027
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005028 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri6da525d2015-08-07 13:55:54 +05305029 len = VOS_MIN(priv_data.total_len, len + 1);
5030 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5032 "%s: failed to copy data to user buffer", __func__);
5033 ret = -EFAULT;
5034 goto exit;
5035 }
5036 }
5037 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
5038 {
5039 tANI_U8 *value = command;
5040 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
5041
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305042 ret = hdd_drv_cmd_validate(command, 19);
5043 if (ret)
5044 goto exit;
5045
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005046 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
5047 /* input value is in units of msec */
5048 value = value + 20;
5049 /* Convert the value from ascii to integer */
5050 ret = kstrtou16(value, 10, &homeAwayTime);
5051 if (ret < 0)
5052 {
5053 /* If the input value is greater than max value of datatype, then also
5054 kstrtou8 fails */
5055 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5056 "%s: kstrtou8 failed range [%d - %d]", __func__,
5057 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
5058 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
5059 ret = -EINVAL;
5060 goto exit;
5061 }
5062
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005063 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
5064 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
5065 {
5066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5067 "homeAwayTime value %d is out of range"
5068 " (Min: %d Max: %d)", homeAwayTime,
5069 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
5070 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
5071 ret = -EINVAL;
5072 goto exit;
5073 }
5074
5075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5076 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07005077 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
5078 {
5079 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
5080 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
5081 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005082 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305083 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005084 {
5085 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
5086 char extra[32];
5087 tANI_U8 len = 0;
5088
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005089 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri51a5ad12015-08-07 14:06:37 +05305090 len = VOS_MIN(priv_data.total_len, len + 1);
5091 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005092 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5093 "%s: failed to copy data to user buffer", __func__);
5094 ret = -EFAULT;
5095 goto exit;
5096 }
5097 }
5098 else if (strncmp(command, "REASSOC", 7) == 0)
5099 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305100 ret = hdd_drv_cmd_validate(command, 7);
5101 if (ret)
5102 goto exit;
5103
5104 ret = hdd_parse_reassoc(pAdapter, command, priv_data.total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05305105 if (!ret)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005106 goto exit;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005107 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005108 else if (strncmp(command, "SETWESMODE", 10) == 0)
5109 {
5110 tANI_U8 *value = command;
5111 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
5112
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305113 ret = hdd_drv_cmd_validate(command, 10);
5114 if (ret)
5115 goto exit;
5116
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005117 /* Move pointer to ahead of SETWESMODE<delimiter> */
5118 value = value + 11;
5119 /* Convert the value from ascii to integer */
5120 ret = kstrtou8(value, 10, &wesMode);
5121 if (ret < 0)
5122 {
5123 /* If the input value is greater than max value of datatype, then also
5124 kstrtou8 fails */
5125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5126 "%s: kstrtou8 failed range [%d - %d]", __func__,
5127 CFG_ENABLE_WES_MODE_NAME_MIN,
5128 CFG_ENABLE_WES_MODE_NAME_MAX);
5129 ret = -EINVAL;
5130 goto exit;
5131 }
5132
5133 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
5134 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
5135 {
5136 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5137 "WES Mode value %d is out of range"
5138 " (Min: %d Max: %d)", wesMode,
5139 CFG_ENABLE_WES_MODE_NAME_MIN,
5140 CFG_ENABLE_WES_MODE_NAME_MAX);
5141 ret = -EINVAL;
5142 goto exit;
5143 }
5144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5145 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
5146
5147 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
5148 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
5149 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305150 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005151 {
5152 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
5153 char extra[32];
5154 tANI_U8 len = 0;
5155
Arif Hussain826d9412013-11-12 16:44:54 -08005156 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05305157 len = VOS_MIN(priv_data.total_len, len + 1);
5158 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005159 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5160 "%s: failed to copy data to user buffer", __func__);
5161 ret = -EFAULT;
5162 goto exit;
5163 }
5164 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005165#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005166#ifdef FEATURE_WLAN_LFR
5167 else if (strncmp(command, "SETFASTROAM", 11) == 0)
5168 {
5169 tANI_U8 *value = command;
5170 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
5171
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05305172 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
5173 hddLog(LOGE,
5174 FL("Roaming is always disabled in STA + MON concurrency"));
5175 ret = -EINVAL;
5176 goto exit;
5177 }
5178
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305179 ret = hdd_drv_cmd_validate(command, 11);
5180 if (ret)
5181 goto exit;
5182
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005183 /* Move pointer to ahead of SETFASTROAM<delimiter> */
5184 value = value + 12;
5185 /* Convert the value from ascii to integer */
5186 ret = kstrtou8(value, 10, &lfrMode);
5187 if (ret < 0)
5188 {
5189 /* If the input value is greater than max value of datatype, then also
5190 kstrtou8 fails */
5191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5192 "%s: kstrtou8 failed range [%d - %d]", __func__,
5193 CFG_LFR_FEATURE_ENABLED_MIN,
5194 CFG_LFR_FEATURE_ENABLED_MAX);
5195 ret = -EINVAL;
5196 goto exit;
5197 }
5198
5199 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
5200 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
5201 {
5202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5203 "lfr mode value %d is out of range"
5204 " (Min: %d Max: %d)", lfrMode,
5205 CFG_LFR_FEATURE_ENABLED_MIN,
5206 CFG_LFR_FEATURE_ENABLED_MAX);
5207 ret = -EINVAL;
5208 goto exit;
5209 }
5210
5211 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5212 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
5213
5214 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
5215 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
5216 }
5217#endif
5218#ifdef WLAN_FEATURE_VOWIFI_11R
5219 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
5220 {
5221 tANI_U8 *value = command;
5222 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
5223
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305224 ret = hdd_drv_cmd_validate(command, 17);
5225 if (ret)
5226 goto exit;
5227
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005228 /* Move pointer to ahead of SETFASTROAM<delimiter> */
5229 value = value + 18;
5230 /* Convert the value from ascii to integer */
5231 ret = kstrtou8(value, 10, &ft);
5232 if (ret < 0)
5233 {
5234 /* If the input value is greater than max value of datatype, then also
5235 kstrtou8 fails */
5236 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5237 "%s: kstrtou8 failed range [%d - %d]", __func__,
5238 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
5239 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
5240 ret = -EINVAL;
5241 goto exit;
5242 }
5243
5244 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
5245 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
5246 {
5247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5248 "ft mode value %d is out of range"
5249 " (Min: %d Max: %d)", ft,
5250 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
5251 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
5252 ret = -EINVAL;
5253 goto exit;
5254 }
5255
5256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5257 "%s: Received Command to change ft mode = %d", __func__, ft);
5258
5259 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
5260 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
5261 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305262 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
5263 {
5264 tANI_U8 *value = command;
5265 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305266
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305267 ret = hdd_drv_cmd_validate(command, 14);
5268 if (ret)
5269 goto exit;
5270
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305271 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
5272 value = value + 15;
5273 /* Convert the value from ascii to integer */
5274 ret = kstrtou8(value, 10, &dfsScanMode);
5275 if (ret < 0)
5276 {
5277 /* If the input value is greater than max value of
5278 datatype, then also kstrtou8 fails
5279 */
5280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5281 "%s: kstrtou8 failed range [%d - %d]", __func__,
5282 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
5283 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
5284 ret = -EINVAL;
5285 goto exit;
5286 }
5287
5288 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
5289 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
5290 {
5291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5292 "dfsScanMode value %d is out of range"
5293 " (Min: %d Max: %d)", dfsScanMode,
5294 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
5295 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
5296 ret = -EINVAL;
5297 goto exit;
5298 }
5299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5300 "%s: Received Command to Set DFS Scan Mode = %d",
5301 __func__, dfsScanMode);
5302
5303 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
5304 }
5305 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
5306 {
5307 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
5308 char extra[32];
5309 tANI_U8 len = 0;
5310
5311 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05305312 len = VOS_MIN(priv_data.total_len, len + 1);
5313 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305314 {
5315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5316 "%s: failed to copy data to user buffer", __func__);
5317 ret = -EFAULT;
5318 goto exit;
5319 }
5320 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305321 else if (strncmp(command, "FASTREASSOC", 11) == 0)
5322 {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05305323 ret = wlan_hdd_handle_fastreassoc(pAdapter, command);
5324 if (!ret)
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305325 goto exit;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305326 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005327#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005328#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005329 else if (strncmp(command, "SETCCXMODE", 10) == 0)
5330 {
5331 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005332 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005333
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305334 ret = hdd_drv_cmd_validate(command, 10);
5335 if (ret)
5336 goto exit;
5337
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005338 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005339 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005340 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005341 hdd_is_okc_mode_enabled(pHddCtx) &&
5342 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
5343 {
5344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005345 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005346 " hence this operation is not permitted!", __func__);
5347 ret = -EPERM;
5348 goto exit;
5349 }
5350
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005351 /* Move pointer to ahead of SETCCXMODE<delimiter> */
5352 value = value + 11;
5353 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005354 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005355 if (ret < 0)
5356 {
5357 /* If the input value is greater than max value of datatype, then also
5358 kstrtou8 fails */
5359 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5360 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005361 CFG_ESE_FEATURE_ENABLED_MIN,
5362 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005363 ret = -EINVAL;
5364 goto exit;
5365 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005366 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
5367 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005368 {
5369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005370 "Ese mode value %d is out of range"
5371 " (Min: %d Max: %d)", eseMode,
5372 CFG_ESE_FEATURE_ENABLED_MIN,
5373 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005374 ret = -EINVAL;
5375 goto exit;
5376 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005377 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005378 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005379
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005380 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
5381 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005382 }
5383#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005384 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
5385 {
5386 tANI_U8 *value = command;
5387 tANI_BOOLEAN roamScanControl = 0;
5388
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305389 ret = hdd_drv_cmd_validate(command, 18);
5390 if (ret)
5391 goto exit;
5392
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005393 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
5394 value = value + 19;
5395 /* Convert the value from ascii to integer */
5396 ret = kstrtou8(value, 10, &roamScanControl);
5397 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 ", __func__);
5403 ret = -EINVAL;
5404 goto exit;
5405 }
5406
5407 if (0 != roamScanControl)
5408 {
5409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5410 "roam scan control invalid value = %d",
5411 roamScanControl);
5412 ret = -EINVAL;
5413 goto exit;
5414 }
5415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5416 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
5417
5418 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
5419 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005420#ifdef FEATURE_WLAN_OKC
5421 else if (strncmp(command, "SETOKCMODE", 10) == 0)
5422 {
5423 tANI_U8 *value = command;
5424 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
5425
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305426 ret = hdd_drv_cmd_validate(command, 10);
5427 if (ret)
5428 goto exit;
5429
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005430 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005431 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005432 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005433 hdd_is_okc_mode_enabled(pHddCtx) &&
5434 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
5435 {
5436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005437 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005438 " hence this operation is not permitted!", __func__);
5439 ret = -EPERM;
5440 goto exit;
5441 }
5442
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005443 /* Move pointer to ahead of SETOKCMODE<delimiter> */
5444 value = value + 11;
5445 /* Convert the value from ascii to integer */
5446 ret = kstrtou8(value, 10, &okcMode);
5447 if (ret < 0)
5448 {
5449 /* If the input value is greater than max value of datatype, then also
5450 kstrtou8 fails */
5451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5452 "%s: kstrtou8 failed range [%d - %d]", __func__,
5453 CFG_OKC_FEATURE_ENABLED_MIN,
5454 CFG_OKC_FEATURE_ENABLED_MAX);
5455 ret = -EINVAL;
5456 goto exit;
5457 }
5458
5459 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
5460 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
5461 {
5462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5463 "Okc mode value %d is out of range"
5464 " (Min: %d Max: %d)", okcMode,
5465 CFG_OKC_FEATURE_ENABLED_MIN,
5466 CFG_OKC_FEATURE_ENABLED_MAX);
5467 ret = -EINVAL;
5468 goto exit;
5469 }
5470
5471 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5472 "%s: Received Command to change okc mode = %d", __func__, okcMode);
5473
5474 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
5475 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005476#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305477 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005478 {
5479 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
5480 char extra[32];
5481 tANI_U8 len = 0;
5482
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005483 len = scnprintf(extra, sizeof(extra), "%s %d",
5484 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05305485 len = VOS_MIN(priv_data.total_len, len + 1);
5486 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5488 "%s: failed to copy data to user buffer", __func__);
5489 ret = -EFAULT;
5490 goto exit;
5491 }
5492 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05305493#ifdef WLAN_FEATURE_PACKET_FILTERING
5494 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
5495 {
5496 tANI_U8 filterType = 0;
5497 tANI_U8 *value = command;
5498
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305499 ret = hdd_drv_cmd_validate(command, 21);
5500 if (ret)
5501 goto exit;
5502
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05305503 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
5504 value = value + 22;
5505
5506 /* Convert the value from ascii to integer */
5507 ret = kstrtou8(value, 10, &filterType);
5508 if (ret < 0)
5509 {
5510 /* If the input value is greater than max value of datatype,
5511 * then also kstrtou8 fails
5512 */
5513 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5514 "%s: kstrtou8 failed range ", __func__);
5515 ret = -EINVAL;
5516 goto exit;
5517 }
5518
5519 if (filterType != 0 && filterType != 1)
5520 {
5521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5522 "%s: Accepted Values are 0 and 1 ", __func__);
5523 ret = -EINVAL;
5524 goto exit;
5525 }
5526 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
5527 pAdapter->sessionId);
5528 }
5529#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305530 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
5531 {
Kiet Lamad161252014-07-22 11:23:32 -07005532 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05305533 int ret;
5534
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305535 ret = hdd_drv_cmd_validate(command, 10);
5536 if (ret)
5537 goto exit;
5538
Kiet Lamad161252014-07-22 11:23:32 -07005539 dhcpPhase = command + 11;
5540 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305541 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05305542 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07005543 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05305544
5545 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07005546
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05305547 ret = wlan_hdd_scan_abort(pAdapter);
5548 if (ret < 0)
5549 {
5550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5551 FL("failed to abort existing scan %d"), ret);
5552 }
5553
Kiet Lamad161252014-07-22 11:23:32 -07005554 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
5555 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305556 }
Kiet Lamad161252014-07-22 11:23:32 -07005557 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305558 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05305559 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07005560 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05305561
5562 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07005563
5564 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
5565 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305566 }
5567 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005568 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
5569 {
Abhishek Singh58749d62016-02-03 15:27:20 +05305570 hddLog(LOG1,
5571 FL("making default scan to ACTIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05305572 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005573 }
5574 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
5575 {
Abhishek Singh58749d62016-02-03 15:27:20 +05305576 hddLog(LOG1,
5577 FL("making default scan to PASSIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05305578 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005579 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305580 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
5581 {
5582 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5583 char extra[32];
5584 tANI_U8 len = 0;
5585
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05305586 memset(extra, 0, sizeof(extra));
5587 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05305588 len = VOS_MIN(priv_data.total_len, len + 1);
5589 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305590 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5591 "%s: failed to copy data to user buffer", __func__);
5592 ret = -EFAULT;
5593 goto exit;
5594 }
5595 ret = len;
5596 }
5597 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
5598 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05305599 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305600 }
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05305601 else if (strncmp(command, "BTCGETDWELLTIME", 15) == 0)
5602 {
5603 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5604 char extra[32];
5605 tANI_U8 len = 0;
5606
5607 if (hdd_drv_cmd_validate(command, 15)) {
5608 hddLog(LOGE, FL("Invalid driver command"));
5609 return -EINVAL;
5610 }
5611
5612 memset(extra, 0, sizeof(extra));
5613 ret = hdd_btc_get_dwell_time(pCfg, command, extra,
5614 sizeof(extra), &len);
5615 len = VOS_MIN(priv_data.total_len, len + 1);
5616 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
5617 hddLog(LOGE, FL("Failed to copy data to user buffer"));
5618 ret = -EFAULT;
5619 goto exit;
5620 }
5621 ret = len;
5622 }
5623 else if (strncmp(command, "BTCSETDWELLTIME", 15) == 0)
5624 {
5625 if (hdd_drv_cmd_validate(command, 15)) {
5626 hddLog(LOGE, FL("Invalid driver command"));
5627 return -EINVAL;
5628 }
5629 ret = hdd_btc_set_dwell_time(pAdapter, command);
5630 }
5631#ifdef WLAN_AP_STA_CONCURRENCY
5632 else if (strncmp(command, "CONCGETDWELLTIME", 16) == 0)
5633 {
5634 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5635 char extra[32];
5636 tANI_U8 len = 0;
5637
5638 if (hdd_drv_cmd_validate(command, 16)) {
5639 hddLog(LOGE, FL("Invalid driver command"));
5640 return -EINVAL;
5641 }
5642
5643 memset(extra, 0, sizeof(extra));
5644 ret = hdd_conc_get_dwell_time(pCfg, command, extra,
5645 sizeof(extra), &len);
5646 len = VOS_MIN(priv_data.total_len, len + 1);
5647 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
5648 hddLog(LOGE, FL("Failed to copy data to user buffer"));
5649 ret = -EFAULT;
5650 goto exit;
5651 }
5652 ret = len;
5653 }
5654 else if (strncmp(command, "CONCSETDWELLTIME", 16) == 0)
5655 {
5656 if (hdd_drv_cmd_validate(command, 16)) {
5657 hddLog(LOGE, FL("Invalid driver command"));
5658 return -EINVAL;
5659 }
5660 ret = hdd_conc_set_dwell_time(pAdapter, command);
5661 }
5662#endif
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005663 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
5664 {
5665 tANI_U8 filterType = 0;
5666 tANI_U8 *value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305667
5668 ret = hdd_drv_cmd_validate(command, 8);
5669 if (ret)
5670 goto exit;
5671
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005672 value = command + 9;
5673
5674 /* Convert the value from ascii to integer */
5675 ret = kstrtou8(value, 10, &filterType);
5676 if (ret < 0)
5677 {
5678 /* If the input value is greater than max value of datatype,
5679 * then also kstrtou8 fails
5680 */
5681 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5682 "%s: kstrtou8 failed range ", __func__);
5683 ret = -EINVAL;
5684 goto exit;
5685 }
5686 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
5687 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
5688 {
5689 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5690 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
5691 " 2-Sink ", __func__);
5692 ret = -EINVAL;
5693 goto exit;
5694 }
5695 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
5696 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05305697 pScanInfo = &pHddCtx->scan_info;
5698 if (filterType && pScanInfo != NULL &&
5699 pHddCtx->scan_info.mScanPending)
5700 {
5701 /*Miracast Session started. Abort Scan */
5702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5703 "%s, Aborting Scan For Miracast",__func__);
5704 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
5705 eCSR_SCAN_ABORT_DEFAULT);
5706 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005707 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05305708 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005709 }
Leo Chang614d2072013-08-22 14:59:44 -07005710 else if (strncmp(command, "SETMCRATE", 9) == 0)
5711 {
Leo Chang614d2072013-08-22 14:59:44 -07005712 tANI_U8 *value = command;
5713 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07005714 tSirRateUpdateInd *rateUpdate;
5715 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07005716
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305717 ret = hdd_drv_cmd_validate(command, 9);
5718 if (ret)
5719 goto exit;
5720
Leo Chang614d2072013-08-22 14:59:44 -07005721 /* Only valid for SAP mode */
5722 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
5723 {
5724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5725 "%s: SAP mode is not running", __func__);
5726 ret = -EFAULT;
5727 goto exit;
5728 }
5729
5730 /* Move pointer to ahead of SETMCRATE<delimiter> */
5731 /* input value is in units of hundred kbps */
5732 value = value + 10;
5733 /* Convert the value from ascii to integer, decimal base */
5734 ret = kstrtouint(value, 10, &targetRate);
5735
Leo Chang1f98cbd2013-10-17 15:03:52 -07005736 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
5737 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07005738 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07005739 hddLog(VOS_TRACE_LEVEL_ERROR,
5740 "%s: SETMCRATE indication alloc fail", __func__);
5741 ret = -EFAULT;
5742 goto exit;
5743 }
5744 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
5745
5746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5747 "MC Target rate %d", targetRate);
5748 /* Ignore unicast */
5749 rateUpdate->ucastDataRate = -1;
5750 rateUpdate->mcastDataRate24GHz = targetRate;
5751 rateUpdate->mcastDataRate5GHz = targetRate;
5752 rateUpdate->mcastDataRate24GHzTxFlag = 0;
5753 rateUpdate->mcastDataRate5GHzTxFlag = 0;
5754 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
5755 if (eHAL_STATUS_SUCCESS != status)
5756 {
5757 hddLog(VOS_TRACE_LEVEL_ERROR,
5758 "%s: SET_MC_RATE failed", __func__);
5759 vos_mem_free(rateUpdate);
5760 ret = -EFAULT;
5761 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07005762 }
5763 }
jge35567202017-06-21 16:39:38 +08005764 else if (strncmp(command, "MAXTXPOWER", 10) == 0)
5765 {
5766 int status;
5767 int txPower;
5768 eHalStatus smeStatus;
5769 tANI_U8 *value = command;
5770 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5771 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5772
5773 status = hdd_parse_setmaxtxpower_command(value, &txPower);
5774 if (status)
5775 {
5776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5777 "Invalid MAXTXPOWER command ");
5778 ret = -EINVAL;
5779 goto exit;
5780 }
5781
5782 hddLog(VOS_TRACE_LEVEL_INFO, "max tx power %d selfMac: "
5783 MAC_ADDRESS_STR " bssId: " MAC_ADDRESS_STR " ",
5784 txPower, MAC_ADDR_ARRAY(selfMac),
5785 MAC_ADDR_ARRAY(bssid));
5786 smeStatus = sme_SetMaxTxPower((tHalHandle)(pHddCtx->hHal),
5787 bssid, selfMac, txPower) ;
5788 if( smeStatus != eHAL_STATUS_SUCCESS )
5789 {
5790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:Set max tx power failed",
5791 __func__);
5792 ret = -EINVAL;
5793 goto exit;
5794 }
5795
5796 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Set max tx power success",
5797 __func__);
5798 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305799#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08005800 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05305801 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08005802 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05305803 }
5804#endif
Abhishek Singh00b71972016-01-07 10:51:04 +05305805#ifdef WLAN_FEATURE_RMC
5806 else if ((strncasecmp(command, "SETIBSSBEACONOUIDATA", 20) == 0) &&
5807 (WLAN_HDD_IBSS == pAdapter->device_mode))
5808 {
5809 int i = 0;
5810 tANI_U8 *ibss_ie;
5811 tANI_U32 command_len;
5812 tANI_U8 *value = command;
5813 tHalHandle hHal = pHddCtx->hHal;
5814 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5815 tANI_U32 ibss_ie_length;
5816 tANI_U32 len, present;
5817 tANI_U8 *addIE;
5818 tANI_U8 *addIEData;
5819
5820 hddLog(LOG1,
5821 FL(" received command %s"),((char *) value));
5822 /* validate argument of command */
5823 if (strlen(value) <= 21)
5824 {
5825 hddLog(LOGE,
5826 FL("No arguements in command length %zu"), strlen(value));
5827 ret = -EFAULT;
5828 goto exit;
5829 }
5830
5831 /* moving to arguments of commands */
5832 value = value + 21;
5833 command_len = strlen(value);
5834
5835 /* oui_data can't be less than 3 bytes */
5836 if (command_len <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH))
5837 {
5838 hddLog(LOGE,
5839 FL("Invalid SETIBSSBEACONOUIDATA command length %d"),
5840 command_len);
5841 ret = -EFAULT;
5842 goto exit;
5843 }
5844 ibss_ie = vos_mem_malloc(command_len);
5845 if (!ibss_ie) {
5846 hddLog(LOGE,
5847 FL("Could not allocate memory for command length %d"),
5848 command_len);
5849 ret = -ENOMEM;
5850 goto exit;
5851 }
5852 vos_mem_zero(ibss_ie, command_len);
5853
5854 ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie,
5855 command_len);
5856 if (ibss_ie_length < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
5857 hddLog(LOGE, FL("Could not parse command %s return length %d"),
5858 value, ibss_ie_length);
5859 ret = -EFAULT;
5860 vos_mem_free(ibss_ie);
5861 goto exit;
5862 }
5863
5864 hddLog(LOG1, FL("ibss_ie length %d ibss_ie:"), ibss_ie_length);
5865 while (i < ibss_ie_length)
5866 hddLog(LOG1, FL("0x%x"), ibss_ie[i++]);
5867
5868 /* Populate Vendor IE in Beacon */
5869 if ((ccmCfgGetInt(hHal,
5870 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
5871 &present)) != eHAL_STATUS_SUCCESS)
5872 {
5873 hddLog(LOGE,
5874 FL("unable to ftch WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
5875 ret = -EFAULT;
5876 vos_mem_free(ibss_ie);
5877 goto exit;
5878 }
5879
5880 addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5881 if (!addIE) {
5882 hddLog(LOGE,
5883 FL("Could not allocate memory for command length %d"),
5884 command_len);
5885 vos_mem_free(ibss_ie);
5886 ret = -ENOMEM;
5887 goto exit;
5888 }
5889 vos_mem_zero(addIE, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5890
5891 if (present)
5892 {
5893 if ((wlan_cfgGetStrLen(pMac,
5894 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &len)) != eSIR_SUCCESS)
5895 {
5896 hddLog(LOGE,
5897 FL("unable to fetch WNI_CFG_PROBE_RSP_BCN_ADDNIE_LEN"));
5898 ret = -EFAULT;
5899 vos_mem_free(ibss_ie);
5900 vos_mem_free(addIE);
5901 goto exit;
5902 }
5903
5904 if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
5905 ((len + ibss_ie_length) <=
5906 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN))
5907 {
5908 if ((ccmCfgGetStr(hHal,
5909 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, &len))
5910 != eHAL_STATUS_SUCCESS)
5911 {
5912 hddLog(LOGE,
5913 FL("unable to fetch WNI_PROBE_RSP_BCN_ADDNIE_DATA"));
5914 ret = -EFAULT;
5915 vos_mem_free(ibss_ie);
5916 vos_mem_free(addIE);
5917 goto exit;
5918 }
5919 else
5920 {
5921 /* Curruntly only WPA IE is added before Vendor IE
5922 * so we can blindly place the Vendor IE after WPA
5923 * IE. If no WPA IE found replace all with Vendor IE.
5924 */
5925 len = hdd_find_ibss_wpa_ie_pos(addIE, len);
5926 }
5927 }
5928 else
5929 {
5930 hddLog(LOGE,
5931 FL("IE len exceed limit len %d,ibss_ie_length %d "),
5932 len, ibss_ie_length);
5933 ret = -EFAULT;
5934 vos_mem_free(addIE);
5935 vos_mem_free(ibss_ie);
5936 goto exit;
5937 }
5938 }
5939 else {
5940 len = 0;
5941 }
5942
5943 vos_mem_copy (addIE + len , ibss_ie, ibss_ie_length);
5944 len += ibss_ie_length;
5945
5946 if (ccmCfgSetStr(hHal,
5947 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, len, NULL,
5948 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
5949 {
5950 hddLog(LOGE,
5951 FL("unable to set WNI_CFG_PRBE_RSP_BCN_ADDNIE_DATA"));
5952 ret = -EFAULT;
5953 vos_mem_free(ibss_ie);
5954 vos_mem_free(addIE);
5955 goto exit;
5956 }
5957 vos_mem_free(addIE);
5958 if (ccmCfgSetInt(hHal,
5959 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5960 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
5961 {
5962 hddLog(LOGE,
5963 FL("unble to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
5964 ret = -EFAULT;
5965 vos_mem_free(ibss_ie);
5966 goto exit;
5967 }
5968
5969 /* Populate Vendor IE in probe resp */
5970 if ((ccmCfgGetInt(hHal,
5971 WNI_CFG_PROBE_RSP_ADDNIE_FLAG,
5972 &present)) != eHAL_STATUS_SUCCESS)
5973 {
5974 hddLog(LOGE,
5975 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
5976 ret = -EFAULT;
5977 vos_mem_free(ibss_ie);
5978 goto exit;
5979 }
5980
5981 addIEData = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
5982 if (!addIEData) {
5983 hddLog(LOGE,
5984 FL("Could not allocate memory for command length %d"),
5985 command_len);
5986 vos_mem_free(ibss_ie);
5987 ret = -ENOMEM;
5988 goto exit;
5989 }
5990 vos_mem_zero(addIEData, WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
5991
5992 if (present) {
5993 if (eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
5994 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &len)) {
5995 hddLog(LOGE,
5996 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
5997 ret = -EFAULT;
5998 vos_mem_free(ibss_ie);
5999 vos_mem_free(addIEData);
6000 goto exit;
6001 }
6002 if (len < WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && len &&
6003 (ibss_ie_length + len) <=
6004 WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN) {
6005
6006 if ((ccmCfgGetStr(hHal,
6007 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, addIEData, &len))
6008 != eHAL_STATUS_SUCCESS) {
6009 hddLog(LOGE,
6010 FL("unable fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6011 ret = -EFAULT;
6012 vos_mem_free(ibss_ie);
6013 vos_mem_free(addIEData);
6014 goto exit;
6015 }
6016 else {
6017 /* Curruntly only WPA IE is added before Vendor IE
6018 * so we can blindly place the Vendor IE after WPA
6019 * IE. If no WPA IE found replace all with Vendor IE.
6020 */
6021 len = hdd_find_ibss_wpa_ie_pos(addIEData, len);
6022 }
6023 }
6024 else
6025 {
6026 hddLog(LOGE,
6027 FL("IE len exceed limit len %d,ibss_ie_length %d "),
6028 len, ibss_ie_length);
6029 ret = -EFAULT;
6030 vos_mem_free(addIEData);
6031 vos_mem_free(ibss_ie);
6032 goto exit;
6033 }
6034 } /* probe rsp ADD IE present */
6035 else {
6036 /* probe rsp add IE is not present */
6037 len = 0;
6038 }
6039
6040 vos_mem_copy(addIEData +len , ibss_ie, ibss_ie_length);
6041 len += ibss_ie_length;
6042
6043 vos_mem_free(ibss_ie);
6044
6045 if (ccmCfgSetStr(hHal,
6046 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6047 (tANI_U8*)(addIEData),
6048 len, NULL,
6049 eANI_BOOLEAN_FALSE)
6050 == eHAL_STATUS_FAILURE) {
6051 hddLog(LOGE,
6052 FL("unable to copy to WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6053 ret = -EFAULT;
6054 vos_mem_free(addIEData);
6055 goto exit;
6056 }
6057 vos_mem_free(addIEData);
6058 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6059 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6060 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6061 {
6062 hddLog(LOGE,
6063 FL("unable to copy WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
6064 ret = -EFAULT;
6065 goto exit;
6066 }
6067 }
6068 else if (strncasecmp(command, "SETRMCENABLE", 12) == 0)
6069 {
6070 tANI_U8 *value = command;
6071 tANI_U8 ucRmcEnable = 0;
6072 int status;
6073
6074 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6075 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6076 {
6077 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6078 "Received SETRMCENABLE command in invalid mode %d "
6079 "SETRMCENABLE command is only allowed in IBSS or SOFTAP mode",
6080 pAdapter->device_mode);
6081 ret = -EINVAL;
6082 goto exit;
6083 }
6084
6085 status = hdd_parse_setrmcenable_command(value, &ucRmcEnable);
6086 if (status)
6087 {
6088 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6089 "Invalid SETRMCENABLE command ");
6090 ret = -EINVAL;
6091 goto exit;
6092 }
6093
6094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6095 "%s: ucRmcEnable %d ", __func__, ucRmcEnable);
6096
6097 if (TRUE == ucRmcEnable)
6098 {
6099 status = sme_EnableRMC( (tHalHandle)(pHddCtx->hHal),
6100 pAdapter->sessionId );
6101 }
6102 else if(FALSE == ucRmcEnable)
6103 {
6104 status = sme_DisableRMC( (tHalHandle)(pHddCtx->hHal),
6105 pAdapter->sessionId );
6106 }
6107 else
6108 {
6109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6110 "Invalid SETRMCENABLE command %d", ucRmcEnable);
6111 ret = -EINVAL;
6112 goto exit;
6113 }
6114
6115 if (VOS_STATUS_SUCCESS != status)
6116 {
6117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6118 "%s: SETRMC %d failed status %d", __func__, ucRmcEnable,
6119 status);
6120 ret = -EINVAL;
6121 goto exit;
6122 }
6123 }
6124 else if (strncasecmp(command, "SETRMCACTIONPERIOD", 18) == 0)
6125 {
6126 tANI_U8 *value = command;
6127 tANI_U32 uActionPeriod = 0;
6128 int status;
6129
6130 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6131 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6132 {
6133 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6134 "Received SETRMC command in invalid mode %d "
6135 "SETRMC command is only allowed in IBSS or SOFTAP mode",
6136 pAdapter->device_mode);
6137 ret = -EINVAL;
6138 goto exit;
6139 }
6140
6141 status = hdd_parse_setrmcactionperiod_command(value, &uActionPeriod);
6142 if (status)
6143 {
6144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6145 "Invalid SETRMCACTIONPERIOD command ");
6146 ret = -EINVAL;
6147 goto exit;
6148 }
6149
6150 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6151 "%s: uActionPeriod %d ", __func__, uActionPeriod);
6152
6153 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
6154 uActionPeriod, NULL, eANI_BOOLEAN_FALSE))
6155 {
6156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6157 "%s: Could not set SETRMCACTIONPERIOD %d", __func__, uActionPeriod);
6158 ret = -EINVAL;
6159 goto exit;
6160 }
6161
6162 }
6163 else if (strncasecmp(command, "GETIBSSPEERINFOALL", 18) == 0)
6164 {
6165 /* Peer Info All Command */
6166 int status = eHAL_STATUS_SUCCESS;
6167 hdd_station_ctx_t *pHddStaCtx = NULL;
6168 char *extra = NULL;
6169 int idx = 0, length = 0;
6170 v_MACADDR_t *macAddr;
6171 v_U32_t txRateMbps = 0, numOfBytestoPrint = 0;
6172
6173 if (WLAN_HDD_IBSS == pAdapter->device_mode)
6174 {
6175 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6176 }
6177 else
6178 {
6179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6180 "%s: pAdapter is not valid for this device mode",
6181 __func__);
6182 ret = -EINVAL;
6183 goto exit;
6184 }
6185
6186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6187 "%s: Received GETIBSSPEERINFOALL Command", __func__);
6188
6189
6190 /* Handle the command */
6191 status = hdd_cfg80211_get_ibss_peer_info_all(pAdapter);
6192 if (VOS_STATUS_SUCCESS == status)
6193 {
6194 /* The variable extra needed to be allocated on the heap since
6195 * amount of memory required to copy the data for 32 devices
6196 * exceeds the size of 1024 bytes of default stack size. On
6197 * 64 bit devices, the default max stack size of 2048 bytes
6198 */
6199 extra = kmalloc(WLAN_MAX_BUF_SIZE, GFP_KERNEL);
6200
6201 if (NULL == extra)
6202 {
6203 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6204 "%s:kmalloc failed", __func__);
6205 ret = -EINVAL;
6206 goto exit;
6207 }
6208
6209 /* Copy number of stations */
6210 length = scnprintf( extra, WLAN_MAX_BUF_SIZE, "%d ",
6211 pHddStaCtx->ibss_peer_info.numIBSSPeers);
6212 numOfBytestoPrint = length;
6213 for (idx = 0; idx < pHddStaCtx->ibss_peer_info.numIBSSPeers; idx++)
6214 {
6215 macAddr =
6216 hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
6217 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
6218 if (NULL != macAddr)
6219 {
6220 txRateMbps =
6221 ((pHddStaCtx->ibss_peer_info.ibssPeerList[idx].txRate)*500*1000)/1000000;
6222
6223 length += scnprintf( (extra + length), WLAN_MAX_BUF_SIZE - length,
6224 "%02x:%02x:%02x:%02x:%02x:%02x %d %d ",
6225 macAddr->bytes[0], macAddr->bytes[1], macAddr->bytes[2],
6226 macAddr->bytes[3], macAddr->bytes[4], macAddr->bytes[5],
6227 (int)txRateMbps,
6228 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[idx].rssi);
6229 }
6230 else
6231 {
6232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6233 "%s: MAC ADDR is NULL for staIdx: %d", __func__,
6234 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
6235 }
6236
6237 /*
6238 * VOS_TRACE() macro has limitation of 512 bytes for the print
6239 * buffer. Hence printing the data in two chunks. The first chunk
6240 * will have the data for 16 devices and the second chunk will
6241 * have the rest.
6242 */
6243 if (idx < NUM_OF_STA_DATA_TO_PRINT)
6244 {
6245 numOfBytestoPrint = length;
6246 }
6247 }
6248
6249 /*
6250 * Copy the data back into buffer, if the data to copy is
6251 * morethan 512 bytes than we will split the data and do
6252 * it in two shots
6253 */
6254 if (copy_to_user(priv_data.buf, extra, numOfBytestoPrint))
6255 {
6256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6257 "%s: Copy into user data buffer failed ", __func__);
6258 ret = -EFAULT;
6259 kfree(extra);
6260 goto exit;
6261 }
6262 priv_data.buf[numOfBytestoPrint] = '\0';
6263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6264 "%s", priv_data.buf);
6265
6266 if (length > numOfBytestoPrint)
6267 {
6268 if (copy_to_user(priv_data.buf + numOfBytestoPrint,
6269 extra + numOfBytestoPrint,
6270 length - numOfBytestoPrint + 1))
6271 {
6272 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6273 "%s: Copy into user data buffer failed ", __func__);
6274 ret = -EFAULT;
6275 kfree(extra);
6276 goto exit;
6277 }
6278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6279 "%s", &priv_data.buf[numOfBytestoPrint]);
6280 }
6281
6282 /* Free temporary buffer */
6283 kfree(extra);
6284 }
6285
6286 else
6287 {
6288 /* Command failed, log error */
6289 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6290 "%s: GETIBSSPEERINFOALL command failed with status code %d",
6291 __func__, status);
6292 ret = -EINVAL;
6293 goto exit;
6294 }
6295 ret = 0;
6296 }
6297 else if(strncasecmp(command, "GETIBSSPEERINFO", 15) == 0)
6298 {
6299 /* Peer Info <Peer Addr> command */
6300 tANI_U8 *value = command;
6301 VOS_STATUS status;
6302 hdd_station_ctx_t *pHddStaCtx = NULL;
6303 char extra[128] = { 0 };
6304 v_U32_t length = 0;
6305 v_U8_t staIdx = 0;
6306 v_U32_t txRateMbps = 0;
6307 v_MACADDR_t peerMacAddr;
6308
6309 if (WLAN_HDD_IBSS == pAdapter->device_mode)
6310 {
6311 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6312 }
6313 else
6314 {
6315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6316 "%s: pAdapter is not valid for this device mode",
6317 __func__);
6318 ret = -EINVAL;
6319 goto exit;
6320 }
6321
6322 /* if there are no peers, no need to continue with the command */
6323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6324 "%s: Received GETIBSSPEERINFO Command", __func__);
6325
6326 if (eConnectionState_IbssConnected != pHddStaCtx->conn_info.connState)
6327 {
6328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6329 "%s:No IBSS Peers coalesced", __func__);
6330 ret = -EINVAL;
6331 goto exit;
6332 }
6333
6334 /* Parse the incoming command buffer */
6335 status = hdd_parse_get_ibss_peer_info(value, &peerMacAddr);
6336 if (VOS_STATUS_SUCCESS != status)
6337 {
6338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6339 "%s: Invalid GETIBSSPEERINFO command", __func__);
6340 ret = -EINVAL;
6341 goto exit;
6342 }
6343
6344 /* Get station index for the peer mac address */
6345 hdd_Ibss_GetStaId(pHddStaCtx, &peerMacAddr, &staIdx);
6346
6347 if (staIdx > HDD_MAX_NUM_IBSS_STA)
6348 {
6349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6350 "%s: Invalid StaIdx %d returned", __func__, staIdx);
6351 ret = -EINVAL;
6352 goto exit;
6353 }
6354
6355 /* Handle the command */
6356 status = hdd_cfg80211_get_ibss_peer_info(pAdapter, staIdx);
6357 if (VOS_STATUS_SUCCESS == status)
6358 {
6359 v_U32_t txRate = pHddStaCtx->ibss_peer_info.ibssPeerList[0].txRate;
6360 txRateMbps = (txRate * 500 * 1000)/1000000;
6361
6362 length = scnprintf( extra, sizeof(extra), "%d %d", (int)txRateMbps,
6363 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[0].rssi);
6364
6365 /* Copy the data back into buffer */
6366 if (copy_to_user(priv_data.buf, &extra, length+ 1))
6367 {
6368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6369 "%s: copy data to user buffer failed GETIBSSPEERINFO command",
6370 __func__);
6371 ret = -EFAULT;
6372 goto exit;
6373 }
6374 }
6375 else
6376 {
6377 /* Command failed, log error */
6378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6379 "%s: GETIBSSPEERINFO command failed with status code %d",
6380 __func__, status);
6381 ret = -EINVAL;
6382 goto exit;
6383 }
6384
6385 /* Success ! */
6386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6387 "%s", priv_data.buf);
6388 ret = 0;
6389 }
6390 else if (strncasecmp(command, "SETRMCTXRATE", 12) == 0)
6391 {
6392 tANI_U8 *value = command;
6393 tANI_U32 uRate = 0;
6394 tTxrateinfoflags txFlags = 0;
6395 tSirRateUpdateInd *rateUpdateParams;
6396 int status;
6397
6398 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6399 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6400 {
6401 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6402 "Received SETRMCTXRATE command in invalid mode %d "
6403 "SETRMC command is only allowed in IBSS or SOFTAP mode",
6404 pAdapter->device_mode);
6405 ret = -EINVAL;
6406 goto exit;
6407 }
6408
6409 status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags);
6410 if (status)
6411 {
6412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6413 "Invalid SETRMCTXRATE command ");
6414 ret = -EINVAL;
6415 goto exit;
6416 }
6417
6418 rateUpdateParams = vos_mem_malloc(sizeof(tSirRateUpdateInd));
6419 if (NULL == rateUpdateParams)
6420 {
6421 ret = -EINVAL;
6422 goto exit;
6423 }
6424
6425 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6426 "%s: uRate %d ", __func__, uRate);
6427
6428 vos_mem_zero(rateUpdateParams, sizeof(tSirRateUpdateInd ));
6429
6430 /* -1 implies ignore this param */
6431 rateUpdateParams->ucastDataRate = -1;
6432
6433 /*
6434 * Fill the user specifieed RMC rate param
6435 * and the derived tx flags.
6436 */
6437 rateUpdateParams->rmcDataRate = uRate;
6438 rateUpdateParams->rmcDataRateTxFlag = txFlags;
6439
6440 status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), rateUpdateParams);
6441 }
6442 else if (strncasecmp(command, "SETIBSSTXFAILEVENT", 18) == 0 )
6443 {
6444 char *value;
6445 tANI_U8 tx_fail_count = 0;
6446 tANI_U16 pid = 0;
6447
6448 value = command;
6449
6450 ret = hdd_ParseIBSSTXFailEventParams(value, &tx_fail_count, &pid);
6451
6452 if (0 != ret)
6453 {
6454 hddLog(VOS_TRACE_LEVEL_INFO,
6455 "%s: Failed to parse SETIBSSTXFAILEVENT arguments",
6456 __func__);
6457 goto exit;
6458 }
6459
6460 hddLog(VOS_TRACE_LEVEL_INFO, "%s: tx_fail_cnt=%hhu, pid=%hu",
6461 __func__, tx_fail_count, pid);
6462
6463 if (0 == tx_fail_count)
6464 {
6465 // Disable TX Fail Indication
6466 if (eHAL_STATUS_SUCCESS ==
6467 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
6468 tx_fail_count,
6469 NULL))
6470 {
6471 cesium_pid = 0;
6472 }
6473 else
6474 {
6475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6476 "%s: failed to disable TX Fail Event ", __func__);
6477 ret = -EINVAL;
6478 }
6479 }
6480 else
6481 {
6482 if (eHAL_STATUS_SUCCESS ==
6483 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
6484 tx_fail_count,
6485 (void*)hdd_tx_fail_ind_callback))
6486 {
6487 cesium_pid = pid;
6488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6489 "%s: Registered Cesium pid %u", __func__,
6490 cesium_pid);
6491 }
6492 else
6493 {
6494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6495 "%s: Failed to enable TX Fail Monitoring", __func__);
6496 ret = -EINVAL;
6497 }
6498 }
6499 }
6500
6501#endif /* WLAN_FEATURE_RMC */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006502#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006503 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
6504 {
6505 tANI_U8 *value = command;
6506 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
6507 tANI_U8 numChannels = 0;
6508 eHalStatus status = eHAL_STATUS_SUCCESS;
6509
6510 status = hdd_parse_channellist(value, ChannelList, &numChannels);
6511 if (eHAL_STATUS_SUCCESS != status)
6512 {
6513 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6514 "%s: Failed to parse channel list information", __func__);
6515 ret = -EINVAL;
6516 goto exit;
6517 }
6518
6519 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
6520 {
6521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6522 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
6523 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
6524 ret = -EINVAL;
6525 goto exit;
6526 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006527 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006528 ChannelList,
6529 numChannels);
6530 if (eHAL_STATUS_SUCCESS != status)
6531 {
6532 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6533 "%s: Failed to update channel list information", __func__);
6534 ret = -EINVAL;
6535 goto exit;
6536 }
6537 }
6538 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
6539 {
6540 tANI_U8 *value = command;
6541 char extra[128] = {0};
6542 int len = 0;
6543 tANI_U8 tid = 0;
6544 hdd_station_ctx_t *pHddStaCtx = NULL;
6545 tAniTrafStrmMetrics tsmMetrics;
6546 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6547
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306548 ret = hdd_drv_cmd_validate(command, 11);
6549 if (ret)
6550 goto exit;
6551
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006552 /* if not associated, return error */
6553 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6554 {
6555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
6556 ret = -EINVAL;
6557 goto exit;
6558 }
6559
6560 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
6561 value = value + 12;
6562 /* Convert the value from ascii to integer */
6563 ret = kstrtou8(value, 10, &tid);
6564 if (ret < 0)
6565 {
6566 /* If the input value is greater than max value of datatype, then also
6567 kstrtou8 fails */
6568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6569 "%s: kstrtou8 failed range [%d - %d]", __func__,
6570 TID_MIN_VALUE,
6571 TID_MAX_VALUE);
6572 ret = -EINVAL;
6573 goto exit;
6574 }
6575
6576 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
6577 {
6578 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6579 "tid value %d is out of range"
6580 " (Min: %d Max: %d)", tid,
6581 TID_MIN_VALUE,
6582 TID_MAX_VALUE);
6583 ret = -EINVAL;
6584 goto exit;
6585 }
6586
6587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6588 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
6589
6590 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
6591 {
6592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6593 "%s: failed to get tsm stats", __func__);
6594 ret = -EFAULT;
6595 goto exit;
6596 }
6597
6598 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6599 "UplinkPktQueueDly(%d)\n"
6600 "UplinkPktQueueDlyHist[0](%d)\n"
6601 "UplinkPktQueueDlyHist[1](%d)\n"
6602 "UplinkPktQueueDlyHist[2](%d)\n"
6603 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05306604 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006605 "UplinkPktLoss(%d)\n"
6606 "UplinkPktCount(%d)\n"
6607 "RoamingCount(%d)\n"
6608 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
6609 tsmMetrics.UplinkPktQueueDlyHist[0],
6610 tsmMetrics.UplinkPktQueueDlyHist[1],
6611 tsmMetrics.UplinkPktQueueDlyHist[2],
6612 tsmMetrics.UplinkPktQueueDlyHist[3],
6613 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
6614 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
6615
6616 /* Output TSM stats is of the format
6617 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
6618 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006619 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006620 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
6621 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
6622 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
6623 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
6624 tsmMetrics.RoamingDly);
6625
Ratnam Rachurid53009c2015-08-07 13:59:00 +05306626 len = VOS_MIN(priv_data.total_len, len + 1);
6627 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6629 "%s: failed to copy data to user buffer", __func__);
6630 ret = -EFAULT;
6631 goto exit;
6632 }
6633 }
6634 else if (strncmp(command, "SETCCKMIE", 9) == 0)
6635 {
6636 tANI_U8 *value = command;
6637 tANI_U8 *cckmIe = NULL;
6638 tANI_U8 cckmIeLen = 0;
6639 eHalStatus status = eHAL_STATUS_SUCCESS;
6640
6641 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
6642 if (eHAL_STATUS_SUCCESS != status)
6643 {
6644 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6645 "%s: Failed to parse cckm ie data", __func__);
6646 ret = -EINVAL;
6647 goto exit;
6648 }
6649
6650 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
6651 {
6652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6653 "%s: CCKM Ie input length is more than max[%d]", __func__,
6654 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006655 vos_mem_free(cckmIe);
6656 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006657 ret = -EINVAL;
6658 goto exit;
6659 }
6660 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006661 vos_mem_free(cckmIe);
6662 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006663 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006664 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
6665 {
6666 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006667 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006668 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07006669
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006670 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006671 if (eHAL_STATUS_SUCCESS != status)
6672 {
6673 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006674 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006675 ret = -EINVAL;
6676 goto exit;
6677 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07006678 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6679 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
6680 hdd_indicateEseBcnReportNoResults (pAdapter,
6681 eseBcnReq.bcnReq[0].measurementToken,
6682 0x02, //BIT(1) set for measurement done
6683 0); // no BSS
6684 goto exit;
6685 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006686
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006687 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
6688 if (eHAL_STATUS_SUCCESS != status)
6689 {
6690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6691 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
6692 ret = -EINVAL;
6693 goto exit;
6694 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006695 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006696#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05306697 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
6698 {
6699 eHalStatus status;
6700 char buf[32], len;
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306701 void *cookie;
6702 struct hdd_request *request;
6703 static const struct hdd_request_params params = {
6704 .priv_size = 0,
6705 .timeout_ms = WLAN_WAIT_TIME_STATS,
6706 };
c_hpothu92367912014-05-01 15:18:17 +05306707
6708 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6709
6710 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6711 {
6712 hddLog(VOS_TRACE_LEVEL_WARN,
6713 FL("GETBCNMISSRATE: STA is not in connected state"));
6714 ret = -1;
6715 goto exit;
6716 }
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306717 request = hdd_request_alloc(&params);
6718 if (!request) {
6719 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6720 ret = -ENOMEM;
6721 goto exit;
6722 }
6723 cookie = hdd_request_cookie(request);
c_hpothu92367912014-05-01 15:18:17 +05306724
6725 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
6726 pAdapter->sessionId,
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306727 (void *)get_bcn_miss_rate_cb,
6728 cookie);
c_hpothu92367912014-05-01 15:18:17 +05306729 if( eHAL_STATUS_SUCCESS != status)
6730 {
6731 hddLog(VOS_TRACE_LEVEL_INFO,
6732 FL("GETBCNMISSRATE: fail to post WDA cmd"));
6733 ret = -EINVAL;
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306734 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306735 }
6736
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306737 ret = hdd_request_wait_for_response(request);
6738 if(ret)
c_hpothu92367912014-05-01 15:18:17 +05306739 {
6740 hddLog(VOS_TRACE_LEVEL_ERROR,
6741 FL("failed to wait on bcnMissRateComp %d"), ret);
6742
c_hpothu92367912014-05-01 15:18:17 +05306743 ret = -EINVAL;
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306744 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306745 }
6746
6747 hddLog(VOS_TRACE_LEVEL_INFO,
6748 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
6749
6750 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
6751 if (copy_to_user(priv_data.buf, &buf, len + 1))
6752 {
6753 hddLog(VOS_TRACE_LEVEL_ERROR,
6754 "%s: failed to copy data to user buffer", __func__);
6755 ret = -EFAULT;
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306756 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306757 }
6758 ret = len;
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306759
6760free_bcn_miss_rate_req:
6761 hdd_request_put(request);
c_hpothu92367912014-05-01 15:18:17 +05306762 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306763#ifdef FEATURE_WLAN_TDLS
6764 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
6765 tANI_U8 *value = command;
6766 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306767
6768 ret = hdd_drv_cmd_validate(command, 26);
6769 if (ret)
6770 goto exit;
6771
Atul Mittal87ec2422014-09-24 13:12:50 +05306772 /* Move pointer to ahead of TDLSOFFCH*/
6773 value += 26;
c_manjeebbc40212015-12-08 13:52:59 +05306774 if (!(sscanf(value, "%d", &set_value))) {
6775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6776 FL("No input identified"));
6777 ret = -EINVAL;
6778 goto exit;
6779 }
6780
Atul Mittal87ec2422014-09-24 13:12:50 +05306781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6782 "%s: Tdls offchannel offset:%d",
6783 __func__, set_value);
6784 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
6785 if (ret < 0)
6786 {
6787 ret = -EINVAL;
6788 goto exit;
6789 }
6790
6791 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
6792 tANI_U8 *value = command;
6793 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306794
6795 ret = hdd_drv_cmd_validate(command, 18);
6796 if (ret)
6797 goto exit;
6798
Atul Mittal87ec2422014-09-24 13:12:50 +05306799 /* Move pointer to ahead of tdlsoffchnmode*/
6800 value += 18;
c_manjee82323892015-12-08 12:40:34 +05306801 ret = sscanf(value, "%d", &set_value);
6802 if (ret != 1) {
6803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6804 FL("No input identified"));
6805 ret = -EINVAL;
6806 goto exit;
6807 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6809 "%s: Tdls offchannel mode:%d",
6810 __func__, set_value);
6811 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
6812 if (ret < 0)
6813 {
6814 ret = -EINVAL;
6815 goto exit;
6816 }
6817 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
6818 tANI_U8 *value = command;
6819 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306820
6821 ret = hdd_drv_cmd_validate(command, 14);
6822 if (ret)
6823 goto exit;
6824
Atul Mittal87ec2422014-09-24 13:12:50 +05306825 /* Move pointer to ahead of TDLSOFFCH*/
6826 value += 14;
c_manjeef6ccaf52015-12-08 11:52:11 +05306827 ret = sscanf(value, "%d", &set_value);
6828 if (ret != 1) {
6829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6830 "Wrong value is given for hdd_set_tdls_offchannel");
6831 ret = -EINVAL;
6832 goto exit;
6833 }
6834
Atul Mittal87ec2422014-09-24 13:12:50 +05306835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6836 "%s: Tdls offchannel num: %d",
6837 __func__, set_value);
6838 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
6839 if (ret < 0)
6840 {
6841 ret = -EINVAL;
6842 goto exit;
6843 }
6844 }
6845#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05306846 else if (strncmp(command, "GETFWSTATS", 10) == 0)
6847 {
6848 eHalStatus status;
6849 char *buf = NULL;
6850 char len;
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306851 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp),
6852 *fw_stats_result;
Satyanarayana Dash72806012014-12-02 14:30:08 +05306853 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306854 int stats;
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306855 void *cookie;
6856 struct hdd_request *request;
6857 struct fw_stats_priv *priv;
6858 static const struct hdd_request_params params = {
6859 .priv_size = sizeof(*priv),
6860 .timeout_ms = WLAN_WAIT_TIME_STATS,
6861 };
Satyanarayana Dash72806012014-12-02 14:30:08 +05306862
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306863 ret = hdd_drv_cmd_validate(command, 10);
6864 if (ret)
6865 goto exit;
6866
6867 stats = *(ptr + 11) - '0';
Satyanarayana Dash72806012014-12-02 14:30:08 +05306868 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
6869 if (!IS_FEATURE_FW_STATS_ENABLE)
6870 {
6871 hddLog(VOS_TRACE_LEVEL_INFO,
6872 FL("Get Firmware stats feature not supported"));
6873 ret = -EINVAL;
6874 goto exit;
6875 }
6876
6877 if (FW_STATS_MAX <= stats || 0 >= stats)
6878 {
6879 hddLog(VOS_TRACE_LEVEL_INFO,
6880 FL(" stats %d not supported"),stats);
6881 ret = -EINVAL;
6882 goto exit;
6883 }
6884
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306885 request = hdd_request_alloc(&params);
6886 if (!request) {
6887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6888 ret = -ENOMEM;
6889 goto exit;
6890 }
6891
Satyanarayana Dash72806012014-12-02 14:30:08 +05306892 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306893 cookie, hdd_fw_statis_cb);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306894 if (eHAL_STATUS_SUCCESS != status)
6895 {
6896 hddLog(VOS_TRACE_LEVEL_ERROR,
6897 FL(" fail to post WDA cmd status = %d"), status);
6898 ret = -EINVAL;
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306899 hdd_request_put(request);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306900 goto exit;
6901 }
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306902 ret = hdd_request_wait_for_response(request);
6903 if (ret)
Satyanarayana Dash72806012014-12-02 14:30:08 +05306904 {
6905 hddLog(VOS_TRACE_LEVEL_ERROR,
6906 FL("failed to wait on GwtFwstats"));
Satyanarayana Dash72806012014-12-02 14:30:08 +05306907 ret = -EINVAL;
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306908 hdd_request_put(request);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306909 goto exit;
6910 }
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306911
6912 priv = hdd_request_priv(request);
6913 fw_stats_result = priv->fw_stats;
6914 fwStatsRsp->type = 0;
6915 if (NULL != fw_stats_result)
6916 {
6917 switch (fw_stats_result->type )
6918 {
6919 case FW_UBSP_STATS:
6920 {
6921 tSirUbspFwStats *stats =
6922 &fwStatsRsp->fwStatsData.ubspStats;
6923 memcpy(fwStatsRsp, fw_stats_result,
6924 sizeof(tSirFwStatsResult));
6925 hddLog(VOS_TRACE_LEVEL_INFO,
6926 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
6927 stats->ubsp_enter_cnt,
6928 stats->ubsp_jump_ddr_cnt);
6929 }
6930 break;
6931
6932 default:
6933 {
6934 hddLog(VOS_TRACE_LEVEL_ERROR,
6935 FL("No handling for stats type %d"),
6936 fw_stats_result->type);
6937 }
6938 }
6939 }
6940 hdd_request_put(request);
6941
Satyanarayana Dash72806012014-12-02 14:30:08 +05306942 if (fwStatsRsp->type)
6943 {
6944 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
6945 if (!buf)
6946 {
6947 hddLog(VOS_TRACE_LEVEL_ERROR,
6948 FL(" failed to allocate memory"));
6949 ret = -ENOMEM;
6950 goto exit;
6951 }
6952 switch( fwStatsRsp->type )
6953 {
6954 case FW_UBSP_STATS:
6955 {
6956 len = snprintf(buf, FW_STATE_RSP_LEN,
6957 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05306958 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
6959 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306960 }
6961 break;
6962 default:
6963 {
6964 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
6965 ret = -EFAULT;
6966 kfree(buf);
6967 goto exit;
6968 }
6969 }
6970 if (copy_to_user(priv_data.buf, buf, len + 1))
6971 {
6972 hddLog(VOS_TRACE_LEVEL_ERROR,
6973 FL(" failed to copy data to user buffer"));
6974 ret = -EFAULT;
6975 kfree(buf);
6976 goto exit;
6977 }
6978 ret = len;
6979 kfree(buf);
6980 }
6981 else
6982 {
6983 hddLog(VOS_TRACE_LEVEL_ERROR,
6984 FL("failed to fetch the stats"));
6985 ret = -EFAULT;
6986 goto exit;
6987 }
Satyanarayana Dash72806012014-12-02 14:30:08 +05306988 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05306989 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
6990 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306991 ret = hdd_drv_cmd_validate(command, 15);
6992 if (ret)
6993 goto exit;
6994
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05306995 /*
6996 * this command wld be called by user-space when it detects WLAN
6997 * ON after airplane mode is set. When APM is set, WLAN turns off.
6998 * But it can be turned back on. Otherwise; when APM is turned back
6999 * off, WLAN wld turn back on. So at that point the command is
7000 * expected to come down. 0 means disable, 1 means enable. The
7001 * constraint is removed when parameter 1 is set or different
7002 * country code is set
7003 */
7004 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
7005 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05307006 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
7007 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05307008 ret = hdd_drv_cmd_validate(command, 16);
7009 if (ret)
7010 goto exit;
7011
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05307012 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
7013 }
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05307014 /*
7015 * command should be a string having format
7016 * SET_DISABLE_CHANNEL_LIST <num of channels>
7017 * <channels separated by spaces>
7018 */
7019 else if (strncmp(command, "SET_DISABLE_CHANNEL_LIST", 24) == 0) {
7020 tANI_U8 *ptr = command;
7021 ret = hdd_drv_cmd_validate(command, 24);
7022 if (ret)
7023 goto exit;
7024
7025 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7026 " Received Command to disable Channels %s",
7027 __func__);
7028 ret = hdd_parse_disable_chan_cmd(pAdapter, ptr);
7029 if (ret)
7030 goto exit;
7031 }
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307032 else if (strncmp(command, "GET_DISABLE_CHANNEL_LIST", 24) == 0) {
7033 char extra[128] = {0};
7034 int len;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05307035
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7037 " Received Command to get disable Channels list %s",
7038 __func__);
7039
7040 len = hdd_get_disable_ch_list(pHddCtx, extra, sizeof(extra));
7041 if (len == 0) {
7042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7043 FL("disable channel list are not yet programed"));
7044 ret = -EINVAL;
7045 goto exit;
7046 }
7047
7048 len = VOS_MIN(priv_data.total_len, len + 1);
7049 if (copy_to_user(priv_data.buf, &extra, len)) {
7050 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7051 "%s: failed to copy data to user buffer", __func__);
7052 ret = -EFAULT;
7053 goto exit;
7054 }
7055
7056 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7057 FL("data:%s"), extra);
7058 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07007059 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307060 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7061 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
7062 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05307063 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
7064 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07007065 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007066 }
7067exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307068 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007069 if (command)
7070 {
7071 kfree(command);
7072 }
7073 return ret;
7074}
7075
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007076#ifdef CONFIG_COMPAT
7077static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7078{
7079 struct {
7080 compat_uptr_t buf;
7081 int used_len;
7082 int total_len;
7083 } compat_priv_data;
7084 hdd_priv_data_t priv_data;
7085 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007086
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007087 /*
7088 * Note that pAdapter and ifr have already been verified by caller,
7089 * and HDD context has also been validated
7090 */
7091 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
7092 sizeof(compat_priv_data))) {
7093 ret = -EFAULT;
7094 goto exit;
7095 }
7096 priv_data.buf = compat_ptr(compat_priv_data.buf);
7097 priv_data.used_len = compat_priv_data.used_len;
7098 priv_data.total_len = compat_priv_data.total_len;
7099 ret = hdd_driver_command(pAdapter, &priv_data);
7100 exit:
7101 return ret;
7102}
7103#else /* CONFIG_COMPAT */
7104static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7105{
7106 /* will never be invoked */
7107 return 0;
7108}
7109#endif /* CONFIG_COMPAT */
7110
7111static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7112{
7113 hdd_priv_data_t priv_data;
7114 int ret = 0;
7115
7116 /*
7117 * Note that pAdapter and ifr have already been verified by caller,
7118 * and HDD context has also been validated
7119 */
7120 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
7121 ret = -EFAULT;
7122 } else {
7123 ret = hdd_driver_command(pAdapter, &priv_data);
7124 }
7125 return ret;
7126}
7127
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307128int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007129{
7130 hdd_adapter_t *pAdapter;
7131 hdd_context_t *pHddCtx;
7132 int ret;
7133
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307134 ENTER();
7135
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007136 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7137 if (NULL == pAdapter) {
7138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7139 "%s: HDD adapter context is Null", __func__);
7140 ret = -ENODEV;
7141 goto exit;
7142 }
7143 if (dev != pAdapter->dev) {
7144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7145 "%s: HDD adapter/dev inconsistency", __func__);
7146 ret = -ENODEV;
7147 goto exit;
7148 }
7149
7150 if ((!ifr) || (!ifr->ifr_data)) {
7151 ret = -EINVAL;
7152 goto exit;
7153 }
7154
7155 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7156 ret = wlan_hdd_validate_context(pHddCtx);
7157 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007158 ret = -EBUSY;
7159 goto exit;
7160 }
7161
7162 switch (cmd) {
7163 case (SIOCDEVPRIVATE + 1):
7164 if (is_compat_task())
7165 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
7166 else
7167 ret = hdd_driver_ioctl(pAdapter, ifr);
7168 break;
7169 default:
7170 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
7171 __func__, cmd);
7172 ret = -EINVAL;
7173 break;
7174 }
7175 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307176 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007177 return ret;
7178}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007179
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307180int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7181{
7182 int ret;
7183
7184 vos_ssr_protect(__func__);
7185 ret = __hdd_ioctl(dev, ifr, cmd);
7186 vos_ssr_unprotect(__func__);
7187
7188 return ret;
7189}
7190
Katya Nigame7b69a82015-04-28 15:24:06 +05307191int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7192{
7193 return 0;
7194}
7195
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007196#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007197/**---------------------------------------------------------------------------
7198
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007199 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007200
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007201 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007202 CCXBEACONREQ<space><Number of fields><space><Measurement token>
7203 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
7204 <space>Scan Mode N<space>Meas Duration N
7205 if the Number of bcn req fields (N) does not match with the actual number of fields passed
7206 then take N.
7207 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
7208 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
7209 This function does not take care of removing duplicate channels from the list
7210
7211 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007212 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007213
7214 \return - 0 for success non-zero for failure
7215
7216 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007217static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
7218 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007219{
7220 tANI_U8 *inPtr = pValue;
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307221 uint8_t input = 0;
7222 uint32_t tempInt = 0;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007223 int j = 0, i = 0, v = 0;
7224 char buf[32];
7225
7226 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7227 /*no argument after the command*/
7228 if (NULL == inPtr)
7229 {
7230 return -EINVAL;
7231 }
7232 /*no space after the command*/
7233 else if (SPACE_ASCII_VALUE != *inPtr)
7234 {
7235 return -EINVAL;
7236 }
7237
7238 /*removing empty spaces*/
7239 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
7240
7241 /*no argument followed by spaces*/
7242 if ('\0' == *inPtr) return -EINVAL;
7243
7244 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007245 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007246 if (1 != v) return -EINVAL;
7247
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307248 v = kstrtos8(buf, 10, &input);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007249 if ( v < 0) return -EINVAL;
7250
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307251 input = VOS_MIN(input, SIR_ESE_MAX_MEAS_IE_REQS);
7252 pEseBcnReq->numBcnReqIe = input;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007253
Srinivas Girigowda725a88e2016-03-31 19:24:25 +05307254 hddLog(LOG1, "Number of Bcn Req Ie fields: %d", pEseBcnReq->numBcnReqIe);
7255
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007256
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007257 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007258 {
7259 for (i = 0; i < 4; i++)
7260 {
7261 /*inPtr pointing to the beginning of first space after number of ie fields*/
7262 inPtr = strpbrk( inPtr, " " );
7263 /*no ie data after the number of ie fields argument*/
7264 if (NULL == inPtr) return -EINVAL;
7265
7266 /*removing empty space*/
7267 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
7268
7269 /*no ie data after the number of ie fields argument and spaces*/
7270 if ( '\0' == *inPtr ) return -EINVAL;
7271
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007272 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007273 if (1 != v) return -EINVAL;
7274
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307275 v = kstrtou32(buf, 10, &tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007276 if (v < 0) return -EINVAL;
7277
7278 switch (i)
7279 {
7280 case 0: /* Measurement token */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307281 if (!tempInt)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007282 {
7283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307284 "Invalid Measurement Token: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007285 return -EINVAL;
7286 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007287 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007288 break;
7289
7290 case 1: /* Channel number */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307291 if ((!tempInt) ||
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007292 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7293 {
7294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307295 "Invalid Channel Number: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007296 return -EINVAL;
7297 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007298 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007299 break;
7300
7301 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08007302 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007303 {
7304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307305 "Invalid Scan Mode(%u) Expected{0|1|2}", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007306 return -EINVAL;
7307 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007308 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007309 break;
7310
7311 case 3: /* Measurement duration */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307312 if (((!tempInt) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
7313 ((pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007314 {
7315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307316 "Invalid Measurement Duration: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007317 return -EINVAL;
7318 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007319 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007320 break;
7321 }
7322 }
7323 }
7324
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007325 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007326 {
7327 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05307328 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007329 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007330 pEseBcnReq->bcnReq[j].measurementToken,
7331 pEseBcnReq->bcnReq[j].channel,
7332 pEseBcnReq->bcnReq[j].scanMode,
7333 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007334 }
7335
7336 return VOS_STATUS_SUCCESS;
7337}
7338
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307339struct tsm_priv {
7340 tAniTrafStrmMetrics tsm_metrics;
7341};
7342
7343static void hdd_get_tsm_stats_cb(tAniTrafStrmMetrics tsm_metrics,
7344 const tANI_U32 sta_id, void *context )
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007345{
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307346 struct hdd_request *request;
7347 struct tsm_priv *priv;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007348
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307349 ENTER();
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007350
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307351 request = hdd_request_get(context);
7352 if (!request) {
7353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
7354 return;
7355 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007356
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307357 priv = hdd_request_priv(request);
7358 priv->tsm_metrics = tsm_metrics;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007359
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307360 hdd_request_complete(request);
7361 hdd_request_put(request);
Jeff Johnson72a40512013-12-19 10:14:15 -08007362
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307363 EXIT();
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007364}
7365
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007366static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
7367 tAniTrafStrmMetrics* pTsmMetrics)
7368{
7369 hdd_station_ctx_t *pHddStaCtx = NULL;
7370 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08007371 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007372 hdd_context_t *pHddCtx = NULL;
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307373 int ret;
7374 void *cookie;
7375 struct hdd_request *request;
7376 struct tsm_priv *priv;
7377 static const struct hdd_request_params params = {
7378 .priv_size = sizeof(*priv),
7379 .timeout_ms = WLAN_WAIT_TIME_STATS,
7380 };
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007381
7382 if (NULL == pAdapter)
7383 {
7384 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
7385 return VOS_STATUS_E_FAULT;
7386 }
7387
7388 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7389 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7390
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307391 request = hdd_request_alloc(&params);
7392 if (!request) {
7393 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
7394 return VOS_STATUS_E_NOMEM;
7395 }
7396 cookie = hdd_request_cookie(request);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007397
7398 /* query tsm stats */
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307399 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_get_tsm_stats_cb,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007400 pHddStaCtx->conn_info.staId[ 0 ],
7401 pHddStaCtx->conn_info.bssId,
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307402 cookie, pHddCtx->pvosContext, tid);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007403
7404 if (eHAL_STATUS_SUCCESS != hstatus)
7405 {
Jeff Johnson72a40512013-12-19 10:14:15 -08007406 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
7407 __func__);
7408 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007409 }
7410 else
7411 {
7412 /* request was sent -- wait for the response */
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307413 ret = hdd_request_wait_for_response(request);
7414 if (ret) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007415 hddLog(VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307416 "SME timeout while retrieving statistics");
Jeff Johnson72a40512013-12-19 10:14:15 -08007417 vstatus = VOS_STATUS_E_TIMEOUT;
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307418 } else {
7419 priv = hdd_request_priv(request);
7420 *pTsmMetrics = priv->tsm_metrics;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007421 }
7422 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007423
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307424 hdd_request_put(request);
Jeff Johnson72a40512013-12-19 10:14:15 -08007425
Jeff Johnson72a40512013-12-19 10:14:15 -08007426 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007427}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007428#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007429
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007430#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08007431void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
7432{
7433 eCsrBand band = -1;
7434 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
7435 switch (band)
7436 {
7437 case eCSR_BAND_ALL:
7438 *pBand = WLAN_HDD_UI_BAND_AUTO;
7439 break;
7440
7441 case eCSR_BAND_24:
7442 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
7443 break;
7444
7445 case eCSR_BAND_5G:
7446 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
7447 break;
7448
7449 default:
7450 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
7451 *pBand = -1;
7452 break;
7453 }
7454}
7455
7456/**---------------------------------------------------------------------------
7457
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007458 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
7459
7460 This function parses the send action frame data passed in the format
7461 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
7462
Srinivas Girigowda56076852013-08-20 14:00:50 -07007463 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007464 \param - pTargetApBssid Pointer to target Ap bssid
7465 \param - pChannel Pointer to the Target AP channel
7466 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
7467 \param - pBuf Pointer to data
7468 \param - pBufLen Pointer to data length
7469
7470 \return - 0 for success non-zero for failure
7471
7472 --------------------------------------------------------------------------*/
7473VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
7474 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
7475{
7476 tANI_U8 *inPtr = pValue;
7477 tANI_U8 *dataEnd;
7478 int tempInt;
7479 int j = 0;
7480 int i = 0;
7481 int v = 0;
7482 tANI_U8 tempBuf[32];
7483 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007484 /* 12 hexa decimal digits, 5 ':' and '\0' */
7485 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007486
7487 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7488 /*no argument after the command*/
7489 if (NULL == inPtr)
7490 {
7491 return -EINVAL;
7492 }
7493
7494 /*no space after the command*/
7495 else if (SPACE_ASCII_VALUE != *inPtr)
7496 {
7497 return -EINVAL;
7498 }
7499
7500 /*removing empty spaces*/
7501 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7502
7503 /*no argument followed by spaces*/
7504 if ('\0' == *inPtr)
7505 {
7506 return -EINVAL;
7507 }
7508
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007509 v = sscanf(inPtr, "%17s", macAddress);
7510 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007511 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7513 "Invalid MAC address or All hex inputs are not read (%d)", v);
7514 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007515 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007516
7517 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7518 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7519 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7520 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7521 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7522 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007523
7524 /* point to the next argument */
7525 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7526 /*no argument after the command*/
7527 if (NULL == inPtr) return -EINVAL;
7528
7529 /*removing empty spaces*/
7530 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7531
7532 /*no argument followed by spaces*/
7533 if ('\0' == *inPtr)
7534 {
7535 return -EINVAL;
7536 }
7537
7538 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007539 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007540 if (1 != v) return -EINVAL;
7541
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007542 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05307543 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05307544 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007545
7546 *pChannel = tempInt;
7547
7548 /* point to the next argument */
7549 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7550 /*no argument after the command*/
7551 if (NULL == inPtr) return -EINVAL;
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
7561 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007562 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007563 if (1 != v) return -EINVAL;
7564
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007565 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08007566 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007567
7568 *pDwellTime = tempInt;
7569
7570 /* point to the next argument */
7571 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7572 /*no argument after the command*/
7573 if (NULL == inPtr) return -EINVAL;
7574 /*removing empty spaces*/
7575 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7576
7577 /*no argument followed by spaces*/
7578 if ('\0' == *inPtr)
7579 {
7580 return -EINVAL;
7581 }
7582
7583 /* find the length of data */
7584 dataEnd = inPtr;
7585 while(('\0' != *dataEnd) )
7586 {
7587 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007588 }
Kiet Lambe150c22013-11-21 16:30:32 +05307589 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007590 if ( *pBufLen <= 0) return -EINVAL;
7591
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07007592 /* Allocate the number of bytes based on the number of input characters
7593 whether it is even or odd.
7594 if the number of input characters are even, then we need N/2 byte.
7595 if the number of input characters are odd, then we need do (N+1)/2 to
7596 compensate rounding off.
7597 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7598 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7599 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007600 if (NULL == *pBuf)
7601 {
7602 hddLog(VOS_TRACE_LEVEL_FATAL,
7603 "%s: vos_mem_alloc failed ", __func__);
7604 return -EINVAL;
7605 }
7606
7607 /* the buffer received from the upper layer is character buffer,
7608 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7609 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7610 and f0 in 3rd location */
7611 for (i = 0, j = 0; j < *pBufLen; j += 2)
7612 {
Kiet Lambe150c22013-11-21 16:30:32 +05307613 if( j+1 == *pBufLen)
7614 {
7615 tempByte = hdd_parse_hex(inPtr[j]);
7616 }
7617 else
7618 {
7619 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
7620 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007621 (*pBuf)[i++] = tempByte;
7622 }
7623 *pBufLen = i;
7624 return VOS_STATUS_SUCCESS;
7625}
7626
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007627/**---------------------------------------------------------------------------
7628
Srinivas Girigowdade697412013-02-14 16:31:48 -08007629 \brief hdd_parse_channellist() - HDD Parse channel list
7630
7631 This function parses the channel list passed in the format
7632 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007633 if the Number of channels (N) does not match with the actual number of channels passed
7634 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
7635 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
7636 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
7637 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08007638
7639 \param - pValue Pointer to input channel list
7640 \param - ChannelList Pointer to local output array to record channel list
7641 \param - pNumChannels Pointer to number of roam scan channels
7642
7643 \return - 0 for success non-zero for failure
7644
7645 --------------------------------------------------------------------------*/
7646VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
7647{
7648 tANI_U8 *inPtr = pValue;
7649 int tempInt;
7650 int j = 0;
7651 int v = 0;
7652 char buf[32];
7653
7654 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7655 /*no argument after the command*/
7656 if (NULL == inPtr)
7657 {
7658 return -EINVAL;
7659 }
7660
7661 /*no space after the command*/
7662 else if (SPACE_ASCII_VALUE != *inPtr)
7663 {
7664 return -EINVAL;
7665 }
7666
7667 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007668 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08007669
7670 /*no argument followed by spaces*/
7671 if ('\0' == *inPtr)
7672 {
7673 return -EINVAL;
7674 }
7675
7676 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007677 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007678 if (1 != v) return -EINVAL;
7679
Srinivas Girigowdade697412013-02-14 16:31:48 -08007680 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007681 if ((v < 0) ||
7682 (tempInt <= 0) ||
7683 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
7684 {
7685 return -EINVAL;
7686 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007687
7688 *pNumChannels = tempInt;
7689
7690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7691 "Number of channels are: %d", *pNumChannels);
7692
7693 for (j = 0; j < (*pNumChannels); j++)
7694 {
7695 /*inPtr pointing to the beginning of first space after number of channels*/
7696 inPtr = strpbrk( inPtr, " " );
7697 /*no channel list after the number of channels argument*/
7698 if (NULL == inPtr)
7699 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007700 if (0 != j)
7701 {
7702 *pNumChannels = j;
7703 return VOS_STATUS_SUCCESS;
7704 }
7705 else
7706 {
7707 return -EINVAL;
7708 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007709 }
7710
7711 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007712 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08007713
7714 /*no channel list after the number of channels argument and spaces*/
7715 if ( '\0' == *inPtr )
7716 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007717 if (0 != j)
7718 {
7719 *pNumChannels = j;
7720 return VOS_STATUS_SUCCESS;
7721 }
7722 else
7723 {
7724 return -EINVAL;
7725 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007726 }
7727
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007728 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007729 if (1 != v) return -EINVAL;
7730
Srinivas Girigowdade697412013-02-14 16:31:48 -08007731 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007732 if ((v < 0) ||
7733 (tempInt <= 0) ||
7734 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7735 {
7736 return -EINVAL;
7737 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007738 pChannelList[j] = tempInt;
7739
7740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7741 "Channel %d added to preferred channel list",
7742 pChannelList[j] );
7743 }
7744
Srinivas Girigowdade697412013-02-14 16:31:48 -08007745 return VOS_STATUS_SUCCESS;
7746}
7747
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007748
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05307749/**
7750 * hdd_parse_reassoc_command_v1_data() - HDD Parse reassoc command data
7751 * This function parses the reasoc command data passed in the format
7752 * REASSOC<space><bssid><space><channel>
7753 *
7754 * @pValue: Pointer to input data (its a NUL terminated string)
7755 * @pTargetApBssid: Pointer to target Ap bssid
7756 * @pChannel: Pointer to the Target AP channel
7757 *
7758 * Return: 0 for success non-zero for failure
7759 */
7760static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
7761 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007762{
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05307763 const tANI_U8 *inPtr = pValue;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007764 int tempInt;
7765 int v = 0;
7766 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08007767 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007768 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007769
7770 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7771 /*no argument after the command*/
7772 if (NULL == inPtr)
7773 {
7774 return -EINVAL;
7775 }
7776
7777 /*no space after the command*/
7778 else if (SPACE_ASCII_VALUE != *inPtr)
7779 {
7780 return -EINVAL;
7781 }
7782
7783 /*removing empty spaces*/
7784 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7785
7786 /*no argument followed by spaces*/
7787 if ('\0' == *inPtr)
7788 {
7789 return -EINVAL;
7790 }
7791
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007792 v = sscanf(inPtr, "%17s", macAddress);
7793 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007794 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7796 "Invalid MAC address or All hex inputs are not read (%d)", v);
7797 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007798 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007799
7800 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7801 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7802 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7803 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7804 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7805 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007806
7807 /* point to the next argument */
7808 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7809 /*no argument after the command*/
7810 if (NULL == inPtr) return -EINVAL;
7811
7812 /*removing empty spaces*/
7813 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7814
7815 /*no argument followed by spaces*/
7816 if ('\0' == *inPtr)
7817 {
7818 return -EINVAL;
7819 }
7820
7821 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007822 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007823 if (1 != v) return -EINVAL;
7824
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007825 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007826 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05307827 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007828 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7829 {
7830 return -EINVAL;
7831 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007832
7833 *pChannel = tempInt;
7834 return VOS_STATUS_SUCCESS;
7835}
7836
7837#endif
7838
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007839#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007840/**---------------------------------------------------------------------------
7841
7842 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
7843
7844 This function parses the SETCCKM IE command
7845 SETCCKMIE<space><ie data>
7846
7847 \param - pValue Pointer to input data
7848 \param - pCckmIe Pointer to output cckm Ie
7849 \param - pCckmIeLen Pointer to output cckm ie length
7850
7851 \return - 0 for success non-zero for failure
7852
7853 --------------------------------------------------------------------------*/
7854VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
7855 tANI_U8 *pCckmIeLen)
7856{
7857 tANI_U8 *inPtr = pValue;
7858 tANI_U8 *dataEnd;
7859 int j = 0;
7860 int i = 0;
7861 tANI_U8 tempByte = 0;
7862
7863 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7864 /*no argument after the command*/
7865 if (NULL == inPtr)
7866 {
7867 return -EINVAL;
7868 }
7869
7870 /*no space after the command*/
7871 else if (SPACE_ASCII_VALUE != *inPtr)
7872 {
7873 return -EINVAL;
7874 }
7875
7876 /*removing empty spaces*/
7877 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7878
7879 /*no argument followed by spaces*/
7880 if ('\0' == *inPtr)
7881 {
7882 return -EINVAL;
7883 }
7884
7885 /* find the length of data */
7886 dataEnd = inPtr;
7887 while(('\0' != *dataEnd) )
7888 {
7889 dataEnd++;
7890 ++(*pCckmIeLen);
7891 }
7892 if ( *pCckmIeLen <= 0) return -EINVAL;
7893
7894 /* Allocate the number of bytes based on the number of input characters
7895 whether it is even or odd.
7896 if the number of input characters are even, then we need N/2 byte.
7897 if the number of input characters are odd, then we need do (N+1)/2 to
7898 compensate rounding off.
7899 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7900 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7901 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
7902 if (NULL == *pCckmIe)
7903 {
7904 hddLog(VOS_TRACE_LEVEL_FATAL,
7905 "%s: vos_mem_alloc failed ", __func__);
7906 return -EINVAL;
7907 }
7908 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
7909 /* the buffer received from the upper layer is character buffer,
7910 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7911 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7912 and f0 in 3rd location */
7913 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
7914 {
7915 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
7916 (*pCckmIe)[i++] = tempByte;
7917 }
7918 *pCckmIeLen = i;
7919
7920 return VOS_STATUS_SUCCESS;
7921}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007922#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007923
Jeff Johnson295189b2012-06-20 16:38:30 -07007924/**---------------------------------------------------------------------------
7925
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007926 \brief hdd_is_valid_mac_address() - Validate MAC address
7927
7928 This function validates whether the given MAC address is valid or not
7929 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
7930 where X is the hexa decimal digit character and separated by ':'
7931 This algorithm works even if MAC address is not separated by ':'
7932
7933 This code checks given input string mac contains exactly 12 hexadecimal digits.
7934 and a separator colon : appears in the input string only after
7935 an even number of hex digits.
7936
7937 \param - pMacAddr pointer to the input MAC address
7938 \return - 1 for valid and 0 for invalid
7939
7940 --------------------------------------------------------------------------*/
7941
7942v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
7943{
7944 int xdigit = 0;
7945 int separator = 0;
7946 while (*pMacAddr)
7947 {
7948 if (isxdigit(*pMacAddr))
7949 {
7950 xdigit++;
7951 }
7952 else if (':' == *pMacAddr)
7953 {
7954 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
7955 break;
7956
7957 ++separator;
7958 }
7959 else
7960 {
7961 separator = -1;
7962 /* Invalid MAC found */
7963 return 0;
7964 }
7965 ++pMacAddr;
7966 }
7967 return (xdigit == 12 && (separator == 5 || separator == 0));
7968}
7969
7970/**---------------------------------------------------------------------------
7971
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307972 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07007973
7974 \param - dev Pointer to net_device structure
7975
7976 \return - 0 for success non-zero for failure
7977
7978 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307979int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007980{
7981 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7982 hdd_context_t *pHddCtx;
7983 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7984 VOS_STATUS status;
7985 v_BOOL_t in_standby = TRUE;
7986
7987 if (NULL == pAdapter)
7988 {
7989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05307990 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007991 return -ENODEV;
7992 }
7993
7994 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307995 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
7996 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07007997 if (NULL == pHddCtx)
7998 {
7999 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008000 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008001 return -ENODEV;
8002 }
8003
8004 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8005 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
8006 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008007 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
8008 {
8009 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308010 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008011 in_standby = FALSE;
8012 break;
8013 }
8014 else
8015 {
8016 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8017 pAdapterNode = pNext;
8018 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008019 }
8020
8021 if (TRUE == in_standby)
8022 {
8023 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
8024 {
8025 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
8026 "wlan out of power save", __func__);
8027 return -EINVAL;
8028 }
8029 }
8030
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008031 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07008032 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8033 {
8034 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008035 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008036 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308037 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008038 netif_tx_start_all_queues(dev);
8039 }
8040
8041 return 0;
8042}
8043
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308044/**---------------------------------------------------------------------------
8045
8046 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
8047
8048 This is called in response to ifconfig up
8049
8050 \param - dev Pointer to net_device structure
8051
8052 \return - 0 for success non-zero for failure
8053
8054 --------------------------------------------------------------------------*/
8055int hdd_open(struct net_device *dev)
8056{
8057 int ret;
8058
8059 vos_ssr_protect(__func__);
8060 ret = __hdd_open(dev);
8061 vos_ssr_unprotect(__func__);
8062
8063 return ret;
8064}
8065
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308066int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008067{
8068 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308069 hdd_adapter_t *sta_adapter;
8070 hdd_context_t *hdd_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008071
8072 if(pAdapter == NULL) {
8073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008074 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008075 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008076 }
8077
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308078 if (vos_get_concurrency_mode() != VOS_STA_MON)
8079 return 0;
8080
8081 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8082 if (wlan_hdd_validate_context(hdd_ctx))
8083 return -EINVAL;
8084
8085 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
8086 if (!sta_adapter) {
8087 hddLog(LOGE, FL("No valid STA interface"));
8088 return -EINVAL;
8089 }
8090
8091 if (!test_bit(DEVICE_IFACE_OPENED, &sta_adapter->event_flags)) {
8092 hddLog(LOGE, FL("STA Interface is not OPENED"));
8093 return -EINVAL;
8094 }
8095
8096 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
8097
Jeff Johnson295189b2012-06-20 16:38:30 -07008098 return 0;
8099}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308100
8101int hdd_mon_open (struct net_device *dev)
8102{
8103 int ret;
8104
8105 vos_ssr_protect(__func__);
8106 ret = __hdd_mon_open(dev);
8107 vos_ssr_unprotect(__func__);
8108
8109 return ret;
8110}
8111
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308112int __hdd_mon_stop (struct net_device *dev)
8113{
8114 hdd_adapter_t *mon_adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8115 hdd_context_t *hdd_ctx;
8116
8117 if (vos_get_concurrency_mode() != VOS_STA_MON)
8118 return 0;
8119
8120 if(!mon_adapter) {
8121 hddLog(LOGE, FL("HDD adapter is Null"));
8122 return -EINVAL;
8123 }
8124
8125 hdd_ctx = WLAN_HDD_GET_CTX(mon_adapter);
8126 if (wlan_hdd_validate_context(hdd_ctx))
8127 return -EINVAL;
8128
8129 if (!test_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags)) {
8130 hddLog(LOGE, FL("NETDEV Interface is not OPENED"));
8131 return -ENODEV;
8132 }
8133
8134 clear_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags);
8135 hdd_stop_adapter(hdd_ctx, mon_adapter, VOS_FALSE);
8136
8137 return 0;
8138}
8139
Katya Nigame7b69a82015-04-28 15:24:06 +05308140int hdd_mon_stop(struct net_device *dev)
8141{
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308142 int ret;
8143
8144 vos_ssr_protect(__func__);
8145 ret = __hdd_mon_stop(dev);
8146 vos_ssr_unprotect(__func__);
8147
8148 return ret;
Katya Nigame7b69a82015-04-28 15:24:06 +05308149}
8150
Jeff Johnson295189b2012-06-20 16:38:30 -07008151/**---------------------------------------------------------------------------
8152
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308153 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07008154
8155 \param - dev Pointer to net_device structure
8156
8157 \return - 0 for success non-zero for failure
8158
8159 --------------------------------------------------------------------------*/
8160
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308161int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008162{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308163 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008164 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8165 hdd_context_t *pHddCtx;
8166 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8167 VOS_STATUS status;
8168 v_BOOL_t enter_standby = TRUE;
8169
8170 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008171 if (NULL == pAdapter)
8172 {
8173 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05308174 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008175 return -ENODEV;
8176 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05308177 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308178 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308179
8180 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8181 ret = wlan_hdd_validate_context(pHddCtx);
8182 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07008183 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308184 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008185 }
8186
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308187 /* Nothing to be done if the interface is not opened */
8188 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
8189 {
8190 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8191 "%s: NETDEV Interface is not OPENED", __func__);
8192 return -ENODEV;
8193 }
8194
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308195 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308196 /*
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05308197 * In STA + Monitor mode concurrency, no point in running
8198 * capture on monitor interface, when STA interface is stopped
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308199 */
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05308200 wlan_hdd_stop_mon(pHddCtx, true);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308201 }
8202
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308203 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008204 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07008205 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308206
8207 /* Disable TX on the interface, after this hard_start_xmit() will not
8208 * be called on that interface
8209 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308210 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008211 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308212
8213 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07008214 netif_carrier_off(pAdapter->dev);
8215
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308216 /* The interface is marked as down for outside world (aka kernel)
8217 * But the driver is pretty much alive inside. The driver needs to
8218 * tear down the existing connection on the netdev (session)
8219 * cleanup the data pipes and wait until the control plane is stabilized
8220 * for this interface. The call also needs to wait until the above
8221 * mentioned actions are completed before returning to the caller.
8222 * Notice that the hdd_stop_adapter is requested not to close the session
8223 * That is intentional to be able to scan if it is a STA/P2P interface
8224 */
8225 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308226#ifdef FEATURE_WLAN_TDLS
8227 mutex_lock(&pHddCtx->tdls_lock);
8228#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308229 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05308230 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308231#ifdef FEATURE_WLAN_TDLS
8232 mutex_unlock(&pHddCtx->tdls_lock);
8233#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008234 /* SoftAP ifaces should never go in power save mode
8235 making sure same here. */
8236 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07008237 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07008238 )
8239 {
8240 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308241 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8242 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008243 EXIT();
8244 return 0;
8245 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308246 /* Find if any iface is up. If any iface is up then can't put device to
8247 * sleep/power save mode
8248 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008249 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8250 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
8251 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008252 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
8253 {
8254 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308255 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008256 enter_standby = FALSE;
8257 break;
8258 }
8259 else
8260 {
8261 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8262 pAdapterNode = pNext;
8263 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008264 }
8265
8266 if (TRUE == enter_standby)
8267 {
8268 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
8269 "entering standby", __func__);
8270 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
8271 {
8272 /*log and return success*/
8273 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
8274 "wlan in power save", __func__);
8275 }
8276 }
8277
8278 EXIT();
8279 return 0;
8280}
8281
8282/**---------------------------------------------------------------------------
8283
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308284 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07008285
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308286 This is called in response to ifconfig down
8287
8288 \param - dev Pointer to net_device structure
8289
8290 \return - 0 for success non-zero for failure
8291-----------------------------------------------------------------------------*/
8292int hdd_stop (struct net_device *dev)
8293{
8294 int ret;
8295
8296 vos_ssr_protect(__func__);
8297 ret = __hdd_stop(dev);
8298 vos_ssr_unprotect(__func__);
8299
8300 return ret;
8301}
8302
8303/**---------------------------------------------------------------------------
8304
8305 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07008306
8307 \param - dev Pointer to net_device structure
8308
8309 \return - void
8310
8311 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308312static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008313{
8314 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308315 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008316 ENTER();
8317
8318 do
8319 {
8320 if (NULL == pAdapter)
8321 {
8322 hddLog(VOS_TRACE_LEVEL_FATAL,
8323 "%s: NULL pAdapter", __func__);
8324 break;
8325 }
8326
8327 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8328 {
8329 hddLog(VOS_TRACE_LEVEL_FATAL,
8330 "%s: Invalid magic", __func__);
8331 break;
8332 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308333 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8334 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07008335 {
8336 hddLog(VOS_TRACE_LEVEL_FATAL,
8337 "%s: NULL pHddCtx", __func__);
8338 break;
8339 }
8340
8341 if (dev != pAdapter->dev)
8342 {
8343 hddLog(VOS_TRACE_LEVEL_FATAL,
8344 "%s: Invalid device reference", __func__);
8345 /* we haven't validated all cases so let this go for now */
8346 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308347#ifdef FEATURE_WLAN_TDLS
8348 mutex_lock(&pHddCtx->tdls_lock);
8349#endif
c_hpothu002231a2015-02-05 14:58:51 +05308350 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308351#ifdef FEATURE_WLAN_TDLS
8352 mutex_unlock(&pHddCtx->tdls_lock);
8353#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008354
8355 /* after uninit our adapter structure will no longer be valid */
8356 pAdapter->dev = NULL;
8357 pAdapter->magic = 0;
Manjeet Singh47ee8472016-04-11 11:57:18 +05308358 pAdapter->pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008359 } while (0);
8360
8361 EXIT();
8362}
8363
8364/**---------------------------------------------------------------------------
8365
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308366 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
8367
8368 This is called during the netdev unregister to uninitialize all data
8369associated with the device
8370
8371 \param - dev Pointer to net_device structure
8372
8373 \return - void
8374
8375 --------------------------------------------------------------------------*/
8376static void hdd_uninit (struct net_device *dev)
8377{
8378 vos_ssr_protect(__func__);
8379 __hdd_uninit(dev);
8380 vos_ssr_unprotect(__func__);
8381}
8382
8383/**---------------------------------------------------------------------------
8384
Jeff Johnson295189b2012-06-20 16:38:30 -07008385 \brief hdd_release_firmware() -
8386
8387 This function calls the release firmware API to free the firmware buffer.
8388
8389 \param - pFileName Pointer to the File Name.
8390 pCtx - Pointer to the adapter .
8391
8392
8393 \return - 0 for success, non zero for failure
8394
8395 --------------------------------------------------------------------------*/
8396
8397VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
8398{
8399 VOS_STATUS status = VOS_STATUS_SUCCESS;
8400 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8401 ENTER();
8402
8403
8404 if (!strcmp(WLAN_FW_FILE, pFileName)) {
8405
8406 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
8407
8408 if(pHddCtx->fw) {
8409 release_firmware(pHddCtx->fw);
8410 pHddCtx->fw = NULL;
8411 }
8412 else
8413 status = VOS_STATUS_E_FAILURE;
8414 }
8415 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
8416 if(pHddCtx->nv) {
8417 release_firmware(pHddCtx->nv);
8418 pHddCtx->nv = NULL;
8419 }
8420 else
8421 status = VOS_STATUS_E_FAILURE;
8422
8423 }
8424
8425 EXIT();
8426 return status;
8427}
8428
8429/**---------------------------------------------------------------------------
8430
8431 \brief hdd_request_firmware() -
8432
8433 This function reads the firmware file using the request firmware
8434 API and returns the the firmware data and the firmware file size.
8435
8436 \param - pfileName - Pointer to the file name.
8437 - pCtx - Pointer to the adapter .
8438 - ppfw_data - Pointer to the pointer of the firmware data.
8439 - pSize - Pointer to the file size.
8440
8441 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
8442
8443 --------------------------------------------------------------------------*/
8444
8445
8446VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
8447{
8448 int status;
8449 VOS_STATUS retval = VOS_STATUS_SUCCESS;
8450 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8451 ENTER();
8452
8453 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
8454
8455 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
8456
8457 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8458 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
8459 __func__, pfileName);
8460 retval = VOS_STATUS_E_FAILURE;
8461 }
8462
8463 else {
8464 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
8465 *pSize = pHddCtx->fw->size;
8466 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
8467 __func__, *pSize);
8468 }
8469 }
8470 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
8471
8472 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
8473
8474 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
8475 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
8476 __func__, pfileName);
8477 retval = VOS_STATUS_E_FAILURE;
8478 }
8479
8480 else {
8481 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
8482 *pSize = pHddCtx->nv->size;
8483 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
8484 __func__, *pSize);
8485 }
8486 }
8487
8488 EXIT();
8489 return retval;
8490}
8491/**---------------------------------------------------------------------------
8492 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
8493
8494 This is the function invoked by SME to inform the result of a full power
8495 request issued by HDD
8496
8497 \param - callbackcontext - Pointer to cookie
8498 status - result of request
8499
8500 \return - None
8501
8502--------------------------------------------------------------------------*/
8503void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
8504{
8505 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
8506
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008507 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008508 if(&pHddCtx->full_pwr_comp_var)
8509 {
8510 complete(&pHddCtx->full_pwr_comp_var);
8511 }
8512}
8513
Abhishek Singh00b71972016-01-07 10:51:04 +05308514#ifdef WLAN_FEATURE_RMC
8515static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo)
8516{
8517 int payload_len;
8518 struct sk_buff *skb;
8519 struct nlmsghdr *nlh;
8520 v_U8_t *data;
8521
8522 payload_len = ETH_ALEN;
8523
8524 if (0 == cesium_pid)
8525 {
8526 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: cesium process not registered",
8527 __func__);
8528 return;
8529 }
8530
8531 if ((skb = nlmsg_new(payload_len,GFP_ATOMIC)) == NULL)
8532 {
8533 hddLog(VOS_TRACE_LEVEL_ERROR,
8534 "%s: nlmsg_new() failed for msg size[%d]",
8535 __func__, NLMSG_SPACE(payload_len));
8536 return;
8537 }
8538
8539 nlh = nlmsg_put(skb, cesium_pid, seqNo, 0, payload_len, NLM_F_REQUEST);
8540
8541 if (NULL == nlh)
8542 {
8543 hddLog(VOS_TRACE_LEVEL_ERROR,
8544 "%s: nlmsg_put() failed for msg size[%d]",
8545 __func__, NLMSG_SPACE(payload_len));
8546
8547 kfree_skb(skb);
8548 return;
8549 }
8550
8551 data = nlmsg_data(nlh);
8552 memcpy(data, MacAddr, ETH_ALEN);
8553
8554 if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0)
8555 {
8556 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_unicast() failed for msg size[%d]",
8557 __func__, NLMSG_SPACE(payload_len));
8558 }
8559
8560 return;
8561}
8562
8563/**---------------------------------------------------------------------------
8564 \brief hdd_ParseuserParams - return a pointer to the next argument
8565
8566 \return - status
8567
8568--------------------------------------------------------------------------*/
8569static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg)
8570{
8571 tANI_U8 *pVal;
8572
8573 pVal = strchr(pValue, ' ');
8574
8575 if (NULL == pVal)
8576 {
8577 /* no argument remains */
8578 return -EINVAL;
8579 }
8580 else if (SPACE_ASCII_VALUE != *pVal)
8581 {
8582 /* no space after the current argument */
8583 return -EINVAL;
8584 }
8585
8586 pVal++;
8587
8588 /* remove empty spaces */
8589 while ((SPACE_ASCII_VALUE == *pVal) && ('\0' != *pVal))
8590 {
8591 pVal++;
8592 }
8593
8594 /* no argument followed by spaces */
8595 if ('\0' == *pVal)
8596 {
8597 return -EINVAL;
8598 }
8599
8600 *ppArg = pVal;
8601
8602 return 0;
8603}
8604
8605/**----------------------------------------------------------------------------
8606 \brief hdd_ParseIBSSTXFailEventParams - Parse params for SETIBSSTXFAILEVENT
8607
8608 \return - status
8609
8610------------------------------------------------------------------------------*/
8611static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
8612 tANI_U8 *tx_fail_count,
8613 tANI_U16 *pid)
8614{
8615 tANI_U8 *param = NULL;
8616 int ret;
8617
8618 ret = hdd_ParseUserParams(pValue, &param);
8619
8620 if (0 == ret && NULL != param)
8621 {
8622 if (1 != sscanf(param, "%hhu", tx_fail_count))
8623 {
8624 ret = -EINVAL;
8625 goto done;
8626 }
8627 }
8628 else
8629 {
8630 goto done;
8631 }
8632
8633 if (0 == *tx_fail_count)
8634 {
8635 *pid = 0;
8636 goto done;
8637 }
8638
8639 pValue = param;
8640 pValue++;
8641
8642 ret = hdd_ParseUserParams(pValue, &param);
8643
8644 if (0 == ret)
8645 {
8646 if (1 != sscanf(param, "%hu", pid))
8647 {
8648 ret = -EINVAL;
8649 goto done;
8650 }
8651 }
8652 else
8653 {
8654 goto done;
8655 }
8656
8657done:
8658 return ret;
8659}
8660
8661static int hdd_open_cesium_nl_sock()
8662{
8663#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8664 struct netlink_kernel_cfg cfg = {
8665 .groups = WLAN_NLINK_MCAST_GRP_ID,
8666 .input = NULL
8667 };
8668#endif
8669 int ret = 0;
8670
8671#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8672 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
8673#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
8674 THIS_MODULE,
8675#endif
8676 &cfg);
8677#else
8678 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
8679 WLAN_NLINK_MCAST_GRP_ID, NULL, NULL, THIS_MODULE);
8680#endif
8681
8682 if (cesium_nl_srv_sock == NULL)
8683 {
8684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8685 "NLINK: cesium netlink_kernel_create failed");
8686 ret = -ECONNREFUSED;
8687 }
8688
8689 return ret;
8690}
8691
8692static void hdd_close_cesium_nl_sock()
8693{
8694 if (NULL != cesium_nl_srv_sock)
8695 {
8696 netlink_kernel_release(cesium_nl_srv_sock);
8697 cesium_nl_srv_sock = NULL;
8698 }
8699}
8700#endif /* WLAN_FEATURE_RMC */
Jeff Johnson295189b2012-06-20 16:38:30 -07008701/**---------------------------------------------------------------------------
8702
8703 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
8704
8705 This is the function invoked by SME to inform the result of BMPS
8706 request issued by HDD
8707
8708 \param - callbackcontext - Pointer to cookie
8709 status - result of request
8710
8711 \return - None
8712
8713--------------------------------------------------------------------------*/
8714void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
8715{
8716
8717 struct completion *completion_var = (struct completion*) callbackContext;
8718
Arif Hussain6d2a3322013-11-17 19:50:10 -08008719 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008720 if(completion_var != NULL)
8721 {
8722 complete(completion_var);
8723 }
8724}
8725
8726/**---------------------------------------------------------------------------
8727
8728 \brief hdd_get_cfg_file_size() -
8729
8730 This function reads the configuration file using the request firmware
8731 API and returns the configuration file size.
8732
8733 \param - pCtx - Pointer to the adapter .
8734 - pFileName - Pointer to the file name.
8735 - pBufSize - Pointer to the buffer size.
8736
8737 \return - 0 for success, non zero for failure
8738
8739 --------------------------------------------------------------------------*/
8740
8741VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
8742{
8743 int status;
8744 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8745
8746 ENTER();
8747
8748 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
8749
8750 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8751 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
8752 status = VOS_STATUS_E_FAILURE;
8753 }
8754 else {
8755 *pBufSize = pHddCtx->fw->size;
8756 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
8757 release_firmware(pHddCtx->fw);
8758 pHddCtx->fw = NULL;
8759 }
8760
8761 EXIT();
8762 return VOS_STATUS_SUCCESS;
8763}
8764
8765/**---------------------------------------------------------------------------
8766
8767 \brief hdd_read_cfg_file() -
8768
8769 This function reads the configuration file using the request firmware
8770 API and returns the cfg data and the buffer size of the configuration file.
8771
8772 \param - pCtx - Pointer to the adapter .
8773 - pFileName - Pointer to the file name.
8774 - pBuffer - Pointer to the data buffer.
8775 - pBufSize - Pointer to the buffer size.
8776
8777 \return - 0 for success, non zero for failure
8778
8779 --------------------------------------------------------------------------*/
8780
8781VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
8782 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
8783{
8784 int status;
8785 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8786
8787 ENTER();
8788
8789 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
8790
8791 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8792 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
8793 return VOS_STATUS_E_FAILURE;
8794 }
8795 else {
8796 if(*pBufSize != pHddCtx->fw->size) {
8797 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
8798 "file size", __func__);
8799 release_firmware(pHddCtx->fw);
8800 pHddCtx->fw = NULL;
8801 return VOS_STATUS_E_FAILURE;
8802 }
8803 else {
8804 if(pBuffer) {
8805 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
8806 }
8807 release_firmware(pHddCtx->fw);
8808 pHddCtx->fw = NULL;
8809 }
8810 }
8811
8812 EXIT();
8813
8814 return VOS_STATUS_SUCCESS;
8815}
8816
8817/**---------------------------------------------------------------------------
8818
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308819 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008820
8821 This function sets the user specified mac address using
8822 the command ifconfig wlanX hw ether <mac adress>.
8823
8824 \param - dev - Pointer to the net device.
8825 - addr - Pointer to the sockaddr.
8826 \return - 0 for success, non zero for failure
8827
8828 --------------------------------------------------------------------------*/
8829
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308830static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07008831{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308832 hdd_adapter_t *pAdapter;
8833 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008834 struct sockaddr *psta_mac_addr = addr;
8835 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308836 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008837
8838 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308839 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8840 if (NULL == pAdapter)
8841 {
8842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8843 "%s: Adapter is NULL",__func__);
8844 return -EINVAL;
8845 }
8846 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8847 ret = wlan_hdd_validate_context(pHddCtx);
8848 if (0 != ret)
8849 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308850 return ret;
8851 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008852
8853 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07008854 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
8855
8856 EXIT();
8857 return halStatus;
8858}
8859
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308860/**---------------------------------------------------------------------------
8861
8862 \brief hdd_set_mac_address() -
8863
8864 Wrapper function to protect __hdd_set_mac_address() function from ssr
8865
8866 \param - dev - Pointer to the net device.
8867 - addr - Pointer to the sockaddr.
8868 \return - 0 for success, non zero for failure
8869
8870 --------------------------------------------------------------------------*/
8871static int hdd_set_mac_address(struct net_device *dev, void *addr)
8872{
8873 int ret;
8874
8875 vos_ssr_protect(__func__);
8876 ret = __hdd_set_mac_address(dev, addr);
8877 vos_ssr_unprotect(__func__);
8878
8879 return ret;
8880}
8881
Jeff Johnson295189b2012-06-20 16:38:30 -07008882tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
8883{
8884 int i;
8885 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8886 {
Abhishek Singheb183782014-02-06 13:37:21 +05308887 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008888 break;
8889 }
8890
8891 if( VOS_MAX_CONCURRENCY_PERSONA == i)
8892 return NULL;
8893
8894 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
8895 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
8896}
8897
8898void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
8899{
8900 int i;
8901 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8902 {
8903 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
8904 {
8905 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
8906 break;
8907 }
8908 }
8909 return;
8910}
8911
8912#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
8913 static struct net_device_ops wlan_drv_ops = {
8914 .ndo_open = hdd_open,
8915 .ndo_stop = hdd_stop,
8916 .ndo_uninit = hdd_uninit,
8917 .ndo_start_xmit = hdd_hard_start_xmit,
8918 .ndo_tx_timeout = hdd_tx_timeout,
8919 .ndo_get_stats = hdd_stats,
8920 .ndo_do_ioctl = hdd_ioctl,
8921 .ndo_set_mac_address = hdd_set_mac_address,
8922 .ndo_select_queue = hdd_select_queue,
8923#ifdef WLAN_FEATURE_PACKET_FILTERING
8924#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
8925 .ndo_set_rx_mode = hdd_set_multicast_list,
8926#else
8927 .ndo_set_multicast_list = hdd_set_multicast_list,
8928#endif //LINUX_VERSION_CODE
8929#endif
8930 };
Jeff Johnson295189b2012-06-20 16:38:30 -07008931 static struct net_device_ops wlan_mon_drv_ops = {
8932 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05308933 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07008934 .ndo_uninit = hdd_uninit,
8935 .ndo_start_xmit = hdd_mon_hard_start_xmit,
8936 .ndo_tx_timeout = hdd_tx_timeout,
8937 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05308938 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07008939 .ndo_set_mac_address = hdd_set_mac_address,
8940 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308941
Jeff Johnson295189b2012-06-20 16:38:30 -07008942#endif
8943
8944void hdd_set_station_ops( struct net_device *pWlanDev )
8945{
8946#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07008947 pWlanDev->netdev_ops = &wlan_drv_ops;
8948#else
8949 pWlanDev->open = hdd_open;
8950 pWlanDev->stop = hdd_stop;
8951 pWlanDev->uninit = hdd_uninit;
8952 pWlanDev->hard_start_xmit = NULL;
8953 pWlanDev->tx_timeout = hdd_tx_timeout;
8954 pWlanDev->get_stats = hdd_stats;
8955 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07008956 pWlanDev->set_mac_address = hdd_set_mac_address;
8957#endif
8958}
8959
Katya Nigam1fd24402015-02-16 14:52:19 +05308960void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
8961{
8962 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
8963 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
8964 #else
8965 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
8966 #endif
8967}
8968
Jeff Johnsoneed415b2013-01-18 16:11:20 -08008969static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07008970{
8971 struct net_device *pWlanDev = NULL;
8972 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008973 /*
8974 * cfg80211 initialization and registration....
8975 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05308976 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
8977#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
8978 NET_NAME_UNKNOWN,
8979#endif
8980 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07008981 if(pWlanDev != NULL)
8982 {
8983
8984 //Save the pointer to the net_device in the HDD adapter
8985 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
8986
Jeff Johnson295189b2012-06-20 16:38:30 -07008987 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
8988
8989 pAdapter->dev = pWlanDev;
8990 pAdapter->pHddCtx = pHddCtx;
8991 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05308992 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07008993
Rajeev79dbe4c2013-10-05 11:03:42 +05308994#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05308995 pAdapter->pBatchScanRsp = NULL;
8996 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07008997 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08008998 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05308999 mutex_init(&pAdapter->hdd_batch_scan_lock);
9000#endif
9001
Jeff Johnson295189b2012-06-20 16:38:30 -07009002 pAdapter->isLinkUpSvcNeeded = FALSE;
9003 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
9004 //Init the net_device structure
9005 strlcpy(pWlanDev->name, name, IFNAMSIZ);
9006
9007 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
9008 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
9009 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
9010 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
9011
9012 hdd_set_station_ops( pAdapter->dev );
9013
9014 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009015 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
9016 pAdapter->wdev.wiphy = pHddCtx->wiphy;
9017 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009018 /* set pWlanDev's parent to underlying device */
9019 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07009020
9021 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009022 }
9023
9024 return pAdapter;
9025}
9026
9027VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
9028{
9029 struct net_device *pWlanDev = pAdapter->dev;
9030 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
9031 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9032 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
9033
9034 if( rtnl_lock_held )
9035 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08009036 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07009037 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
9038 {
9039 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
9040 return VOS_STATUS_E_FAILURE;
9041 }
9042 }
9043 if (register_netdevice(pWlanDev))
9044 {
9045 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
9046 return VOS_STATUS_E_FAILURE;
9047 }
9048 }
9049 else
9050 {
9051 if(register_netdev(pWlanDev))
9052 {
9053 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
9054 return VOS_STATUS_E_FAILURE;
9055 }
9056 }
9057 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
9058
9059 return VOS_STATUS_SUCCESS;
9060}
9061
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009062static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07009063{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009064 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009065
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009066 if (NULL == pAdapter)
9067 {
9068 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
9069 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07009070 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009071
9072 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
9073 {
9074 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
9075 return eHAL_STATUS_NOT_INITIALIZED;
9076 }
9077
9078 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
9079
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009080#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009081 /* need to make sure all of our scheduled work has completed.
9082 * This callback is called from MC thread context, so it is safe to
9083 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009084 *
9085 * Even though this is called from MC thread context, if there is a faulty
9086 * work item in the system, that can hang this call forever. So flushing
9087 * this global work queue is not safe; and now we make sure that
9088 * individual work queues are stopped correctly. But the cancel work queue
9089 * is a GPL only API, so the proprietary version of the driver would still
9090 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009091 */
9092 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009093#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009094
9095 /* We can be blocked while waiting for scheduled work to be
9096 * flushed, and the adapter structure can potentially be freed, in
9097 * which case the magic will have been reset. So make sure the
9098 * magic is still good, and hence the adapter structure is still
9099 * valid, before signaling completion */
9100 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
9101 {
9102 complete(&pAdapter->session_close_comp_var);
9103 }
9104
Jeff Johnson295189b2012-06-20 16:38:30 -07009105 return eHAL_STATUS_SUCCESS;
9106}
Manjeet Singh47ee8472016-04-11 11:57:18 +05309107/**
9108 * hdd_close_tx_queues() - close tx queues
9109 * @hdd_ctx: hdd global context
9110 *
9111 * Return: None
9112 */
9113static void hdd_close_tx_queues(hdd_context_t *hdd_ctx)
9114{
9115 VOS_STATUS status;
9116 hdd_adapter_t *adapter;
9117 hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter = NULL;
9118 /* Not validating hdd_ctx as it's already done by the caller */
9119 ENTER();
9120 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
9121 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
9122 adapter = adapter_node->pAdapter;
9123 if (adapter && adapter->dev) {
9124 netif_tx_disable (adapter->dev);
9125 netif_carrier_off(adapter->dev);
9126 }
9127 status = hdd_get_next_adapter(hdd_ctx, adapter_node,
9128 &next_adapter);
9129 adapter_node = next_adapter;
9130 }
9131 EXIT();
9132}
Jeff Johnson295189b2012-06-20 16:38:30 -07009133
9134VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
9135{
9136 struct net_device *pWlanDev = pAdapter->dev;
9137 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
9138 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9139 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
9140 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309141 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009142
Nirav Shah7e3c8132015-06-22 23:51:42 +05309143 spin_lock_init( &pAdapter->sta_hash_lock);
9144 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
9145
Jeff Johnson295189b2012-06-20 16:38:30 -07009146 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07009147 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009148 //Open a SME session for future operation
9149 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07009150 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009151 if ( !HAL_STATUS_SUCCESS( halStatus ) )
9152 {
9153 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009154 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009155 halStatus, halStatus );
9156 status = VOS_STATUS_E_FAILURE;
9157 goto error_sme_open;
9158 }
9159
9160 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05309161 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009162 &pAdapter->session_open_comp_var,
9163 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309164 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009165 {
9166 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309167 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07009168 status = VOS_STATUS_E_FAILURE;
9169 goto error_sme_open;
9170 }
9171
9172 // Register wireless extensions
9173 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
9174 {
9175 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009176 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009177 halStatus, halStatus );
9178 status = VOS_STATUS_E_FAILURE;
9179 goto error_register_wext;
9180 }
Katya Nigam1fd24402015-02-16 14:52:19 +05309181
Jeff Johnson295189b2012-06-20 16:38:30 -07009182 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05309183 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
9184 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
9185 #else
9186 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
9187 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009188
9189 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05309190 hddLog(VOS_TRACE_LEVEL_INFO,
9191 "%s: Set HDD connState to eConnectionState_NotConnected",
9192 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009193 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
9194
9195 //Set the default operation channel
9196 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
9197
9198 /* Make the default Auth Type as OPEN*/
9199 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9200
9201 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
9202 {
9203 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009204 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009205 status, status );
9206 goto error_init_txrx;
9207 }
9208
9209 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9210
9211 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
9212 {
9213 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009214 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009215 status, status );
9216 goto error_wmm_init;
9217 }
9218
9219 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9220
9221 return VOS_STATUS_SUCCESS;
9222
9223error_wmm_init:
9224 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9225 hdd_deinit_tx_rx(pAdapter);
9226error_init_txrx:
9227 hdd_UnregisterWext(pWlanDev);
9228error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009229 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009230 {
9231 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009232 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05309233 pAdapter->sessionId, FALSE, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009234 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07009235 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309236 unsigned long rc;
9237
Jeff Johnson295189b2012-06-20 16:38:30 -07009238 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309239 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009240 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009241 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309242 if (rc <= 0)
9243 hddLog(VOS_TRACE_LEVEL_ERROR,
9244 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009245 }
9246}
9247error_sme_open:
9248 return status;
9249}
9250
Jeff Johnson295189b2012-06-20 16:38:30 -07009251void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
9252{
9253 hdd_cfg80211_state_t *cfgState;
9254
9255 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
9256
9257 if( NULL != cfgState->buf )
9258 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309259 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07009260 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
9261 rc = wait_for_completion_interruptible_timeout(
9262 &pAdapter->tx_action_cnf_event,
9263 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309264 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009265 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05309266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9267 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
9268 , __func__, rc);
9269
9270 // Inform tx status as FAILURE to upper layer and free cfgState->buf
9271 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009272 }
9273 }
9274 return;
9275}
Jeff Johnson295189b2012-06-20 16:38:30 -07009276
c_hpothu002231a2015-02-05 14:58:51 +05309277void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07009278{
9279 ENTER();
9280 switch ( pAdapter->device_mode )
9281 {
Katya Nigam1fd24402015-02-16 14:52:19 +05309282 case WLAN_HDD_IBSS:
9283 {
9284 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9285 {
9286 hdd_ibss_deinit_tx_rx( pAdapter );
9287 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9288 }
9289 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009290 case WLAN_HDD_INFRA_STATION:
9291 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009292 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009293 {
9294 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9295 {
9296 hdd_deinit_tx_rx( pAdapter );
9297 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9298 }
9299
9300 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9301 {
9302 hdd_wmm_adapter_close( pAdapter );
9303 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9304 }
9305
Jeff Johnson295189b2012-06-20 16:38:30 -07009306 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009307 break;
9308 }
9309
9310 case WLAN_HDD_SOFTAP:
9311 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009312 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05309313
9314 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9315 {
9316 hdd_wmm_adapter_close( pAdapter );
9317 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9318 }
9319
Jeff Johnson295189b2012-06-20 16:38:30 -07009320 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009321
c_hpothu002231a2015-02-05 14:58:51 +05309322 hdd_unregister_hostapd(pAdapter, rtnl_held);
Agrawal Ashisha0584d42016-09-29 13:03:45 +05309323 /* set con_mode to STA only when no SAP concurrency mode */
9324 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
9325 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07009326 break;
9327 }
9328
9329 case WLAN_HDD_MONITOR:
9330 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009331 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9332 {
9333 hdd_deinit_tx_rx( pAdapter );
9334 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9335 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009336 break;
9337 }
9338
9339
9340 default:
9341 break;
9342 }
9343
9344 EXIT();
9345}
9346
9347void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
9348{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08009349 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309350
9351 ENTER();
9352 if (NULL == pAdapter)
9353 {
9354 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9355 "%s: HDD adapter is Null", __func__);
9356 return;
9357 }
9358
9359 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009360
Rajeev79dbe4c2013-10-05 11:03:42 +05309361#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309362 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
9363 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08009364 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309365 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
9366 )
9367 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08009368 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05309369 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08009370 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
9371 {
9372 hdd_deinit_batch_scan(pAdapter);
9373 }
Rajeev79dbe4c2013-10-05 11:03:42 +05309374 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08009375 }
Rajeev79dbe4c2013-10-05 11:03:42 +05309376#endif
9377
Jeff Johnson295189b2012-06-20 16:38:30 -07009378 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
9379 if( rtnl_held )
9380 {
9381 unregister_netdevice(pWlanDev);
9382 }
9383 else
9384 {
9385 unregister_netdev(pWlanDev);
9386 }
9387 // note that the pAdapter is no longer valid at this point
9388 // since the memory has been reclaimed
9389 }
9390
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309391 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009392}
9393
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009394void hdd_set_pwrparams(hdd_context_t *pHddCtx)
9395{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309396 VOS_STATUS status;
9397 hdd_adapter_t *pAdapter = NULL;
9398 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009399
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309400 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009401
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309402 /*loop through all adapters.*/
9403 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009404 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309405 pAdapter = pAdapterNode->pAdapter;
9406 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
9407 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009408
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309409 { // we skip this registration for modes other than STA and P2P client modes.
9410 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9411 pAdapterNode = pNext;
9412 continue;
9413 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009414
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309415 //Apply Dynamic DTIM For P2P
9416 //Only if ignoreDynamicDtimInP2pMode is not set in ini
9417 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
9418 pHddCtx->cfg_ini->enableModulatedDTIM) &&
9419 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9420 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
9421 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
9422 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
9423 (eConnectionState_Associated ==
9424 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
9425 (pHddCtx->cfg_ini->fIsBmpsEnabled))
9426 {
9427 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009428
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309429 powerRequest.uIgnoreDTIM = 1;
9430 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
9431
9432 if (pHddCtx->cfg_ini->enableModulatedDTIM)
9433 {
9434 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
9435 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
9436 }
9437 else
9438 {
9439 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
9440 }
9441
9442 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
9443 * specified during Enter/Exit BMPS when LCD off*/
9444 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
9445 NULL, eANI_BOOLEAN_FALSE);
9446 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
9447 NULL, eANI_BOOLEAN_FALSE);
9448
9449 /* switch to the DTIM specified in cfg.ini */
9450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05309451 "Switch to DTIM %d Listen interval %d",
9452 powerRequest.uDTIMPeriod,
9453 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309454 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
9455 break;
9456
9457 }
9458
9459 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9460 pAdapterNode = pNext;
9461 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009462}
9463
9464void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
9465{
9466 /*Switch back to DTIM 1*/
9467 tSirSetPowerParamsReq powerRequest = { 0 };
9468
9469 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
9470 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07009471 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009472
9473 /* Update ignoreDTIM and ListedInterval in CFG with default values */
9474 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
9475 NULL, eANI_BOOLEAN_FALSE);
9476 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
9477 NULL, eANI_BOOLEAN_FALSE);
9478
9479 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9480 "Switch to DTIM%d",powerRequest.uListenInterval);
9481 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
9482
9483}
9484
Jeff Johnson295189b2012-06-20 16:38:30 -07009485VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
9486{
9487 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05309488 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
9489 {
9490 hddLog( LOGE, FL("Wlan Unload in progress"));
9491 return VOS_STATUS_E_PERM;
9492 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309493
9494 if (wlan_hdd_check_monitor_state(pHddCtx)) {
9495 hddLog(LOG1, FL("Monitor mode is started, cannot enable BMPS"));
9496 return VOS_STATUS_SUCCESS;
9497 }
9498
Jeff Johnson295189b2012-06-20 16:38:30 -07009499 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
9500 {
9501 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
9502 }
9503
9504 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
9505 {
9506 sme_StartAutoBmpsTimer(pHddCtx->hHal);
9507 }
9508
9509 if (pHddCtx->cfg_ini->fIsImpsEnabled)
9510 {
9511 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
9512 }
9513
9514 return status;
9515}
9516
9517VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
9518{
9519 hdd_adapter_t *pAdapter = NULL;
9520 eHalStatus halStatus;
9521 VOS_STATUS status = VOS_STATUS_E_INVAL;
9522 v_BOOL_t disableBmps = FALSE;
9523 v_BOOL_t disableImps = FALSE;
9524
9525 switch(session_type)
9526 {
9527 case WLAN_HDD_INFRA_STATION:
9528 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07009529 case WLAN_HDD_P2P_CLIENT:
9530 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009531 //Exit BMPS -> Is Sta/P2P Client is already connected
9532 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
9533 if((NULL != pAdapter)&&
9534 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9535 {
9536 disableBmps = TRUE;
9537 }
9538
9539 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
9540 if((NULL != pAdapter)&&
9541 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9542 {
9543 disableBmps = TRUE;
9544 }
9545
9546 //Exit both Bmps and Imps incase of Go/SAP Mode
9547 if((WLAN_HDD_SOFTAP == session_type) ||
9548 (WLAN_HDD_P2P_GO == session_type))
9549 {
9550 disableBmps = TRUE;
9551 disableImps = TRUE;
9552 }
9553
9554 if(TRUE == disableImps)
9555 {
9556 if (pHddCtx->cfg_ini->fIsImpsEnabled)
9557 {
9558 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
9559 }
9560 }
9561
9562 if(TRUE == disableBmps)
9563 {
9564 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
9565 {
9566 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
9567
9568 if(eHAL_STATUS_SUCCESS != halStatus)
9569 {
9570 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009571 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009572 VOS_ASSERT(0);
9573 return status;
9574 }
9575 }
9576
9577 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
9578 {
9579 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
9580
9581 if(eHAL_STATUS_SUCCESS != halStatus)
9582 {
9583 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009584 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009585 VOS_ASSERT(0);
9586 return status;
9587 }
9588 }
9589 }
9590
9591 if((TRUE == disableBmps) ||
9592 (TRUE == disableImps))
9593 {
9594 /* Now, get the chip into Full Power now */
9595 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
9596 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
9597 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
9598
9599 if(halStatus != eHAL_STATUS_SUCCESS)
9600 {
9601 if(halStatus == eHAL_STATUS_PMC_PENDING)
9602 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309603 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009604 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309605 ret = wait_for_completion_interruptible_timeout(
9606 &pHddCtx->full_pwr_comp_var,
9607 msecs_to_jiffies(1000));
9608 if (ret <= 0)
9609 {
9610 hddLog(VOS_TRACE_LEVEL_ERROR,
9611 "%s: wait on full_pwr_comp_var failed %ld",
9612 __func__, ret);
9613 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009614 }
9615 else
9616 {
9617 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009618 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009619 VOS_ASSERT(0);
9620 return status;
9621 }
9622 }
9623
9624 status = VOS_STATUS_SUCCESS;
9625 }
9626
9627 break;
9628 }
9629 return status;
9630}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309631
9632void hdd_monPostMsgCb(tANI_U32 *magic, struct completion *cmpVar)
9633{
9634 if (magic == NULL || cmpVar == NULL) {
9635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07009636 FL("invalid arguments %pK %pK"), magic, cmpVar);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309637 return;
9638 }
9639 if (*magic != MON_MODE_MSG_MAGIC) {
9640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9641 FL("maic: %x"), *magic);
9642 return;
9643 }
9644
9645 complete(cmpVar);
9646 return;
9647}
9648
Katya Nigame7b69a82015-04-28 15:24:06 +05309649void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
9650 {
9651 hdd_mon_ctx_t *pMonCtx = NULL;
Katya Nigame7b69a82015-04-28 15:24:06 +05309652
Rajeev Kumar Sirasanagandla54447612018-03-06 15:49:56 +05309653 spin_lock_init(&pAdapter->sta_hash_lock);
9654 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
9655
9656 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
Katya Nigame7b69a82015-04-28 15:24:06 +05309657 pMonCtx->state = 0;
9658 pMonCtx->ChannelNo = 1;
9659 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05309660 pMonCtx->crcCheckEnabled = 1;
9661 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
9662 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05309663 pMonCtx->numOfMacFilters = 0;
9664 }
9665
Jeff Johnson295189b2012-06-20 16:38:30 -07009666
9667hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08009668 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07009669 tANI_U8 rtnl_held )
9670{
9671 hdd_adapter_t *pAdapter = NULL;
9672 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
9673 VOS_STATUS status = VOS_STATUS_E_FAILURE;
9674 VOS_STATUS exitbmpsStatus;
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309675 v_CONTEXT_t pVosContext = NULL;
9676
9677 /* No need to check for NULL, reaching this step
9678 * means vos context is initialized
9679 */
9680 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009681
Arif Hussain6d2a3322013-11-17 19:50:10 -08009682 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009683
Nirav Shah436658f2014-02-28 17:05:45 +05309684 if(macAddr == NULL)
9685 {
9686 /* Not received valid macAddr */
9687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9688 "%s:Unable to add virtual intf: Not able to get"
9689 "valid mac address",__func__);
9690 return NULL;
9691 }
9692
Jeff Johnson295189b2012-06-20 16:38:30 -07009693 //Disable BMPS incase of Concurrency
9694 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
9695
9696 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
9697 {
9698 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309699 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009700 VOS_ASSERT(0);
9701 return NULL;
9702 }
9703
9704 switch(session_type)
9705 {
9706 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07009707 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009708 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009709 {
9710 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9711
9712 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309713 {
9714 hddLog(VOS_TRACE_LEVEL_FATAL,
9715 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009716 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309717 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009718
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309719#ifdef FEATURE_WLAN_TDLS
9720 /* A Mutex Lock is introduced while changing/initializing the mode to
9721 * protect the concurrent access for the Adapters by TDLS module.
9722 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309723 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309724#endif
9725
Jeff Johnsone7245742012-09-05 17:12:55 -07009726 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
9727 NL80211_IFTYPE_P2P_CLIENT:
9728 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07009729
Jeff Johnson295189b2012-06-20 16:38:30 -07009730 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309731#ifdef FEATURE_WLAN_TDLS
9732 mutex_unlock(&pHddCtx->tdls_lock);
9733#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05309734
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309735 hdd_initialize_adapter_common(pAdapter);
Sunil Dutt66485cb2013-12-19 19:05:03 +05309736 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009737 if( VOS_STATUS_SUCCESS != status )
9738 goto err_free_netdev;
9739
9740 status = hdd_register_interface( pAdapter, rtnl_held );
9741 if( VOS_STATUS_SUCCESS != status )
9742 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05309743#ifdef FEATURE_WLAN_TDLS
9744 mutex_lock(&pHddCtx->tdls_lock);
9745#endif
c_hpothu002231a2015-02-05 14:58:51 +05309746 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05309747#ifdef FEATURE_WLAN_TDLS
9748 mutex_unlock(&pHddCtx->tdls_lock);
9749#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009750 goto err_free_netdev;
9751 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309752
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05309753 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309754 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05309755
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309756#ifdef WLAN_NS_OFFLOAD
9757 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309758 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309759#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009760 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309761 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009762 netif_tx_disable(pAdapter->dev);
9763 //netif_tx_disable(pWlanDev);
9764 netif_carrier_off(pAdapter->dev);
9765
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309766 if (WLAN_HDD_P2P_CLIENT == session_type ||
9767 WLAN_HDD_P2P_DEVICE == session_type)
9768 {
9769 /* Initialize the work queue to defer the
9770 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309771 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309772 hdd_p2p_roc_work_queue);
9773 }
9774
Jeff Johnson295189b2012-06-20 16:38:30 -07009775 break;
9776 }
9777
Jeff Johnson295189b2012-06-20 16:38:30 -07009778 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009779 case WLAN_HDD_SOFTAP:
9780 {
9781 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
9782 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309783 {
9784 hddLog(VOS_TRACE_LEVEL_FATAL,
9785 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009786 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309787 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009788
Jeff Johnson295189b2012-06-20 16:38:30 -07009789 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
9790 NL80211_IFTYPE_AP:
9791 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009792 pAdapter->device_mode = session_type;
9793
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309794 hdd_initialize_adapter_common(pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +05309795 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -07009796 if( VOS_STATUS_SUCCESS != status )
9797 goto err_free_netdev;
9798
Nirav Shah7e3c8132015-06-22 23:51:42 +05309799 status = hdd_sta_id_hash_attach(pAdapter);
9800 if (VOS_STATUS_SUCCESS != status)
9801 {
9802 hddLog(VOS_TRACE_LEVEL_FATAL,
9803 FL("failed to attach hash for session %d"), session_type);
9804 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
9805 goto err_free_netdev;
9806 }
9807
Jeff Johnson295189b2012-06-20 16:38:30 -07009808 status = hdd_register_hostapd( pAdapter, rtnl_held );
9809 if( VOS_STATUS_SUCCESS != status )
9810 {
c_hpothu002231a2015-02-05 14:58:51 +05309811 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07009812 goto err_free_netdev;
9813 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309814 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009815 netif_tx_disable(pAdapter->dev);
9816 netif_carrier_off(pAdapter->dev);
9817
9818 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309819
Hanumanth Reddy Pothulab4537b82018-03-02 12:20:38 +05309820 // Workqueue which gets scheduled in IPv4 notification callback.
9821 vos_init_work(&pAdapter->ipv4NotifierWorkQueue,
9822 hdd_ipv4_notifier_work_queue);
9823
9824#ifdef WLAN_NS_OFFLOAD
9825 // Workqueue which gets scheduled in IPv6 notification callback.
9826 vos_init_work(&pAdapter->ipv6NotifierWorkQueue,
9827 hdd_ipv6_notifier_work_queue);
9828#endif
9829
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309830 if (WLAN_HDD_P2P_GO == session_type)
9831 {
9832 /* Initialize the work queue to
9833 * defer the back to back RoC request */
9834 INIT_DELAYED_WORK(&pAdapter->roc_work,
9835 hdd_p2p_roc_work_queue);
9836 }
Bhargav Shahd0715912015-10-01 18:17:37 +05309837
Jeff Johnson295189b2012-06-20 16:38:30 -07009838 break;
9839 }
9840 case WLAN_HDD_MONITOR:
9841 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009842 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9843 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309844 {
9845 hddLog(VOS_TRACE_LEVEL_FATAL,
9846 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009847 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309848 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009849
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309850 pAdapter->device_mode = session_type;
9851 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
9852
Katya Nigame7b69a82015-04-28 15:24:06 +05309853 // Register wireless extensions
9854 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
9855 {
9856 hddLog(VOS_TRACE_LEVEL_FATAL,
9857 "hdd_register_wext() failed with status code %08d [x%08x]",
9858 status, status );
9859 status = VOS_STATUS_E_FAILURE;
9860 }
9861
Jeff Johnson295189b2012-06-20 16:38:30 -07009862#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
9863 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
9864#else
9865 pAdapter->dev->open = hdd_mon_open;
9866 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05309867 pAdapter->dev->stop = hdd_mon_stop;
9868 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07009869#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05309870 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309871 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009872 hdd_init_tx_rx( pAdapter );
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309873
9874 if (VOS_MONITOR_MODE != hdd_get_conparam())
9875 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9876
Jeff Johnson295189b2012-06-20 16:38:30 -07009877 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309878 status = hdd_register_interface( pAdapter, rtnl_held );
Katya Nigame7b69a82015-04-28 15:24:06 +05309879 //Stop the Interface TX queue.
9880 netif_tx_disable(pAdapter->dev);
9881 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009882 }
9883 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009884 case WLAN_HDD_FTM:
9885 {
9886 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9887
9888 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309889 {
9890 hddLog(VOS_TRACE_LEVEL_FATAL,
9891 FL("failed to allocate adapter for session %d"), session_type);
9892 return NULL;
9893 }
9894
Jeff Johnson295189b2012-06-20 16:38:30 -07009895 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
9896 * message while loading driver in FTM mode. */
9897 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
9898 pAdapter->device_mode = session_type;
9899 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309900
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309901 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309902 hdd_init_tx_rx( pAdapter );
9903
9904 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309905 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309906 netif_tx_disable(pAdapter->dev);
9907 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009908 }
9909 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009910 default:
9911 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309912 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
9913 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009914 VOS_ASSERT(0);
9915 return NULL;
9916 }
9917 }
9918
Jeff Johnson295189b2012-06-20 16:38:30 -07009919 if( VOS_STATUS_SUCCESS == status )
9920 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309921 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -07009922 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
9923 if( NULL == pHddAdapterNode )
9924 {
9925 status = VOS_STATUS_E_NOMEM;
9926 }
9927 else
9928 {
9929 pHddAdapterNode->pAdapter = pAdapter;
9930 status = hdd_add_adapter_back ( pHddCtx,
9931 pHddAdapterNode );
9932 }
9933 }
9934
9935 if( VOS_STATUS_SUCCESS != status )
9936 {
9937 if( NULL != pAdapter )
9938 {
9939 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
9940 pAdapter = NULL;
9941 }
9942 if( NULL != pHddAdapterNode )
9943 {
9944 vos_mem_free( pHddAdapterNode );
9945 }
9946
9947 goto resume_bmps;
9948 }
9949
9950 if(VOS_STATUS_SUCCESS == status)
9951 {
9952 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07009953 //Initialize the WoWL service
9954 if(!hdd_init_wowl(pAdapter))
9955 {
9956 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
9957 goto err_free_netdev;
9958 }
Manjeet Singh3ed79242017-01-11 19:04:32 +05309959 //Initialize the TSF capture data
9960 wlan_hdd_tsf_init(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009961 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009962 return pAdapter;
9963
9964err_free_netdev:
9965 free_netdev(pAdapter->dev);
9966 wlan_hdd_release_intf_addr( pHddCtx,
9967 pAdapter->macAddressCurrent.bytes );
9968
9969resume_bmps:
9970 //If bmps disabled enable it
9971 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
9972 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309973 if (pHddCtx->hdd_wlan_suspended)
9974 {
9975 hdd_set_pwrparams(pHddCtx);
9976 }
9977 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009978 }
9979 return NULL;
9980}
9981
9982VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
9983 tANI_U8 rtnl_held )
9984{
9985 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
9986 VOS_STATUS status;
9987
9988 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
9989 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309990 {
9991 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
9992 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009993 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309994 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009995
9996 while ( pCurrent->pAdapter != pAdapter )
9997 {
9998 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
9999 if( VOS_STATUS_SUCCESS != status )
10000 break;
10001
10002 pCurrent = pNext;
10003 }
10004 pAdapterNode = pCurrent;
10005 if( VOS_STATUS_SUCCESS == status )
10006 {
10007 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10008 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010009
10010#ifdef FEATURE_WLAN_TDLS
10011
10012 /* A Mutex Lock is introduced while changing/initializing the mode to
10013 * protect the concurrent access for the Adapters by TDLS module.
10014 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010015 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010016#endif
10017
Jeff Johnson295189b2012-06-20 16:38:30 -070010018 hdd_remove_adapter( pHddCtx, pAdapterNode );
10019 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080010020 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010021
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010022#ifdef FEATURE_WLAN_TDLS
10023 mutex_unlock(&pHddCtx->tdls_lock);
10024#endif
10025
Jeff Johnson295189b2012-06-20 16:38:30 -070010026
10027 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +053010028 if ((!vos_concurrent_open_sessions_running()) &&
10029 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
10030 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010031 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010032 if (pHddCtx->hdd_wlan_suspended)
10033 {
10034 hdd_set_pwrparams(pHddCtx);
10035 }
10036 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010037 }
10038
10039 return VOS_STATUS_SUCCESS;
10040 }
10041
10042 return VOS_STATUS_E_FAILURE;
10043}
10044
10045VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
10046{
10047 hdd_adapter_list_node_t *pHddAdapterNode;
10048 VOS_STATUS status;
10049
10050 ENTER();
10051
10052 do
10053 {
10054 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
10055 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
10056 {
10057 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
10058 vos_mem_free( pHddAdapterNode );
10059 }
10060 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
10061
10062 EXIT();
10063
10064 return VOS_STATUS_SUCCESS;
10065}
10066
10067void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
10068{
10069 v_U8_t addIE[1] = {0};
10070
10071 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10072 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
10073 eANI_BOOLEAN_FALSE) )
10074 {
10075 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010076 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010077 }
10078
10079 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10080 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10081 eANI_BOOLEAN_FALSE) )
10082 {
10083 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010084 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010085 }
10086
10087 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10088 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10089 eANI_BOOLEAN_FALSE) )
10090 {
10091 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010092 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010093 }
10094}
10095
Anurag Chouhan83026002016-12-13 22:46:21 +053010096VOS_STATUS hdd_cleanup_ap_events(hdd_adapter_t *adapter)
10097{
10098#ifdef DHCP_SERVER_OFFLOAD
10099 vos_event_destroy(&adapter->dhcp_status.vos_event);
10100#endif
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010101#ifdef MDNS_OFFLOAD
10102 vos_event_destroy(&adapter->mdns_status.vos_event);
10103#endif
Anurag Chouhan83026002016-12-13 22:46:21 +053010104 return VOS_STATUS_SUCCESS;
10105}
10106
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010107int wlan_hdd_stop_mon(hdd_context_t *hdd_ctx, bool wait)
10108{
10109 hdd_mon_ctx_t *mon_ctx;
10110 long ret;
10111 v_U32_t magic;
10112 struct completion cmp_var;
10113 void (*func_ptr)(tANI_U32 *magic, struct completion *cmpVar) = NULL;
10114 hdd_adapter_t *adapter;
10115
10116 adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
10117 if (!adapter) {
10118 hddLog(LOGE, FL("Invalid STA + MON mode"));
10119 return -EINVAL;
10120 }
10121
10122 mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(adapter);
10123 if (!mon_ctx)
10124 return 0;
10125
10126 if (mon_ctx->state != MON_MODE_START)
10127 return 0;
10128
10129 mon_ctx->state = MON_MODE_STOP;
10130 if (wait) {
10131 func_ptr = hdd_monPostMsgCb;
10132 magic = MON_MODE_MSG_MAGIC;
10133 init_completion(&cmp_var);
10134 }
10135
10136 if (VOS_STATUS_SUCCESS != wlan_hdd_mon_postMsg(&magic, &cmp_var,
10137 mon_ctx,
10138 hdd_monPostMsgCb)) {
10139 hddLog(LOGE, FL("failed to stop MON MODE"));
10140 mon_ctx->state = MON_MODE_START;
10141 magic = 0;
10142 return -EINVAL;
10143 }
10144
10145 if (!wait)
10146 goto bmps_roaming;
10147
10148 ret = wait_for_completion_timeout(&cmp_var, MON_MODE_MSG_TIMEOUT);
10149 magic = 0;
10150 if (ret <= 0 ) {
10151 hddLog(LOGE,
10152 FL("timeout on stop monitor mode completion %ld"), ret);
10153 return -EINVAL;
10154 }
10155
10156bmps_roaming:
10157 hddLog(LOG1, FL("Enable BMPS"));
10158 hdd_enable_bmps_imps(hdd_ctx);
10159 hdd_restore_roaming(hdd_ctx);
10160
10161 return 0;
10162}
10163
10164bool wlan_hdd_check_monitor_state(hdd_context_t *hdd_ctx)
10165{
10166 hdd_adapter_t *mon_adapter;
10167 hdd_mon_ctx_t *mon_ctx;
10168
10169 if (hdd_ctx->concurrency_mode != VOS_STA_MON)
10170 return false;
10171
10172 mon_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
10173 if (!mon_adapter) {
10174 hddLog(LOGE, FL("Invalid concurrency mode"));
10175 return false;
10176 }
10177
10178 mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(mon_adapter);
10179 if (mon_ctx->state == MON_MODE_START)
10180 return true;
10181
10182 return false;
10183}
10184
10185int wlan_hdd_check_and_stop_mon(hdd_adapter_t *sta_adapter, bool wait)
10186{
10187 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(sta_adapter);
10188
10189 if ((sta_adapter->device_mode != WLAN_HDD_INFRA_STATION) ||
10190 !wlan_hdd_check_monitor_state(hdd_ctx))
10191 return 0;
10192
10193 if (wlan_hdd_stop_mon(hdd_ctx, wait))
10194 return -EINVAL;
10195
10196 return 0;
10197}
10198
10199void hdd_disable_roaming(hdd_context_t *hdd_ctx)
10200{
10201 if (!hdd_ctx)
10202 return;
10203
10204 if (!hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled) {
10205 hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
10206 return;
10207 }
10208
10209 hddLog(LOG1, FL("Disable driver and firmware roaming"));
10210
10211 hdd_ctx->roaming_ini_original =
10212 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled;
10213
10214 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
10215 CFG_LFR_FEATURE_ENABLED_MIN;
10216
10217 sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
10218 CFG_LFR_FEATURE_ENABLED_MIN);
10219}
10220
10221void hdd_restore_roaming(hdd_context_t *hdd_ctx)
10222{
10223 if (!hdd_ctx->roaming_ini_original)
10224 return;
10225
10226 hddLog(LOG1, FL("Enable driver and firmware roaming"));
10227
10228 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
10229 CFG_LFR_FEATURE_ENABLED_MAX;
10230
10231 hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
10232
10233 sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
10234 CFG_LFR_FEATURE_ENABLED_MAX);
10235}
Anurag Chouhan83026002016-12-13 22:46:21 +053010236
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010237VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
10238 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -070010239{
10240 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
10241 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010242 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010243 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010244 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010245 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +053010246 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010247
Anand N Sunkad26d71b92014-12-24 18:08:22 +053010248 if (pHddCtx->isLogpInProgress) {
10249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10250 "%s:LOGP in Progress. Ignore!!!",__func__);
10251 return VOS_STATUS_E_FAILURE;
10252 }
10253
Jeff Johnson295189b2012-06-20 16:38:30 -070010254 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010255
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010256 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -070010257 switch(pAdapter->device_mode)
10258 {
Nirav Shah0cf4d892015-11-05 16:27:27 +053010259 case WLAN_HDD_IBSS:
10260 if ( VOS_TRUE == bCloseSession )
10261 {
10262 status = hdd_sta_id_hash_detach(pAdapter);
10263 if (status != VOS_STATUS_SUCCESS)
10264 hddLog(VOS_TRACE_LEVEL_ERROR,
10265 FL("sta id hash detach failed"));
10266 }
10267
Jeff Johnson295189b2012-06-20 16:38:30 -070010268 case WLAN_HDD_INFRA_STATION:
10269 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -070010270 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010271 {
10272 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +053010273#ifdef FEATURE_WLAN_TDLS
10274 mutex_lock(&pHddCtx->tdls_lock);
10275 wlan_hdd_tdls_exit(pAdapter, TRUE);
10276 mutex_unlock(&pHddCtx->tdls_lock);
10277#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010278 if( hdd_connIsConnected(pstation) ||
10279 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010280 {
Abhishek Singhe21a5212017-06-09 09:42:58 +053010281 /*
10282 * Indicate sme of disconnect so that in progress connection
10283 * or preauth can be aborted.
10284 */
10285 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10286 pAdapter->sessionId);
Abhishek Singh99f17b82017-02-06 16:57:56 +053010287 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010288 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
10289 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
10290 pAdapter->sessionId,
10291 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
10292 else
10293 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
10294 pAdapter->sessionId,
10295 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Abhishek Singh7b52ed52016-02-11 17:45:54 +053010296 /* Success implies disconnect command got queued up successfully
10297 * Or cmd not queued as scan for SSID is in progress
10298 */
10299 if((eHAL_STATUS_SUCCESS == halStatus) ||
10300 (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -070010301 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010302 ret = wait_for_completion_interruptible_timeout(
10303 &pAdapter->disconnect_comp_var,
10304 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singh7b52ed52016-02-11 17:45:54 +053010305 if (ret <= 0 &&
10306 (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010307 {
10308 hddLog(VOS_TRACE_LEVEL_ERROR,
10309 "%s: wait on disconnect_comp_var failed %ld",
10310 __func__, ret);
10311 }
10312 }
10313 else
10314 {
10315 hddLog(LOGE, "%s: failed to post disconnect event to SME",
10316 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010317 }
10318 memset(&wrqu, '\0', sizeof(wrqu));
10319 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
10320 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
10321 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
10322 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010323 else if(pstation->conn_info.connState ==
10324 eConnectionState_Disconnecting)
10325 {
10326 ret = wait_for_completion_interruptible_timeout(
10327 &pAdapter->disconnect_comp_var,
10328 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10329 if (ret <= 0)
10330 {
10331 hddLog(VOS_TRACE_LEVEL_ERROR,
10332 FL("wait on disconnect_comp_var failed %ld"), ret);
10333 }
10334 }
Sachin Ahuja27dd2402016-08-01 20:30:31 +053010335 if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -070010336 {
Mahesh A Saptasagar0b61dcc2016-02-15 14:23:38 +053010337 wlan_hdd_scan_abort(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010338 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +053010339 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
10340 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010341 {
10342 while (pAdapter->is_roc_inprogress)
10343 {
10344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10345 "%s: ROC in progress for session %d!!!",
10346 __func__, pAdapter->sessionId);
10347 // waiting for ROC to expire
10348 msleep(500);
10349 /* In GO present case , if retry exceeds 3,
10350 it means something went wrong. */
10351 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
10352 {
10353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10354 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +053010355 if (eHAL_STATUS_SUCCESS !=
10356 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
10357 pAdapter->sessionId ))
10358 {
10359 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10360 FL("Failed to Cancel Remain on Channel"));
10361 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010362 wait_for_completion_interruptible_timeout(
10363 &pAdapter->cancel_rem_on_chan_var,
10364 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
10365 break;
10366 }
10367 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010368 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010369 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +053010370#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010371 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +053010372#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010373
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010374 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010375
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010376 /* It is possible that the caller of this function does not
10377 * wish to close the session
10378 */
10379 if (VOS_TRUE == bCloseSession &&
10380 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010381 {
10382 INIT_COMPLETION(pAdapter->session_close_comp_var);
10383 if (eHAL_STATUS_SUCCESS ==
Agrawal Ashish5a3522c2016-03-02 15:08:28 +053010384 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, FALSE,
10385 VOS_FALSE, hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010386 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010387 unsigned long ret;
10388
Jeff Johnson295189b2012-06-20 16:38:30 -070010389 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010390 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010391 &pAdapter->session_close_comp_var,
10392 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010393 if ( 0 >= ret)
10394 {
10395 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010396 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010397 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010398 }
10399 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010400 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010401 break;
10402
10403 case WLAN_HDD_SOFTAP:
10404 case WLAN_HDD_P2P_GO:
Nirav Shah0cf4d892015-11-05 16:27:27 +053010405 if ( VOS_TRUE == bCloseSession )
10406 {
10407 status = hdd_sta_id_hash_detach(pAdapter);
10408 if (status != VOS_STATUS_SUCCESS)
10409 hddLog(VOS_TRACE_LEVEL_ERROR,
10410 FL("sta id hash detach failed"));
10411 }
10412
Jeff Johnson295189b2012-06-20 16:38:30 -070010413 //Any softap specific cleanup here...
Anurag Chouhan83026002016-12-13 22:46:21 +053010414 hdd_cleanup_ap_events(pAdapter);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010415 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
10416 while (pAdapter->is_roc_inprogress) {
10417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10418 "%s: ROC in progress for session %d!!!",
10419 __func__, pAdapter->sessionId);
10420 msleep(500);
10421 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
10422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10423 "%s: ROC completion is not received.!!!", __func__);
10424 WLANSAP_CancelRemainOnChannel(
10425 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
10426 wait_for_completion_interruptible_timeout(
10427 &pAdapter->cancel_rem_on_chan_var,
10428 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
10429 break;
10430 }
10431 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +053010432
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010433 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010434 }
Agrawal Ashish17ef5082016-10-17 18:33:21 +053010435#ifdef SAP_AUTH_OFFLOAD
10436 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
10437 hdd_set_sap_auth_offload(pAdapter, FALSE);
10438#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010439 mutex_lock(&pHddCtx->sap_lock);
10440 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10441 {
10442 VOS_STATUS status;
10443 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10444
10445 //Stop Bss.
10446 status = WLANSAP_StopBss(pHddCtx->pvosContext);
10447 if (VOS_IS_STATUS_SUCCESS(status))
10448 {
10449 hdd_hostapd_state_t *pHostapdState =
10450 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10451
10452 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10453
10454 if (!VOS_IS_STATUS_SUCCESS(status))
10455 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010456 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
10457 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010458 }
10459 }
10460 else
10461 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010462 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010463 }
10464 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010465 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010466
10467 if (eHAL_STATUS_FAILURE ==
10468 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
10469 0, NULL, eANI_BOOLEAN_FALSE))
10470 {
10471 hddLog(LOGE,
10472 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010473 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010474 }
10475
10476 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
10477 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10478 eANI_BOOLEAN_FALSE) )
10479 {
10480 hddLog(LOGE,
10481 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
10482 }
10483
10484 // Reset WNI_CFG_PROBE_RSP Flags
10485 wlan_hdd_reset_prob_rspies(pAdapter);
10486 kfree(pAdapter->sessionCtx.ap.beacon);
10487 pAdapter->sessionCtx.ap.beacon = NULL;
10488 }
10489 mutex_unlock(&pHddCtx->sap_lock);
Hanumanth Reddy Pothulab4537b82018-03-02 12:20:38 +053010490
10491#ifdef WLAN_NS_OFFLOAD
10492 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
10493#endif
10494 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
10495
Jeff Johnson295189b2012-06-20 16:38:30 -070010496 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -070010497
Jeff Johnson295189b2012-06-20 16:38:30 -070010498 case WLAN_HDD_MONITOR:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010499 if (VOS_MONITOR_MODE != hdd_get_conparam())
10500 wlan_hdd_stop_mon(pHddCtx, true);
10501 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -070010502
Jeff Johnson295189b2012-06-20 16:38:30 -070010503 default:
10504 break;
10505 }
10506
10507 EXIT();
10508 return VOS_STATUS_SUCCESS;
10509}
10510
Kapil Gupta137ef892016-12-13 19:38:00 +053010511/**
10512 * wlan_hdd_restart_sap() - to restart SAP in driver internally
10513 * @ap_adapter: - Pointer to SAP hdd_adapter_t structure
10514 *
10515 * wlan_hdd_restart_sap first delete SAP and do cleanup.
10516 * After that WLANSAP_StartBss start re-start process of SAP.
10517 *
10518 * Return: None
10519 */
10520static void wlan_hdd_restart_sap(hdd_adapter_t *ap_adapter)
10521{
10522 hdd_ap_ctx_t *pHddApCtx;
10523 hdd_hostapd_state_t *pHostapdState;
10524 VOS_STATUS vos_status;
10525 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(ap_adapter);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010526#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053010527 struct station_del_parameters delStaParams;
10528#endif
10529 tsap_Config_t *pConfig;
10530
10531 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
10532 pConfig = &pHddApCtx->sapConfig;
10533
10534 mutex_lock(&pHddCtx->sap_lock);
10535 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010536#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053010537 delStaParams.mac = NULL;
10538 delStaParams.subtype = SIR_MAC_MGMT_DEAUTH >> 4;
10539 delStaParams.reason_code = eCsrForcedDeauthSta;
10540 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
10541 &delStaParams);
10542#else
10543 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
10544 NULL);
10545#endif
10546 hdd_cleanup_actionframe(pHddCtx, ap_adapter);
10547
10548 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
10549 vos_event_reset(&pHostapdState->vosEvent);
10550
10551 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10552 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
10553 10000);
10554 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10555 hddLog(LOGE, FL("SAP Stop Failed"));
10556 goto end;
10557 }
10558 }
10559 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
10560 wlan_hdd_decr_active_session(pHddCtx, ap_adapter->device_mode);
10561 hddLog(LOG1, FL("SAP Stop Success"));
10562
10563 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
10564 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10565 goto end;
10566 }
10567
10568 if (WLANSAP_StartBss(pHddCtx->pvosContext, hdd_hostapd_SAPEventCB,
10569 pConfig, (v_PVOID_t)ap_adapter->dev) != VOS_STATUS_SUCCESS) {
10570 hddLog(LOGE, FL("SAP Start Bss fail"));
10571 goto end;
10572 }
10573
10574 hddLog(LOG1, FL("Waiting for SAP to start"));
10575 vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10576 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10577 hddLog(LOGE, FL("SAP Start failed"));
10578 goto end;
10579 }
10580 hddLog(LOG1, FL("SAP Start Success"));
10581 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
10582 wlan_hdd_incr_active_session(pHddCtx, ap_adapter->device_mode);
10583 pHostapdState->bCommit = TRUE;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010584 if (!VOS_IS_STATUS_SUCCESS(hdd_dhcp_mdns_offload(ap_adapter))) {
10585 hddLog(VOS_TRACE_LEVEL_ERROR, FL("DHCP/MDNS offload Failed!!"));
10586 vos_event_reset(&pHostapdState->vosEvent);
10587 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10588 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
10589 10000);
10590 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10591 hddLog(LOGE, FL("SAP Stop Failed"));
10592 goto end;
10593 }
10594 }
10595 }
Kapil Gupta137ef892016-12-13 19:38:00 +053010596 }
10597end:
10598 mutex_unlock(&pHddCtx->sap_lock);
10599 return;
10600}
10601
10602/**
10603 * __hdd_sap_restart_handle() - to handle restarting of SAP
10604 * @work: name of the work
10605 *
10606 * Purpose of this function is to trigger sap start. this function
10607 * will be called from workqueue.
10608 *
10609 * Return: void.
10610 */
10611static void __hdd_sap_restart_handle(struct work_struct *work)
10612{
10613 hdd_adapter_t *sap_adapter;
10614 hdd_context_t *hdd_ctx = container_of(work,
10615 hdd_context_t,
10616 sap_start_work);
10617 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
10618 vos_ssr_unprotect(__func__);
10619 return;
10620 }
10621 sap_adapter = hdd_get_adapter(hdd_ctx,
10622 WLAN_HDD_SOFTAP);
10623 if (sap_adapter == NULL) {
10624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10625 FL("sap_adapter is NULL"));
10626 vos_ssr_unprotect(__func__);
10627 return;
10628 }
10629
10630 if (hdd_ctx->is_ch_avoid_in_progress) {
10631 sap_adapter->sessionCtx.ap.sapConfig.channel = AUTO_CHANNEL_SELECT;
10632 wlan_hdd_restart_sap(sap_adapter);
10633 hdd_change_ch_avoidance_status(hdd_ctx, false);
10634 }
Agrawal Ashish574b3e62017-02-09 18:58:34 +053010635 if (hdd_ctx->cfg_ini->enable_sap_auth_offload)
10636 wlan_hdd_restart_sap(sap_adapter);
Kapil Gupta137ef892016-12-13 19:38:00 +053010637}
10638
10639/**
10640 * hdd_sap_restart_handle() - to handle restarting of SAP
10641 * @work: name of the work
10642 *
10643 * Purpose of this function is to trigger sap start. this function
10644 * will be called from workqueue.
10645 *
10646 * Return: void.
10647 */
10648static void hdd_sap_restart_handle(struct work_struct *work)
10649{
10650 vos_ssr_protect(__func__);
10651 __hdd_sap_restart_handle(work);
10652 vos_ssr_unprotect(__func__);
10653}
10654
10655
Abhishek Singh78c691f2017-11-30 13:48:44 +053010656/**
10657 * __hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
10658 * @work: name of the work
10659 *
10660 * Purpose of this function is to force SCC using ECSA. This function
10661 * will be called from workqueue.
10662 *
10663 * Return: void.
10664 */
10665static void
10666__hdd_force_scc_with_ecsa_handle(struct work_struct *work)
10667{
10668 hdd_adapter_t *sap_adapter;
10669 hdd_station_ctx_t *sta_ctx;
10670 hdd_adapter_t *sta_adapter;
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010671 ptSapContext sap_ctx = NULL;
10672 v_CONTEXT_t vos_ctx;
10673 tANI_U8 target_channel;
10674 tsap_Config_t *sap_config;
10675 bool sta_sap_scc_on_dfs_chan;
10676 eNVChannelEnabledType chan_state;
Abhishek Singh78c691f2017-11-30 13:48:44 +053010677 hdd_context_t *hdd_ctx = container_of(to_delayed_work(work),
10678 hdd_context_t,
10679 ecsa_chan_change_work);
10680
10681 if (wlan_hdd_validate_context(hdd_ctx))
10682 return;
10683
10684 sap_adapter = hdd_get_adapter(hdd_ctx,
10685 WLAN_HDD_SOFTAP);
10686 if (!sap_adapter) {
10687 hddLog(LOGE, FL("sap_adapter is NULL"));
10688 return;
10689 }
10690
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010691 vos_ctx = hdd_ctx->pvosContext;
10692 if (!vos_ctx) {
10693 hddLog(LOGE, FL("vos_ctx is NULL"));
10694 return;
10695 }
10696
10697 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
10698 if (!sap_ctx) {
10699 hddLog(LOGE, FL("sap_ctx is NULL"));
10700 return;
10701 }
10702
10703 sap_config = &sap_adapter->sessionCtx.ap.sapConfig;
10704
10705 sta_sap_scc_on_dfs_chan = hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_ctx);
10706
Abhishek Singh78c691f2017-11-30 13:48:44 +053010707 sta_adapter = hdd_get_adapter(hdd_ctx,
10708 WLAN_HDD_INFRA_STATION);
10709 if (!sta_adapter) {
10710 hddLog(LOGE, FL("sta_adapter is NULL"));
10711 return;
10712 }
Abhishek Singh78c691f2017-11-30 13:48:44 +053010713
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010714 if (wlansap_chk_n_set_chan_change_in_progress(sap_ctx))
Abhishek Singh78c691f2017-11-30 13:48:44 +053010715 return;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010716 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
10717
10718 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
10719 if (sta_ctx->conn_info.connState != eConnectionState_Associated) {
10720 if (sta_ctx->conn_info.connState == eConnectionState_NotConnected) {
10721 chan_state = vos_nv_getChannelEnabledState(sap_ctx->channel);
10722 hddLog(LOG1, FL("sta not in connected state %d, sta_sap_scc_on_dfs_chan %d, chan_state %d"),
10723 sta_ctx->conn_info.connState, sta_sap_scc_on_dfs_chan,
10724 chan_state);
10725 if (sta_sap_scc_on_dfs_chan &&
10726 (chan_state == NV_CHANNEL_DFS)) {
10727 hddLog(LOGE, FL("Switch SAP to user configured channel"));
10728 target_channel = sap_config->user_config_channel;
10729 goto switch_channel;
10730 }
10731 }
10732 goto abort;
Abhishek Singh78c691f2017-11-30 13:48:44 +053010733 }
10734
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010735 target_channel = sta_ctx->conn_info.operationChannel;
10736switch_channel:
10737 hddLog(LOGE, FL("Switch SAP to %d channel"),
10738 target_channel);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010739 if (!wlansap_set_channel_change(vos_ctx, target_channel, true))
10740 return;
10741
10742abort:
10743 wlansap_reset_chan_change_in_progress(sap_ctx);
10744 complete(&sap_ctx->ecsa_info.chan_switch_comp);
Abhishek Singh78c691f2017-11-30 13:48:44 +053010745}
10746
10747/**
10748 * hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
10749 * @work: name of the work
10750 *
10751 * Purpose of this function is to force SCC using ECSA. This function
10752 * will be called from workqueue.
10753 *
10754 * Return: void.
10755 */
10756static void
10757hdd_force_scc_with_ecsa_handle(struct work_struct *work)
10758{
10759 vos_ssr_protect(__func__);
10760 __hdd_force_scc_with_ecsa_handle(work);
10761 vos_ssr_unprotect(__func__);
10762}
10763
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010764int hdd_wait_for_ecsa_complete(hdd_context_t *hdd_ctx)
10765{
10766 int ret;
10767 ptSapContext sap_ctx = NULL;
10768 v_CONTEXT_t vos_ctx;
10769
10770 vos_ctx = hdd_ctx->pvosContext;
10771 if (!vos_ctx) {
10772 hddLog(LOGE, FL("vos_ctx is NULL"));
10773 return 0;
10774 }
10775
10776 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
10777 if (!sap_ctx) {
10778 hddLog(LOG1, FL("sap_ctx is NULL"));
10779 return 0;
10780 }
10781 if(!sap_ctx->isSapSessionOpen) {
10782 hddLog(LOG1, FL("sap session not opened, SAP in state %d"),
10783 sap_ctx->sapsMachine);
10784 return 0;
10785 }
10786
10787 if (!wlansap_get_change_in_progress(sap_ctx)) {
10788 hddLog(LOG1, FL("channel switch not in progress"));
10789 return 0;
10790 }
10791 ret = wait_for_completion_timeout(&sap_ctx->ecsa_info.chan_switch_comp,
10792 msecs_to_jiffies(HDD_SAP_CHAN_CNG_WAIT_TIME));
10793 if (!ret)
10794 {
10795 hddLog(LOGE, FL("Timeout waiting for SAP channel switch"));
10796 return ret;
10797 }
10798
10799 return 0;
10800}
10801
10802
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010803/**
10804 * hdd_is_sta_sap_scc_allowed_on_dfs_chan() - check if sta+sap scc allowed on
10805 * dfs chan
10806 * @hdd_ctx: pointer to hdd context
10807 *
10808 * This function used to check if sta+sap scc allowed on DFS channel.
10809 *
10810 * Return: None
10811 */
10812bool hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_context_t *hdd_ctx)
10813{
10814 if (hdd_ctx->cfg_ini->force_scc_with_ecsa &&
10815 hdd_ctx->cfg_ini->sta_sap_scc_on_dfs_chan)
10816 return true;
10817 else
10818 return false;
10819}
10820
Jeff Johnson295189b2012-06-20 16:38:30 -070010821VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
10822{
10823 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10824 VOS_STATUS status;
10825 hdd_adapter_t *pAdapter;
10826
10827 ENTER();
10828
10829 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10830
10831 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10832 {
10833 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010834
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010835 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -070010836
10837 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10838 pAdapterNode = pNext;
10839 }
10840
10841 EXIT();
10842
10843 return VOS_STATUS_SUCCESS;
10844}
10845
Rajeev Kumarf999e582014-01-09 17:33:29 -080010846
10847#ifdef FEATURE_WLAN_BATCH_SCAN
10848/**---------------------------------------------------------------------------
10849
10850 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
10851 structures
10852
10853 \param - pAdapter Pointer to HDD adapter
10854
10855 \return - None
10856
10857 --------------------------------------------------------------------------*/
10858void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
10859{
10860 tHddBatchScanRsp *pNode;
10861 tHddBatchScanRsp *pPrev;
10862
Siddharth Bhalb3e9b792014-02-24 15:14:16 +053010863 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -080010864 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +053010865 hddLog(VOS_TRACE_LEVEL_ERROR,
10866 "%s: Adapter context is Null", __func__);
10867 return;
10868 }
10869
10870 pNode = pAdapter->pBatchScanRsp;
10871 while (pNode)
10872 {
10873 pPrev = pNode;
10874 pNode = pNode->pNext;
10875 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -080010876 }
10877
10878 pAdapter->pBatchScanRsp = NULL;
10879 pAdapter->numScanList = 0;
10880 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
10881 pAdapter->prev_batch_id = 0;
10882
10883 return;
10884}
10885#endif
10886
10887
Jeff Johnson295189b2012-06-20 16:38:30 -070010888VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
10889{
10890 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10891 VOS_STATUS status;
10892 hdd_adapter_t *pAdapter;
10893
10894 ENTER();
10895
10896 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10897
10898 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10899 {
10900 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053010901 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010902 netif_tx_disable(pAdapter->dev);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053010903
10904 if (pHddCtx->cfg_ini->sap_internal_restart &&
10905 pAdapter->device_mode == WLAN_HDD_SOFTAP) {
10906 hddLog(LOG1, FL("driver supports sap restart"));
10907 vos_flush_work(&pHddCtx->sap_start_work);
10908 hdd_sap_indicate_disconnect_for_sta(pAdapter);
10909 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053010910 hdd_softap_deinit_tx_rx(pAdapter, true);
10911 hdd_sap_destroy_timers(pAdapter);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053010912 } else {
10913 netif_carrier_off(pAdapter->dev);
10914 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010915
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070010916 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053010917
10918 if (pAdapter->device_mode == WLAN_HDD_MONITOR)
10919 pAdapter->sessionCtx.monitor.state = MON_MODE_STOP;
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070010920
Jeff Johnson295189b2012-06-20 16:38:30 -070010921 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +053010922
Katya Nigam1fd24402015-02-16 14:52:19 +053010923 if(pAdapter->device_mode == WLAN_HDD_IBSS )
10924 hdd_ibss_deinit_tx_rx(pAdapter);
10925
Nirav Shah7e3c8132015-06-22 23:51:42 +053010926 status = hdd_sta_id_hash_detach(pAdapter);
10927 if (status != VOS_STATUS_SUCCESS)
10928 hddLog(VOS_TRACE_LEVEL_ERROR,
10929 FL("sta id hash detach failed for session id %d"),
10930 pAdapter->sessionId);
10931
Agarwal Ashish6267caa2014-08-06 19:16:21 +053010932 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10933
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +053010934 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
10935 {
10936 hdd_wmm_adapter_close( pAdapter );
10937 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
10938 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010939
Siddharth Bhal2db319d2014-12-03 12:37:18 +053010940 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10941 {
10942 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
10943 }
10944
Rajeev Kumarf999e582014-01-09 17:33:29 -080010945#ifdef FEATURE_WLAN_BATCH_SCAN
10946 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
10947 {
10948 hdd_deinit_batch_scan(pAdapter);
10949 }
10950#endif
10951
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +053010952#ifdef FEATURE_WLAN_TDLS
10953 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +053010954 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +053010955 mutex_unlock(&pHddCtx->tdls_lock);
10956#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010957 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10958 pAdapterNode = pNext;
10959 }
10960
10961 EXIT();
10962
10963 return VOS_STATUS_SUCCESS;
10964}
10965
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053010966/**
Abhishek Singh5a597e62016-12-05 15:16:30 +053010967 * hdd_get_bss_entry() - Get the bss entry matching the chan, bssid and ssid
10968 * @wiphy: wiphy
10969 * @channel: channel of the BSS to find
10970 * @bssid: bssid of the BSS to find
10971 * @ssid: ssid of the BSS to find
10972 * @ssid_len: ssid len of of the BSS to find
10973 *
10974 * The API is a wrapper to get bss from kernel matching the chan,
10975 * bssid and ssid
10976 *
10977 * Return: Void
10978 */
10979#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
10980 && !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
10981
10982struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
10983 struct ieee80211_channel *channel,
10984 const u8 *bssid,
10985 const u8 *ssid, size_t ssid_len)
10986{
10987 return cfg80211_get_bss(wiphy, channel, bssid,
10988 ssid, ssid_len,
10989 WLAN_CAPABILITY_ESS,
10990 WLAN_CAPABILITY_ESS);
10991}
10992#else
10993struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
10994 struct ieee80211_channel *channel,
10995 const u8 *bssid,
10996 const u8 *ssid, size_t ssid_len)
10997{
10998 return cfg80211_get_bss(wiphy, channel, bssid,
10999 ssid, ssid_len,
11000 IEEE80211_BSS_TYPE_ESS,
11001 IEEE80211_PRIVACY_ANY);
11002}
11003#endif
11004
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011005#if defined(CFG80211_CONNECT_BSS) || \
11006 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
11007
11008#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) || \
11009 defined (CFG80211_CONNECT_TIMEOUT_REASON_CODE)
11010/**
11011 * hdd_connect_bss() - helper function to send connection status to supplicant
11012 * @dev: network device
11013 * @bssid: bssid to which we want to associate
11014 * @bss: information about connected bss
11015 * @req_ie: Request Information Element
11016 * @req_ie_len: len of the req IE
11017 * @resp_ie: Response IE
11018 * @resp_ie_len: len of ht response IE
11019 * @status: status
11020 * @gfp: Kernel Flag
11021 *
11022 * This is a helper function to send connection status to supplicant
11023 * and gets invoked from wrapper API
11024 *
11025 * Return: Void
11026 */
11027static void hdd_connect_bss(struct net_device *dev,
11028 const u8 *bssid,
11029 struct cfg80211_bss *bss,
11030 const u8 *req_ie,
11031 size_t req_ie_len,
11032 const u8 *resp_ie,
11033 size_t resp_ie_len,
11034 u16 status,
11035 gfp_t gfp)
11036{
11037 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
11038 resp_ie, resp_ie_len, status, gfp, NL80211_TIMEOUT_UNSPECIFIED);
11039}
11040#else
11041/**
11042 * hdd_connect_bss() - helper function to send connection status to supplicant
11043 * @dev: network device
11044 * @bssid: bssid to which we want to associate
11045 * @bss: information about connected bss
11046 * @req_ie: Request Information Element
11047 * @req_ie_len: len of the req IE
11048 * @resp_ie: Response IE
11049 * @resp_ie_len: len of ht response IE
11050 * @status: status
11051 * @gfp: Kernel Flag
11052 *
11053 * This is a helper function to send connection status to supplicant
11054 * and gets invoked from wrapper API
11055 *
11056 * Return: Void
11057 */
11058static void hdd_connect_bss(struct net_device *dev,
11059 const u8 *bssid,
11060 struct cfg80211_bss *bss,
11061 const u8 *req_ie,
11062 size_t req_ie_len,
11063 const u8 *resp_ie,
11064 size_t resp_ie_len,
11065 u16 status,
11066 gfp_t gfp)
11067{
11068 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
11069 resp_ie, resp_ie_len, status, gfp);
11070}
11071#endif
11072
Abhishek Singh5a597e62016-12-05 15:16:30 +053011073/**
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011074 * hdd_connect_result() - API to send connection status to supplicant
11075 * @dev: network device
11076 * @bssid: bssid to which we want to associate
11077 * @roam_info: information about connected bss
11078 * @req_ie: Request Information Element
11079 * @req_ie_len: len of the req IE
11080 * @resp_ie: Response IE
11081 * @resp_ie_len: len of ht response IE
11082 * @status: status
11083 * @gfp: Kernel Flag
11084 *
11085 * The API is a wrapper to send connection status to supplicant
11086 *
11087 * Return: Void
11088 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011089void hdd_connect_result(struct net_device *dev,
11090 const u8 *bssid,
11091 tCsrRoamInfo *roam_info,
11092 const u8 *req_ie,
11093 size_t req_ie_len,
11094 const u8 *resp_ie,
11095 size_t resp_ie_len,
11096 u16 status,
11097 gfp_t gfp)
11098{
11099 hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev);
11100 struct cfg80211_bss *bss = NULL;
11101
11102 if (WLAN_STATUS_SUCCESS == status) {
11103 struct ieee80211_channel *chan;
11104 int freq;
11105 int chan_no = roam_info->pBssDesc->channelId;;
11106
11107 if (chan_no <= 14)
11108 freq = ieee80211_channel_to_frequency(chan_no,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011109 HDD_NL80211_BAND_2GHZ);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011110 else
11111 freq = ieee80211_channel_to_frequency(chan_no,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011112 HDD_NL80211_BAND_5GHZ);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011113
11114 chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
Abhishek Singh5a597e62016-12-05 15:16:30 +053011115 bss = hdd_get_bss_entry(padapter->wdev.wiphy,
11116 chan, bssid,
11117 roam_info->u.pConnectedProfile->SSID.ssId,
11118 roam_info->u.pConnectedProfile->SSID.length);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011119 }
11120
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011121 hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie, resp_ie_len,
11122 status, gfp);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011123}
11124#else
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011125/**
11126 * hdd_connect_result() - API to send connection status to supplicant
11127 * @dev: network device
11128 * @bssid: bssid to which we want to associate
11129 * @roam_info: information about connected bss
11130 * @req_ie: Request Information Element
11131 * @req_ie_len: len of the req IE
11132 * @resp_ie: Response IE
11133 * @resp_ie_len: len of ht response IE
11134 * @status: status
11135 * @gfp: Kernel Flag
11136 *
11137 * The API is a wrapper to send connection status to supplicant
11138 *
11139 * Return: Void
11140 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011141void hdd_connect_result(struct net_device *dev,
11142 const u8 *bssid,
11143 tCsrRoamInfo *roam_info,
11144 const u8 *req_ie,
11145 size_t req_ie_len,
11146 const u8 * resp_ie,
11147 size_t resp_ie_len,
11148 u16 status,
11149 gfp_t gfp)
11150{
11151 cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
11152 resp_ie, resp_ie_len, status, gfp);
11153}
11154#endif
11155
Jeff Johnson295189b2012-06-20 16:38:30 -070011156VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
11157{
11158 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11159 VOS_STATUS status;
11160 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011161 eConnectionState connState;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011162 v_CONTEXT_t pVosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011163
11164 ENTER();
11165
11166 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11167
11168 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11169 {
11170 pAdapter = pAdapterNode->pAdapter;
11171
Kumar Anand82c009f2014-05-29 00:29:42 -070011172 hdd_wmm_init( pAdapter );
11173
Jeff Johnson295189b2012-06-20 16:38:30 -070011174 switch(pAdapter->device_mode)
11175 {
11176 case WLAN_HDD_INFRA_STATION:
11177 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -070011178 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011179
11180 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
11181
Jeff Johnson295189b2012-06-20 16:38:30 -070011182 hdd_init_station_mode(pAdapter);
11183 /* Open the gates for HDD to receive Wext commands */
11184 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011185 pHddCtx->scan_info.mScanPending = FALSE;
11186 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011187
11188 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +053011189 if (!pHddCtx->isLogpInProgress)
11190 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011191
11192 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011193 if (eConnectionState_Associated == connState ||
11194 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -070011195 {
11196 union iwreq_data wrqu;
11197 memset(&wrqu, '\0', sizeof(wrqu));
11198 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
11199 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
11200 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070011201 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011202
Jeff Johnson295189b2012-06-20 16:38:30 -070011203 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagar9ff4bcc2016-06-01 17:17:50 +053011204 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, false,
Mahesh A Saptasagarb5a15142016-05-25 11:27:43 +053011205 WLAN_REASON_UNSPECIFIED);
Jeff Johnson295189b2012-06-20 16:38:30 -070011206 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011207 else if (eConnectionState_Connecting == connState)
11208 {
11209 /*
11210 * Indicate connect failure to supplicant if we were in the
11211 * process of connecting
11212 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011213 hdd_connect_result(pAdapter->dev, NULL, NULL,
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011214 NULL, 0, NULL, 0,
11215 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
11216 GFP_KERNEL);
11217 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011218 break;
11219
11220 case WLAN_HDD_SOFTAP:
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011221 if (pHddCtx->cfg_ini->sap_internal_restart) {
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011222 hdd_init_ap_mode(pAdapter, true);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011223 status = hdd_sta_id_hash_attach(pAdapter);
11224 if (VOS_STATUS_SUCCESS != status)
11225 {
11226 hddLog(VOS_TRACE_LEVEL_FATAL,
11227 FL("failed to attach hash for"));
11228 }
11229 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011230 break;
11231
11232 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -070011233 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -070011234 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -070011235 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -070011236 break;
11237
11238 case WLAN_HDD_MONITOR:
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011239 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11240
11241 hddLog(VOS_TRACE_LEVEL_INFO, FL("[SSR] monitor mode"));
11242 if (!pVosContext) {
11243 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos context is NULL"));
11244 break;
11245 }
11246
11247 hdd_init_tx_rx(pAdapter);
11248 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk);
Jeff Johnson295189b2012-06-20 16:38:30 -070011249 break;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011250
Jeff Johnson295189b2012-06-20 16:38:30 -070011251 default:
11252 break;
11253 }
11254
11255 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11256 pAdapterNode = pNext;
11257 }
11258
11259 EXIT();
11260
11261 return VOS_STATUS_SUCCESS;
11262}
11263
11264VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
11265{
11266 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11267 hdd_adapter_t *pAdapter;
11268 VOS_STATUS status;
11269 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011270 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011271
11272 ENTER();
11273
11274 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11275
11276 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11277 {
11278 pAdapter = pAdapterNode->pAdapter;
11279
11280 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11281 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11282 {
11283 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11284 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11285
Abhishek Singhf4669da2014-05-26 15:07:49 +053011286 hddLog(VOS_TRACE_LEVEL_INFO,
11287 "%s: Set HDD connState to eConnectionState_NotConnected",
11288 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +053011289 spin_lock_bh(&pAdapter->lock_for_active_session);
11290 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11291 {
11292 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11293 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011294 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +053011295 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -070011296 init_completion(&pAdapter->disconnect_comp_var);
11297 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
11298 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11299
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011300 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070011301 &pAdapter->disconnect_comp_var,
11302 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011303 if (0 >= ret)
11304 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
11305 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -070011306
11307 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
11308 pHddCtx->isAmpAllowed = VOS_FALSE;
11309 sme_RoamConnect(pHddCtx->hHal,
11310 pAdapter->sessionId, &(pWextState->roamProfile),
11311 &roamId);
11312 }
11313
11314 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11315 pAdapterNode = pNext;
11316 }
11317
11318 EXIT();
11319
11320 return VOS_STATUS_SUCCESS;
11321}
11322
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011323void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
11324{
11325 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11326 VOS_STATUS status;
11327 hdd_adapter_t *pAdapter;
11328 hdd_station_ctx_t *pHddStaCtx;
11329 hdd_ap_ctx_t *pHddApCtx;
11330 hdd_hostapd_state_t * pHostapdState;
11331 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
11332 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
11333 const char *p2pMode = "DEV";
11334 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011335
11336 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11337 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11338 {
11339 pAdapter = pAdapterNode->pAdapter;
11340 switch (pAdapter->device_mode) {
11341 case WLAN_HDD_INFRA_STATION:
11342 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11343 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
11344 staChannel = pHddStaCtx->conn_info.operationChannel;
11345 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
11346 }
11347 break;
11348 case WLAN_HDD_P2P_CLIENT:
11349 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11350 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
11351 p2pChannel = pHddStaCtx->conn_info.operationChannel;
11352 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
11353 p2pMode = "CLI";
11354 }
11355 break;
11356 case WLAN_HDD_P2P_GO:
11357 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11358 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11359 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
11360 p2pChannel = pHddApCtx->operatingChannel;
11361 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
11362 }
11363 p2pMode = "GO";
11364 break;
11365 case WLAN_HDD_SOFTAP:
11366 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11367 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11368 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
11369 apChannel = pHddApCtx->operatingChannel;
11370 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
11371 }
11372 break;
11373 default:
11374 break;
11375 }
11376 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11377 pAdapterNode = pNext;
11378 }
11379 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
11380 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
11381 }
Yeshwanth Sriram Guntuka0004c0b2017-12-06 14:43:49 +053011382 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s",
11383 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011384 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053011385 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011386 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
11387 }
11388 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053011389 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011390 apChannel, MAC_ADDR_ARRAY(apBssid));
11391 }
11392
11393 if (p2pChannel > 0 && apChannel > 0) {
11394 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
11395 }
11396}
11397
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011398bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070011399{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011400 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -070011401}
11402
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011403/* Once SSR is disabled then it cannot be set. */
11404void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -070011405{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011406 if (HDD_SSR_DISABLED == isSsrRequired)
11407 return;
11408
Jeff Johnson295189b2012-06-20 16:38:30 -070011409 isSsrRequired = value;
11410}
11411
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +053011412void hdd_set_pre_close( hdd_context_t *pHddCtx)
11413{
11414 sme_PreClose(pHddCtx->hHal);
11415}
11416
Jeff Johnson295189b2012-06-20 16:38:30 -070011417VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
11418 hdd_adapter_list_node_t** ppAdapterNode)
11419{
11420 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011421 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011422 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
11423 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011424 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011425 return status;
11426}
11427
11428VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
11429 hdd_adapter_list_node_t* pAdapterNode,
11430 hdd_adapter_list_node_t** pNextAdapterNode)
11431{
11432 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011433 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011434 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
11435 (hdd_list_node_t*) pAdapterNode,
11436 (hdd_list_node_t**)pNextAdapterNode );
11437
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011438 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011439 return status;
11440}
11441
11442VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
11443 hdd_adapter_list_node_t* pAdapterNode)
11444{
11445 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011446 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011447 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
11448 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011449 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011450 return status;
11451}
11452
11453VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
11454 hdd_adapter_list_node_t** ppAdapterNode)
11455{
11456 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011457 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011458 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
11459 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011460 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011461 return status;
11462}
11463
11464VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
11465 hdd_adapter_list_node_t* pAdapterNode)
11466{
11467 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011468 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011469 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
11470 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011471 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011472 return status;
11473}
11474
11475VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
11476 hdd_adapter_list_node_t* pAdapterNode)
11477{
11478 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011479 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011480 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
11481 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011482 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011483 return status;
11484}
11485
11486hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
11487 tSirMacAddr macAddr )
11488{
11489 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11490 hdd_adapter_t *pAdapter;
11491 VOS_STATUS status;
11492
11493 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11494
11495 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11496 {
11497 pAdapter = pAdapterNode->pAdapter;
11498
11499 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
11500 macAddr, sizeof(tSirMacAddr) ) )
11501 {
11502 return pAdapter;
11503 }
11504 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11505 pAdapterNode = pNext;
11506 }
11507
11508 return NULL;
11509
11510}
11511
11512hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
11513{
11514 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11515 hdd_adapter_t *pAdapter;
11516 VOS_STATUS status;
11517
11518 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11519
11520 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11521 {
11522 pAdapter = pAdapterNode->pAdapter;
11523
11524 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
11525 IFNAMSIZ ) )
11526 {
11527 return pAdapter;
11528 }
11529 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11530 pAdapterNode = pNext;
11531 }
11532
11533 return NULL;
11534
11535}
11536
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053011537hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
11538 tANI_U32 sme_session_id )
11539{
11540 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11541 hdd_adapter_t *pAdapter;
11542 VOS_STATUS vos_status;
11543
11544
11545 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11546
11547 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
11548 {
11549 pAdapter = pAdapterNode->pAdapter;
11550
11551 if (pAdapter->sessionId == sme_session_id)
11552 return pAdapter;
11553
11554 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
11555 pAdapterNode = pNext;
11556 }
11557
11558 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11559 "%s: sme_session_id %d does not exist with host",
11560 __func__, sme_session_id);
11561
11562 return NULL;
11563}
11564
Jeff Johnson295189b2012-06-20 16:38:30 -070011565hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
11566{
11567 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11568 hdd_adapter_t *pAdapter;
11569 VOS_STATUS status;
11570
11571 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11572
11573 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11574 {
11575 pAdapter = pAdapterNode->pAdapter;
11576
11577 if( pAdapter && (mode == pAdapter->device_mode) )
11578 {
11579 return pAdapter;
11580 }
11581 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11582 pAdapterNode = pNext;
11583 }
11584
11585 return NULL;
11586
11587}
11588
11589//Remove this function later
11590hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
11591{
11592 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11593 hdd_adapter_t *pAdapter;
11594 VOS_STATUS status;
11595
11596 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11597
11598 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11599 {
11600 pAdapter = pAdapterNode->pAdapter;
11601
11602 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
11603 {
11604 return pAdapter;
11605 }
11606
11607 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11608 pAdapterNode = pNext;
11609 }
11610
11611 return NULL;
11612
11613}
11614
Jeff Johnson295189b2012-06-20 16:38:30 -070011615/**---------------------------------------------------------------------------
11616
Mahesh A Saptasgar64534612014-09-23 13:13:33 +053011617 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -070011618
11619 This API returns the operating channel of the requested device mode
11620
11621 \param - pHddCtx - Pointer to the HDD context.
11622 - mode - Device mode for which operating channel is required
11623 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
11624 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
11625 \return - channel number. "0" id the requested device is not found OR it is not connected.
11626 --------------------------------------------------------------------------*/
11627v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
11628{
11629 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11630 VOS_STATUS status;
11631 hdd_adapter_t *pAdapter;
11632 v_U8_t operatingChannel = 0;
11633
11634 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11635
11636 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11637 {
11638 pAdapter = pAdapterNode->pAdapter;
11639
11640 if( mode == pAdapter->device_mode )
11641 {
11642 switch(pAdapter->device_mode)
11643 {
11644 case WLAN_HDD_INFRA_STATION:
11645 case WLAN_HDD_P2P_CLIENT:
11646 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
11647 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
11648 break;
11649 case WLAN_HDD_SOFTAP:
11650 case WLAN_HDD_P2P_GO:
11651 /*softap connection info */
11652 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11653 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
11654 break;
11655 default:
11656 break;
11657 }
11658
11659 break; //Found the device of interest. break the loop
11660 }
11661
11662 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11663 pAdapterNode = pNext;
11664 }
11665 return operatingChannel;
11666}
11667
11668#ifdef WLAN_FEATURE_PACKET_FILTERING
11669/**---------------------------------------------------------------------------
11670
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011671 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -070011672
11673 This used to set the multicast address list.
11674
11675 \param - dev - Pointer to the WLAN device.
11676 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011677 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -070011678
11679 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011680static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -070011681{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011682 hdd_adapter_t *pAdapter;
11683 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011684 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011685 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011686 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011687
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011688 ENTER();
11689
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011690 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011691 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070011692 {
11693 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011694 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011695 return;
11696 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011697 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11698 ret = wlan_hdd_validate_context(pHddCtx);
11699 if (0 != ret)
11700 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011701 return;
11702 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011703 if (dev->flags & IFF_ALLMULTI)
11704 {
11705 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011706 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011707 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011708 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011709 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011710 {
11711 mc_count = netdev_mc_count(dev);
11712 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011713 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -070011714 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
11715 {
11716 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011717 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011718 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011719 return;
11720 }
11721
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011722 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -070011723
11724 netdev_for_each_mc_addr(ha, dev) {
11725 if (i == mc_count)
11726 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011727 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
11728 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -080011729 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011730 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011731 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -070011732 i++;
11733 }
11734 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011735
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +053011736 if (pHddCtx->hdd_wlan_suspended)
11737 {
11738 /*
11739 * Configure the Mcast address list to FW
11740 * If wlan is already in suspend mode
11741 */
11742 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
11743 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011744 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011745 return;
11746}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011747
11748static void hdd_set_multicast_list(struct net_device *dev)
11749{
11750 vos_ssr_protect(__func__);
11751 __hdd_set_multicast_list(dev);
11752 vos_ssr_unprotect(__func__);
11753}
Jeff Johnson295189b2012-06-20 16:38:30 -070011754#endif
11755
11756/**---------------------------------------------------------------------------
11757
11758 \brief hdd_select_queue() -
11759
11760 This function is registered with the Linux OS for network
11761 core to decide which queue to use first.
11762
11763 \param - dev - Pointer to the WLAN device.
11764 - skb - Pointer to OS packet (sk_buff).
11765 \return - ac, Queue Index/access category corresponding to UP in IP header
11766
11767 --------------------------------------------------------------------------*/
11768v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011769 struct sk_buff *skb
11770#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
11771 , void *accel_priv
11772#endif
11773#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
11774 , select_queue_fallback_t fallback
11775#endif
11776)
Jeff Johnson295189b2012-06-20 16:38:30 -070011777{
11778 return hdd_wmm_select_queue(dev, skb);
11779}
11780
11781
11782/**---------------------------------------------------------------------------
11783
11784 \brief hdd_wlan_initial_scan() -
11785
11786 This function triggers the initial scan
11787
11788 \param - pAdapter - Pointer to the HDD adapter.
11789
11790 --------------------------------------------------------------------------*/
11791void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
11792{
11793 tCsrScanRequest scanReq;
11794 tCsrChannelInfo channelInfo;
11795 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -070011796 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011797 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11798
11799 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
11800 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
11801 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
11802
11803 if(sme_Is11dSupported(pHddCtx->hHal))
11804 {
11805 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
11806 if ( HAL_STATUS_SUCCESS( halStatus ) )
11807 {
11808 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
11809 if( !scanReq.ChannelInfo.ChannelList )
11810 {
11811 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
11812 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080011813 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011814 return;
11815 }
11816 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
11817 channelInfo.numOfChannels);
11818 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
11819 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080011820 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011821 }
11822
11823 scanReq.scanType = eSIR_PASSIVE_SCAN;
11824 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
11825 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
11826 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
11827 }
11828 else
11829 {
11830 scanReq.scanType = eSIR_ACTIVE_SCAN;
11831 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
11832 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
11833 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
11834 }
11835
11836 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
11837 if ( !HAL_STATUS_SUCCESS( halStatus ) )
11838 {
11839 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
11840 __func__, halStatus );
11841 }
11842
11843 if(sme_Is11dSupported(pHddCtx->hHal))
11844 vos_mem_free(scanReq.ChannelInfo.ChannelList);
11845}
11846
Jeff Johnson295189b2012-06-20 16:38:30 -070011847/**---------------------------------------------------------------------------
11848
11849 \brief hdd_full_power_callback() - HDD full power callback function
11850
11851 This is the function invoked by SME to inform the result of a full power
11852 request issued by HDD
11853
11854 \param - callbackcontext - Pointer to cookie
11855 \param - status - result of request
11856
11857 \return - None
11858
11859 --------------------------------------------------------------------------*/
11860static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
11861{
Jeff Johnson72a40512013-12-19 10:14:15 -080011862 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011863
11864 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070011865 "%s: context = %pK, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070011866
11867 if (NULL == callbackContext)
11868 {
11869 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070011870 "%s: Bad param, context [%pK]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011871 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011872 return;
11873 }
11874
Jeff Johnson72a40512013-12-19 10:14:15 -080011875 /* there is a race condition that exists between this callback
11876 function and the caller since the caller could time out either
11877 before or while this code is executing. we use a spinlock to
11878 serialize these actions */
11879 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011880
11881 if (POWER_CONTEXT_MAGIC != pContext->magic)
11882 {
11883 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -080011884 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011885 hddLog(VOS_TRACE_LEVEL_WARN,
11886 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011887 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -070011888 return;
11889 }
11890
Jeff Johnson72a40512013-12-19 10:14:15 -080011891 /* context is valid so caller is still waiting */
11892
11893 /* paranoia: invalidate the magic */
11894 pContext->magic = 0;
11895
11896 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -070011897 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -080011898
11899 /* serialization is complete */
11900 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011901}
11902
Katya Nigamf0511f62015-05-05 16:40:57 +053011903void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
11904{
11905 pMonCtx->typeSubtypeBitmap = 0;
11906 if( type%10 ) /* Management Packets */
11907 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
11908 type/=10;
11909 if( type%10 ) /* Control Packets */
11910 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
11911 type/=10;
11912 if( type%10 ) /* Data Packets */
11913 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
11914}
11915
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011916VOS_STATUS wlan_hdd_mon_postMsg(tANI_U32 *magic, struct completion *cmpVar,
11917 hdd_mon_ctx_t *pMonCtx , void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +053011918{
11919 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011920 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053011921
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011922 if (MON_MODE_START == pMonCtx->state)
11923 monMsg.type = WDA_MON_START_REQ;
11924 else if (MON_MODE_STOP == pMonCtx->state)
11925 monMsg.type = WDA_MON_STOP_REQ;
11926 else {
11927 hddLog(VOS_TRACE_LEVEL_ERROR,
11928 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +053011929 return VOS_STATUS_E_FAILURE;
11930 }
11931
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011932 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
11933 if (pMonModeReq == NULL) {
11934 hddLog(VOS_TRACE_LEVEL_ERROR,
11935 FL("fail to allocate memory for monitor mode req"));
11936 return VOS_STATUS_E_FAILURE;
11937 }
Katya Nigamf0511f62015-05-05 16:40:57 +053011938
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011939 pMonModeReq->magic = magic;
11940 pMonModeReq->cmpVar = cmpVar;
11941 pMonModeReq->data = pMonCtx;
11942 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +053011943
Katya Nigamf0511f62015-05-05 16:40:57 +053011944 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011945 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053011946 monMsg.bodyval = 0;
11947
11948 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
11949 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
11950 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011951 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +053011952 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011953 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +053011954}
11955
Katya Nigame7b69a82015-04-28 15:24:06 +053011956void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
11957{
11958 VOS_STATUS vosStatus;
11959 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011960 long ret;
11961 hdd_mon_ctx_t *pMonCtx = NULL;
11962 v_U32_t magic;
11963 struct completion cmpVar;
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053011964
Katya Nigame7b69a82015-04-28 15:24:06 +053011965 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
11966 if(pAdapter == NULL || pVosContext == NULL)
11967 {
11968 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
11969 return ;
11970 }
Katya Nigamf0511f62015-05-05 16:40:57 +053011971
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011972 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
11973 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
11974 pMonCtx->state = MON_MODE_STOP;
11975 magic = MON_MODE_MSG_MAGIC;
11976 init_completion(&cmpVar);
11977 if (VOS_STATUS_SUCCESS !=
11978 wlan_hdd_mon_postMsg(&magic, &cmpVar,
11979 pMonCtx, hdd_monPostMsgCb)) {
11980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11981 FL("failed to post MON MODE REQ"));
11982 pMonCtx->state = MON_MODE_START;
11983 magic = 0;
11984 return;
11985 }
11986 ret = wait_for_completion_timeout(&cmpVar, MON_MODE_MSG_TIMEOUT);
11987 magic = 0;
11988 if (ret <= 0 ) {
11989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11990 FL("timeout on monitor mode completion %ld"), ret);
11991 }
11992 }
11993
Katya Nigame7b69a82015-04-28 15:24:06 +053011994 hdd_UnregisterWext(pAdapter->dev);
11995
11996 vos_mon_stop( pVosContext );
11997
11998 vosStatus = vos_sched_close( pVosContext );
11999 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
12000 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12001 "%s: Failed to close VOSS Scheduler",__func__);
12002 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12003 }
12004
12005 vosStatus = vos_nv_close();
12006 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12007 {
12008 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12009 "%s: Failed to close NV", __func__);
12010 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12011 }
12012
12013 vos_close(pVosContext);
12014
12015 #ifdef WLAN_KD_READY_NOTIFIER
12016 nl_srv_exit(pHddCtx->ptt_pid);
12017 #else
12018 nl_srv_exit();
12019 #endif
12020
Katya Nigame7b69a82015-04-28 15:24:06 +053012021 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +053012022}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012023/**
12024 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
12025 * @ wiphy: the wiphy to validate against
12026 *
12027 * Return: void
12028 */
12029void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
12030{
12031 int i =0;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053012032 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012033 {
12034 if (NULL != wiphy->bands[i] &&
12035 (NULL != wiphy->bands[i]->channels))
12036 {
12037 vos_mem_free(wiphy->bands[i]->channels);
12038 wiphy->bands[i]->channels = NULL;
12039 }
12040 }
12041}
Jeff Johnson295189b2012-06-20 16:38:30 -070012042/**---------------------------------------------------------------------------
12043
12044 \brief hdd_wlan_exit() - HDD WLAN exit function
12045
12046 This is the driver exit point (invoked during rmmod)
12047
12048 \param - pHddCtx - Pointer to the HDD Context
12049
12050 \return - None
12051
12052 --------------------------------------------------------------------------*/
12053void hdd_wlan_exit(hdd_context_t *pHddCtx)
12054{
12055 eHalStatus halStatus;
12056 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
12057 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +053012058 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080012059 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -080012060 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012061 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +053012062 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012063
12064 ENTER();
12065
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012066
Katya Nigame7b69a82015-04-28 15:24:06 +053012067 if (VOS_MONITOR_MODE == hdd_get_conparam())
12068 {
12069 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
12070 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053012071 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +053012072 }
12073 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -080012074 {
12075 // Unloading, restart logic is no more required.
12076 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -070012077
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053012078#ifdef FEATURE_WLAN_TDLS
12079 /* At the time of driver unloading; if tdls connection is present;
12080 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
12081 * wlan_hdd_tdls_find_peer always checks for valid context;
12082 * as load/unload in progress there can be a race condition.
12083 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
12084 * when tdls state is enabled.
12085 * As soon as driver set load/unload flag; tdls flag also needs
12086 * to be disabled so that hdd_rx_packet_cbk won't call
12087 * wlan_hdd_tdls_find_peer.
12088 */
Masti, Narayanraddi20494af2015-12-17 20:56:42 +053012089 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE,
12090 HDD_SET_TDLS_MODE_SOURCE_USER);
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053012091#endif
12092
c_hpothu5ab05e92014-06-13 17:34:05 +053012093 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12094 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -070012095 {
c_hpothu5ab05e92014-06-13 17:34:05 +053012096 pAdapter = pAdapterNode->pAdapter;
12097 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070012098 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053012099 /* Disable TX on the interface, after this hard_start_xmit() will
12100 * not be called on that interface
12101 */
12102 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
12103 netif_tx_disable(pAdapter->dev);
12104
12105 /* Mark the interface status as "down" for outside world */
12106 netif_carrier_off(pAdapter->dev);
12107
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053012108 /* DeInit the adapter. This ensures that all data packets
12109 * are freed.
12110 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053012111#ifdef FEATURE_WLAN_TDLS
12112 mutex_lock(&pHddCtx->tdls_lock);
12113#endif
c_hpothu002231a2015-02-05 14:58:51 +053012114 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053012115#ifdef FEATURE_WLAN_TDLS
12116 mutex_unlock(&pHddCtx->tdls_lock);
12117#endif
Masti, Narayanraddi26378462016-01-05 18:20:28 +053012118 vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work);
12119
12120 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053012121
c_hpothu5ab05e92014-06-13 17:34:05 +053012122 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012123 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
12124 WLAN_HDD_MONITOR == pAdapter->device_mode)
c_hpothu5ab05e92014-06-13 17:34:05 +053012125 {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012126 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12127 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
12128 wlan_hdd_cfg80211_deregister_frames(pAdapter);
12129
c_hpothu5ab05e92014-06-13 17:34:05 +053012130 hdd_UnregisterWext(pAdapter->dev);
12131 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012132
Jeff Johnson295189b2012-06-20 16:38:30 -070012133 }
c_hpothu5ab05e92014-06-13 17:34:05 +053012134 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12135 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012136 }
mukul sharmabab477d2015-06-11 17:14:55 +053012137
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012138 // Cancel any outstanding scan requests. We are about to close all
12139 // of our adapters, but an adapter structure is what SME passes back
12140 // to our callback function. Hence if there are any outstanding scan
12141 // requests then there is a race condition between when the adapter
12142 // is closed and when the callback is invoked.We try to resolve that
12143 // race condition here by canceling any outstanding scans before we
12144 // close the adapters.
12145 // Note that the scans may be cancelled in an asynchronous manner,
12146 // so ideally there needs to be some kind of synchronization. Rather
12147 // than introduce a new synchronization here, we will utilize the
12148 // fact that we are about to Request Full Power, and since that is
12149 // synchronized, the expectation is that by the time Request Full
12150 // Power has completed all scans will be cancelled.
12151 if (pHddCtx->scan_info.mScanPending)
12152 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +053012153 if(NULL != pAdapter)
12154 {
12155 hddLog(VOS_TRACE_LEVEL_INFO,
12156 FL("abort scan mode: %d sessionId: %d"),
12157 pAdapter->device_mode,
12158 pAdapter->sessionId);
12159 }
12160 hdd_abort_mac_scan(pHddCtx,
12161 pHddCtx->scan_info.sessionId,
12162 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012163 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012164 }
c_hpothu5ab05e92014-06-13 17:34:05 +053012165 else
Jeff Johnson88ba7742013-02-27 14:36:02 -080012166 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012167 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +053012168 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
12169 {
12170 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
12171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12172 "%s: in middle of FTM START", __func__);
12173 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
12174 msecs_to_jiffies(20000));
12175 if(!lrc)
12176 {
12177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12178 "%s: timedout on ftmStartCmpVar fatal error", __func__);
12179 }
12180 }
Jeff Johnson88ba7742013-02-27 14:36:02 -080012181 wlan_hdd_ftm_close(pHddCtx);
12182 goto free_hdd_ctx;
12183 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012184
Jeff Johnson295189b2012-06-20 16:38:30 -070012185 /* DeRegister with platform driver as client for Suspend/Resume */
12186 vosStatus = hddDeregisterPmOps(pHddCtx);
12187 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
12188 {
12189 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
12190 VOS_ASSERT(0);
12191 }
12192
12193 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
12194 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
12195 {
12196 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
12197 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012198
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012199 //Stop the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053012200 if ((pHddCtx->cfg_ini->dynSplitscan) && (VOS_TIMER_STATE_RUNNING ==
12201 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012202 {
12203 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
12204 }
12205
12206 // Destroy the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053012207 if ((pHddCtx->cfg_ini->dynSplitscan) &&
12208 (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
12209 &pHddCtx->tx_rx_trafficTmr))))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012210 {
12211 hddLog(VOS_TRACE_LEVEL_ERROR,
12212 "%s: Cannot deallocate Traffic monitor timer", __func__);
12213 }
12214
Bhargav Shahd0715912015-10-01 18:17:37 +053012215 if (VOS_TIMER_STATE_RUNNING ==
12216 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
12217 vos_timer_stop(&pHddCtx->delack_timer);
12218 }
12219
12220 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
12221 &pHddCtx->delack_timer))) {
12222 hddLog(VOS_TRACE_LEVEL_ERROR,
12223 "%s: Cannot deallocate Bus bandwidth timer", __func__);
12224 }
12225
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012226 if (VOS_TIMER_STATE_RUNNING ==
12227 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) {
12228 vos_timer_stop(&pHddCtx->tdls_source_timer);
12229 }
12230
Abhishek Singh8a3e4dc2017-01-02 10:39:18 +053012231 vos_set_snoc_high_freq_voting(false);
12232
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012233 vos_timer_destroy(&pHddCtx->tdls_source_timer);
12234
Jeff Johnson295189b2012-06-20 16:38:30 -070012235 //Disable IMPS/BMPS as we do not want the device to enter any power
12236 //save mode during shutdown
12237 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
12238 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
12239 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
12240
12241 //Ensure that device is in full power as we will touch H/W during vos_Stop
12242 init_completion(&powerContext.completion);
12243 powerContext.magic = POWER_CONTEXT_MAGIC;
12244
12245 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
12246 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
12247
12248 if (eHAL_STATUS_SUCCESS != halStatus)
12249 {
12250 if (eHAL_STATUS_PMC_PENDING == halStatus)
12251 {
12252 /* request was sent -- wait for the response */
12253 lrc = wait_for_completion_interruptible_timeout(
12254 &powerContext.completion,
12255 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -070012256 if (lrc <= 0)
12257 {
12258 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012259 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -070012260 }
12261 }
12262 else
12263 {
12264 hddLog(VOS_TRACE_LEVEL_ERROR,
12265 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012266 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -070012267 /* continue -- need to clean up as much as possible */
12268 }
12269 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +053012270 if ((eHAL_STATUS_SUCCESS == halStatus) ||
12271 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
12272 {
12273 /* This will issue a dump command which will clean up
12274 BTQM queues and unblock MC thread */
12275 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
12276 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012277
Jeff Johnson72a40512013-12-19 10:14:15 -080012278 /* either we never sent a request, we sent a request and received a
12279 response or we sent a request and timed out. if we never sent a
12280 request or if we sent a request and got a response, we want to
12281 clear the magic out of paranoia. if we timed out there is a
12282 race condition such that the callback function could be
12283 executing at the same time we are. of primary concern is if the
12284 callback function had already verified the "magic" but had not
12285 yet set the completion variable when a timeout occurred. we
12286 serialize these activities by invalidating the magic while
12287 holding a shared spinlock which will cause us to block if the
12288 callback is currently executing */
12289 spin_lock(&hdd_context_lock);
12290 powerContext.magic = 0;
12291 spin_unlock(&hdd_context_lock);
12292
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +053012293 /* If Device is shutdown, no point for SME to wait for responses
12294 from device. Pre Close SME */
12295 if(wcnss_device_is_shutdown())
12296 {
12297 sme_PreClose(pHddCtx->hHal);
12298 }
Yue Ma0d4891e2013-08-06 17:01:45 -070012299 hdd_debugfs_exit(pHddCtx);
12300
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012301#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +053012302 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012303 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
12304#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +053012305 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012306 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
12307
Jeff Johnson295189b2012-06-20 16:38:30 -070012308 // Unregister the Net Device Notifier
12309 unregister_netdevice_notifier(&hdd_netdev_notifier);
12310
Jeff Johnson295189b2012-06-20 16:38:30 -070012311 hdd_stop_all_adapters( pHddCtx );
12312
Jeff Johnson295189b2012-06-20 16:38:30 -070012313#ifdef WLAN_BTAMP_FEATURE
12314 vosStatus = WLANBAP_Stop(pVosContext);
12315 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12316 {
12317 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12318 "%s: Failed to stop BAP",__func__);
12319 }
12320#endif //WLAN_BTAMP_FEATURE
12321
12322 //Stop all the modules
12323 vosStatus = vos_stop( pVosContext );
12324 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12325 {
12326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12327 "%s: Failed to stop VOSS",__func__);
12328 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053012329 if (isSsrPanicOnFailure())
12330 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012331 }
12332
Jeff Johnson295189b2012-06-20 16:38:30 -070012333 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -070012334 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012335
12336 //Close the scheduler before calling vos_close to make sure no thread is
12337 // scheduled after the each module close is called i.e after all the data
12338 // structures are freed.
12339 vosStatus = vos_sched_close( pVosContext );
12340 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
12341 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12342 "%s: Failed to close VOSS Scheduler",__func__);
12343 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12344 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012345#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
12346 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012347 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070012348#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012349 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012350 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012351
Mihir Shete7a24b5f2013-12-21 12:18:31 +053012352#ifdef CONFIG_ENABLE_LINUX_REG
12353 vosStatus = vos_nv_close();
12354 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12355 {
12356 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12357 "%s: Failed to close NV", __func__);
12358 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12359 }
12360#endif
12361
Jeff Johnson295189b2012-06-20 16:38:30 -070012362 //Close VOSS
12363 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
12364 vos_close(pVosContext);
12365
Jeff Johnson295189b2012-06-20 16:38:30 -070012366 //Close Watchdog
12367 if(pHddCtx->cfg_ini->fIsLogpEnabled)
12368 vos_watchdog_close(pVosContext);
12369
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053012370 //Clean up HDD Nlink Service
12371 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053012372
Manjeet Singh47ee8472016-04-11 11:57:18 +053012373 hdd_close_tx_queues(pHddCtx);
c_manjeecfd1efb2015-09-25 19:32:34 +053012374 wlan_free_fwr_mem_dump_buffer();
12375 memdump_deinit();
12376
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012377#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012378 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012379 {
12380 wlan_logging_sock_deactivate_svc();
12381 }
12382#endif
12383
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053012384#ifdef WLAN_KD_READY_NOTIFIER
12385 nl_srv_exit(pHddCtx->ptt_pid);
12386#else
12387 nl_srv_exit();
12388#endif /* WLAN_KD_READY_NOTIFIER */
12389
Abhishek Singh00b71972016-01-07 10:51:04 +053012390#ifdef WLAN_FEATURE_RMC
12391 hdd_close_cesium_nl_sock();
12392#endif /* WLAN_FEATURE_RMC */
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053012393
Jeff Johnson295189b2012-06-20 16:38:30 -070012394 hdd_close_all_adapters( pHddCtx );
12395
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012396 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
Abhishek Singh78c691f2017-11-30 13:48:44 +053012397 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
Kapil Gupta137ef892016-12-13 19:38:00 +053012398 vos_flush_work(&pHddCtx->sap_start_work);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012399
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +053012400free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -070012401 /* free the power on lock from platform driver */
12402 if (free_riva_power_on_lock("wlan"))
12403 {
12404 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
12405 __func__);
12406 }
12407
c_hpothu78c7b602014-05-17 17:35:49 +053012408 //Free up dynamically allocated members inside HDD Adapter
12409 if (pHddCtx->cfg_ini)
12410 {
12411 kfree(pHddCtx->cfg_ini);
12412 pHddCtx->cfg_ini= NULL;
12413 }
12414
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053012415 hdd_request_manager_deinit();
12416
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053012417 /* FTM/MONITOR mode, WIPHY did not registered
Leo Changf04ddad2013-09-18 13:46:38 -070012418 If un-register here, system crash will happen */
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053012419 if (!(VOS_FTM_MODE == hdd_get_conparam() ||
12420 VOS_MONITOR_MODE == hdd_get_conparam()))
Leo Changf04ddad2013-09-18 13:46:38 -070012421 {
12422 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012423 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -070012424 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012425 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070012426 if (hdd_is_ssr_required())
12427 {
12428 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -070012429 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -070012430 msleep(5000);
12431 }
12432 hdd_set_ssr_required (VOS_FALSE);
12433}
12434
12435
12436/**---------------------------------------------------------------------------
12437
12438 \brief hdd_update_config_from_nv() - Function to update the contents of
12439 the running configuration with parameters taken from NV storage
12440
12441 \param - pHddCtx - Pointer to the HDD global context
12442
12443 \return - VOS_STATUS_SUCCESS if successful
12444
12445 --------------------------------------------------------------------------*/
12446static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
12447{
Jeff Johnson295189b2012-06-20 16:38:30 -070012448 v_BOOL_t itemIsValid = VOS_FALSE;
12449 VOS_STATUS status;
12450 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
12451 v_U8_t macLoop;
12452
12453 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
12454 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
12455 if(status != VOS_STATUS_SUCCESS)
12456 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012457 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070012458 return VOS_STATUS_E_FAILURE;
12459 }
12460
12461 if (itemIsValid == VOS_TRUE)
12462 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012463 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -070012464 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
12465 VOS_MAX_CONCURRENCY_PERSONA);
12466 if(status != VOS_STATUS_SUCCESS)
12467 {
12468 /* Get MAC from NV fail, not update CFG info
12469 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -080012470 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070012471 return VOS_STATUS_E_FAILURE;
12472 }
12473
12474 /* If first MAC is not valid, treat all others are not valid
12475 * Then all MACs will be got from ini file */
12476 if(vos_is_macaddr_zero(&macFromNV[0]))
12477 {
12478 /* MAC address in NV file is not configured yet */
12479 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
12480 return VOS_STATUS_E_INVAL;
12481 }
12482
12483 /* Get MAC address from NV, update CFG info */
12484 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
12485 {
12486 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
12487 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012488 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -070012489 /* This MAC is not valid, skip it
12490 * This MAC will be got from ini file */
12491 }
12492 else
12493 {
12494 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
12495 (v_U8_t *)&macFromNV[macLoop].bytes[0],
12496 VOS_MAC_ADDR_SIZE);
12497 }
12498 }
12499 }
12500 else
12501 {
12502 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
12503 return VOS_STATUS_E_FAILURE;
12504 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012505
Jeff Johnson295189b2012-06-20 16:38:30 -070012506
12507 return VOS_STATUS_SUCCESS;
12508}
12509
12510/**---------------------------------------------------------------------------
12511
12512 \brief hdd_post_voss_start_config() - HDD post voss start config helper
12513
12514 \param - pAdapter - Pointer to the HDD
12515
12516 \return - None
12517
12518 --------------------------------------------------------------------------*/
12519VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
12520{
12521 eHalStatus halStatus;
12522 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012523 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -070012524
Jeff Johnson295189b2012-06-20 16:38:30 -070012525
12526 // Send ready indication to the HDD. This will kick off the MAC
12527 // into a 'running' state and should kick off an initial scan.
12528 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
12529 if ( !HAL_STATUS_SUCCESS( halStatus ) )
12530 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053012531 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -070012532 "code %08d [x%08x]",__func__, halStatus, halStatus );
12533 return VOS_STATUS_E_FAILURE;
12534 }
12535
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012536 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -070012537 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
12538 // And RIVA will crash
12539 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
12540 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012541 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
12542 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
12543
12544
Jeff Johnson295189b2012-06-20 16:38:30 -070012545 return VOS_STATUS_SUCCESS;
12546}
12547
Jeff Johnson295189b2012-06-20 16:38:30 -070012548/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012549void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070012550{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012551
12552 vos_wake_lock_acquire(&wlan_wake_lock, reason);
12553
Jeff Johnson295189b2012-06-20 16:38:30 -070012554}
12555
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012556void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070012557{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012558
12559 vos_wake_lock_release(&wlan_wake_lock, reason);
12560
Jeff Johnson295189b2012-06-20 16:38:30 -070012561}
12562
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012563void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012564{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012565
12566 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
12567 reason);
12568
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012569}
12570
Jeff Johnson295189b2012-06-20 16:38:30 -070012571/**---------------------------------------------------------------------------
12572
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012573 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
12574 information between Host and Riva
12575
12576 This function gets reported version of FW
12577 It also finds the version of Riva headers used to compile the host
12578 It compares the above two and prints a warning if they are different
12579 It gets the SW and HW version string
12580 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
12581 indicating the features they support through a bitmap
12582
12583 \param - pHddCtx - Pointer to HDD context
12584
12585 \return - void
12586
12587 --------------------------------------------------------------------------*/
12588
12589void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
12590{
12591
12592 tSirVersionType versionCompiled;
12593 tSirVersionType versionReported;
12594 tSirVersionString versionString;
12595 tANI_U8 fwFeatCapsMsgSupported = 0;
12596 VOS_STATUS vstatus;
12597
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080012598 memset(&versionCompiled, 0, sizeof(versionCompiled));
12599 memset(&versionReported, 0, sizeof(versionReported));
12600
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012601 /* retrieve and display WCNSS version information */
12602 do {
12603
12604 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
12605 &versionCompiled);
12606 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12607 {
12608 hddLog(VOS_TRACE_LEVEL_FATAL,
12609 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012610 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012611 break;
12612 }
12613
12614 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
12615 &versionReported);
12616 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12617 {
12618 hddLog(VOS_TRACE_LEVEL_FATAL,
12619 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012620 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012621 break;
12622 }
12623
12624 if ((versionCompiled.major != versionReported.major) ||
12625 (versionCompiled.minor != versionReported.minor) ||
12626 (versionCompiled.version != versionReported.version) ||
12627 (versionCompiled.revision != versionReported.revision))
12628 {
12629 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
12630 "Host expected %u.%u.%u.%u\n",
12631 WLAN_MODULE_NAME,
12632 (int)versionReported.major,
12633 (int)versionReported.minor,
12634 (int)versionReported.version,
12635 (int)versionReported.revision,
12636 (int)versionCompiled.major,
12637 (int)versionCompiled.minor,
12638 (int)versionCompiled.version,
12639 (int)versionCompiled.revision);
12640 }
12641 else
12642 {
12643 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
12644 WLAN_MODULE_NAME,
12645 (int)versionReported.major,
12646 (int)versionReported.minor,
12647 (int)versionReported.version,
12648 (int)versionReported.revision);
12649 }
12650
12651 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
12652 versionString,
12653 sizeof(versionString));
12654 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12655 {
12656 hddLog(VOS_TRACE_LEVEL_FATAL,
12657 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012658 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012659 break;
12660 }
12661
12662 pr_info("%s: WCNSS software version %s\n",
12663 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +053012664 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012665
12666 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
12667 versionString,
12668 sizeof(versionString));
12669 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12670 {
12671 hddLog(VOS_TRACE_LEVEL_FATAL,
12672 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012673 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012674 break;
12675 }
12676
12677 pr_info("%s: WCNSS hardware version %s\n",
12678 WLAN_MODULE_NAME, versionString);
12679
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012680 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
12681 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012682 send the message only if it the riva is 1.1
12683 minor numbers for different riva branches:
12684 0 -> (1.0)Mainline Build
12685 1 -> (1.1)Mainline Build
12686 2->(1.04) Stability Build
12687 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012688 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012689 ((versionReported.minor>=1) && (versionReported.version>=1)))
12690 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
12691 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012692
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012693 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -080012694 {
12695#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
12696 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
12697 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
12698#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -070012699 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
12700 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
12701 {
12702 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
12703 }
12704
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012705 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -080012706 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012707
12708 } while (0);
12709
12710}
Neelansh Mittaledafed22014-09-04 18:54:39 +053012711void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
12712{
12713 struct sk_buff *skb;
12714 struct nlmsghdr *nlh;
12715 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053012716 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +053012717 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012718
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053012719 if (in_interrupt() || irqs_disabled() || in_atomic())
12720 flags = GFP_ATOMIC;
12721
12722 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +053012723
12724 if(skb == NULL) {
12725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12726 "%s: alloc_skb failed", __func__);
12727 return;
12728 }
12729
12730 nlh = (struct nlmsghdr *)skb->data;
12731 nlh->nlmsg_pid = 0; /* from kernel */
12732 nlh->nlmsg_flags = 0;
12733 nlh->nlmsg_seq = 0;
12734 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
12735
12736 ani_hdr = NLMSG_DATA(nlh);
12737 ani_hdr->type = type;
12738
12739 switch(type) {
12740 case WLAN_SVC_SAP_RESTART_IND:
12741 ani_hdr->length = 0;
12742 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
12743 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
12744 break;
Bhargav Shahd0715912015-10-01 18:17:37 +053012745 case WLAN_SVC_WLAN_TP_IND:
12746 ani_hdr->length = len;
12747 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
12748 + len));
12749 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12750 memcpy(nl_data, data, len);
12751 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
12752 break;
Bhargav shah23c94942015-10-13 12:48:35 +053012753 case WLAN_MSG_RPS_ENABLE_IND:
12754 ani_hdr->length = len;
12755 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
12756 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12757 memcpy(nl_data, data, len);
12758 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
12759 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012760 default:
12761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12762 "Attempt to send unknown nlink message %d", type);
12763 kfree_skb(skb);
12764 return;
12765 }
12766
12767 nl_srv_bcast(skb);
12768
12769 return;
12770}
12771
Bhargav Shahd0715912015-10-01 18:17:37 +053012772/**
12773 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
12774 * @pHddCtx: Valid Global HDD context pointer
12775 * @rx_packets: Number of RX packet in perticular time
12776 *
12777 * Based on the RX packet this function calculate next value of tcp delack.
12778 * This function compare rx packet value to high and low threshold limit.
12779 *
12780 * Return: void
12781 */
12782void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
12783{
12784 /* average of rx_packets and prev_rx is taken so that
12785 bus width doesnot fluctuate much */
12786 uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
12787 TP_IND_TYPE next_rx_level = pHddCtx->cur_rx_level;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012788
Bhargav Shahd0715912015-10-01 18:17:37 +053012789 pHddCtx->prev_rx = rx_packets;
12790 if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
12791 next_rx_level = TP_IND_HIGH;
12792 else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
12793 next_rx_level = TP_IND_LOW;
12794
12795 hdd_set_delack_value(pHddCtx, next_rx_level);
12796}
12797
12798#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))
12799
12800/**
12801 * hdd_tcp_delack_compute_function() - get link status
12802 * @priv: Valid Global HDD context pointer
12803 *
12804 * This function find number of RX packet during timer life span.
12805 * It request tcp delack with number of RX packet and re-configure delack timer
12806 * for tcpDelAckComputeInterval timer interval.
12807 *
12808 * Return: void
12809 */
12810void hdd_tcp_delack_compute_function(void *priv)
12811{
12812 hdd_context_t *pHddCtx = (hdd_context_t *)priv;
12813 hdd_adapter_t *pAdapter = NULL;
12814 v_U32_t rx_packets = 0;
12815 hdd_adapter_list_node_t *pAdapterNode = NULL;
12816 VOS_STATUS status = 0;
12817
12818 for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12819 NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
12820 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
12821 if ((pAdapter = pAdapterNode->pAdapter) == NULL)
12822 continue;
12823
12824 rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
12825 pAdapter->prev_rx_packets);
12826 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
12827 }
12828
12829 hdd_request_tcp_delack(pHddCtx, rx_packets);
12830
12831 vos_timer_start(&pHddCtx->delack_timer,
12832 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
12833}
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012834
12835/**---------------------------------------------------------------------------
12836
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012837 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
12838
12839 \param - pHddCtx - Pointer to the hdd context
12840
12841 \return - true if hardware supports 5GHz
12842
12843 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +053012844boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012845{
12846 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
12847 * then hardware support 5Ghz.
12848 */
12849 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
12850 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012851 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012852 return true;
12853 }
12854 else
12855 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012856 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012857 __func__);
12858 return false;
12859 }
12860}
12861
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012862/**---------------------------------------------------------------------------
12863
12864 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
12865 generate function
12866
12867 This is generate the random mac address for WLAN interface
12868
12869 \param - pHddCtx - Pointer to HDD context
12870 idx - Start interface index to get auto
12871 generated mac addr.
12872 mac_addr - Mac address
12873
12874 \return - 0 for success, < 0 for failure
12875
12876 --------------------------------------------------------------------------*/
12877
12878static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
12879 int idx, v_MACADDR_t mac_addr)
12880{
12881 int i;
12882 unsigned int serialno;
12883 serialno = wcnss_get_serial_number();
12884
12885 if (0 != serialno)
12886 {
12887 /* MAC address has 3 bytes of OUI so we have a maximum of 3
12888 bytes of the serial number that can be used to generate
12889 the other 3 bytes of the MAC address. Mask off all but
12890 the lower 3 bytes (this will also make sure we don't
12891 overflow in the next step) */
12892 serialno &= 0x00FFFFFF;
12893
12894 /* we need a unique address for each session */
12895 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
12896
12897 /* autogen other Mac addresses */
12898 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
12899 {
12900 /* start with the entire default address */
12901 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
12902 /* then replace the lower 3 bytes */
12903 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
12904 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
12905 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
12906
Nachiket Kukadede2e24f2017-09-25 16:24:27 +053012907 if (0 == memcmp(&pHddCtx->cfg_ini->intfMacAddr[i].bytes[0],
12908 &mac_addr.bytes[0], VOS_MAC_ADDR_SIZE))
12909 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] +=
12910 VOS_MAX_CONCURRENCY_PERSONA;
12911
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012912 serialno++;
12913 hddLog(VOS_TRACE_LEVEL_ERROR,
12914 "%s: Derived Mac Addr: "
12915 MAC_ADDRESS_STR, __func__,
12916 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
12917 }
12918
12919 }
12920 else
12921 {
12922 hddLog(LOGE, FL("Failed to Get Serial NO"));
12923 return -1;
12924 }
12925 return 0;
12926}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012927
Katya Nigame7b69a82015-04-28 15:24:06 +053012928int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
12929{
12930 VOS_STATUS status;
12931 v_CONTEXT_t pVosContext= NULL;
12932 hdd_adapter_t *pAdapter= NULL;
12933
12934 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12935
12936 if (NULL == pVosContext)
12937 {
12938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12939 "%s: Trying to open VOSS without a PreOpen", __func__);
12940 VOS_ASSERT(0);
12941 return VOS_STATUS_E_FAILURE;
12942 }
12943
12944 status = vos_nv_open();
12945 if (!VOS_IS_STATUS_SUCCESS(status))
12946 {
12947 /* NV module cannot be initialized */
12948 hddLog( VOS_TRACE_LEVEL_FATAL,
12949 "%s: vos_nv_open failed", __func__);
12950 return VOS_STATUS_E_FAILURE;
12951 }
12952
12953 status = vos_init_wiphy_from_nv_bin();
12954 if (!VOS_IS_STATUS_SUCCESS(status))
12955 {
12956 /* NV module cannot be initialized */
12957 hddLog( VOS_TRACE_LEVEL_FATAL,
12958 "%s: vos_init_wiphy failed", __func__);
12959 goto err_vos_nv_close;
12960 }
12961
12962 status = vos_open( &pVosContext, pHddCtx->parent_dev);
12963 if ( !VOS_IS_STATUS_SUCCESS( status ))
12964 {
12965 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
12966 goto err_vos_nv_close;
12967 }
12968
12969 status = vos_mon_start( pVosContext );
12970 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12971 {
12972 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
12973 goto err_vosclose;
12974 }
12975
12976 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
12977 WDA_featureCapsExchange(pVosContext);
12978 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
12979
12980 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
12981 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
12982 if( pAdapter == NULL )
12983 {
12984 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
12985 goto err_close_adapter;
12986 }
12987
12988 //Initialize the nlink service
12989 if(nl_srv_init() != 0)
12990 {
12991 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
12992 goto err_close_adapter;
12993 }
12994 return VOS_STATUS_SUCCESS;
12995
12996err_close_adapter:
12997 hdd_close_all_adapters( pHddCtx );
12998 vos_mon_stop( pVosContext );
12999err_vosclose:
13000 status = vos_sched_close( pVosContext );
13001 if (!VOS_IS_STATUS_SUCCESS(status)) {
13002 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
13003 "%s: Failed to close VOSS Scheduler", __func__);
13004 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
13005 }
13006 vos_close(pVosContext );
13007
13008err_vos_nv_close:
13009 vos_nv_close();
13010
13011return status;
13012}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013013/**---------------------------------------------------------------------------
13014
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013015 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
13016 completed to flush out the scan results
13017
13018 11d scan is done during driver load and is a passive scan on all
13019 channels supported by the device, 11d scans may find some APs on
13020 frequencies which are forbidden to be used in the regulatory domain
13021 the device is operating in. If these APs are notified to the supplicant
13022 it may try to connect to these APs, thus flush out all the scan results
13023 which are present in SME after 11d scan is done.
13024
13025 \return - eHalStatus
13026
13027 --------------------------------------------------------------------------*/
13028static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
13029 tANI_U32 scanId, eCsrScanStatus status)
13030{
13031 ENTER();
13032
13033 sme_ScanFlushResult(halHandle, 0);
13034
13035 EXIT();
13036
13037 return eHAL_STATUS_SUCCESS;
13038}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013039/**---------------------------------------------------------------------------
13040
13041 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
13042 logging is completed successfully.
13043
13044 \return - None
13045
13046 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +053013047void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013048{
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013049 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013050
13051 if (NULL == pHddCtx)
13052 {
13053 hddLog(VOS_TRACE_LEVEL_ERROR,
13054 "%s: HDD context is NULL",__func__);
13055 return;
13056 }
13057
c_manjeecfd1efb2015-09-25 19:32:34 +053013058 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +053013059 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013060 {
13061 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
13062 pHddCtx->mgmt_frame_logging = TRUE;
13063 }
13064 else
13065 {
13066 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
13067 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +053013068 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013069 }
13070
c_manjeecfd1efb2015-09-25 19:32:34 +053013071 /*Check feature supported by FW*/
13072 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
13073 {
13074 //Store fwr mem dump size given by firmware.
13075 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
13076 }
13077 else
13078 {
13079 wlan_store_fwr_mem_dump_size(0);
13080 }
13081
13082
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013083}
13084/**---------------------------------------------------------------------------
13085
13086 \brief hdd_init_frame_logging - function to initialize frame logging.
13087 Currently only Mgmt Frames are logged in both TX
13088 and Rx direction and are sent to userspace
13089 application using logger thread when queried.
13090
13091 \return - None
13092
13093 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013094void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013095{
13096 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013097 tSirFWLoggingInitParam wlanFWLoggingInitParam = {0};
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013098
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013099 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
13100 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013101 {
13102 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
13103 return;
13104 }
13105
c_manjeecfd1efb2015-09-25 19:32:34 +053013106 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013107 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
13108 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +053013109 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
13110 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013111
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013112 if (pHddCtx->cfg_ini->enableFWLogging ||
13113 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013114 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013115 wlanFWLoggingInitParam.enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013116 }
13117
Sushant Kaushik46804902015-07-08 14:46:03 +053013118 if (pHddCtx->cfg_ini->enableMgmtLogging)
13119 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013120 wlanFWLoggingInitParam.enableFlag |= WLAN_FRAME_LOG_EN;
Sushant Kaushik46804902015-07-08 14:46:03 +053013121 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013122 if (pHddCtx->cfg_ini->enableBMUHWtracing)
13123 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013124 wlanFWLoggingInitParam.enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013125 }
c_manjeecfd1efb2015-09-25 19:32:34 +053013126 if(pHddCtx->cfg_ini->enableFwrMemDump &&
13127 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
13128 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013129 wlanFWLoggingInitParam.enableFlag |= WLAN_FW_MEM_DUMP_EN;
c_manjeecfd1efb2015-09-25 19:32:34 +053013130 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013131 if( wlanFWLoggingInitParam.enableFlag == 0 )
c_manjeecfd1efb2015-09-25 19:32:34 +053013132 {
13133 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
13134 return;
13135 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013136 wlanFWLoggingInitParam.frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
13137 wlanFWLoggingInitParam.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
13138 wlanFWLoggingInitParam.bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
13139 wlanFWLoggingInitParam.continuousFrameLogging =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013140 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013141
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013142 wlanFWLoggingInitParam.enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013143
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013144 wlanFWLoggingInitParam.minLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013145 pHddCtx->cfg_ini->minLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013146 wlanFWLoggingInitParam.maxLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013147 pHddCtx->cfg_ini->maxLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013148 wlanFWLoggingInitParam.fwlogInitCallback = hdd_init_frame_logging_done;
13149 wlanFWLoggingInitParam.fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013150
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013151 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, &wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013152
13153 if (eHAL_STATUS_SUCCESS != halStatus)
13154 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013155 hddLog(LOGE, FL("sme_InitMgmtFrameLogging failed, returned %d"),
13156 halStatus);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013157 }
13158
13159 return;
13160}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013161
Bhargav shah23c94942015-10-13 12:48:35 +053013162static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
13163{
13164 hdd_adapter_t *adapter;
13165 hdd_adapter_list_node_t *adapter_node, *next;
13166 VOS_STATUS status = VOS_STATUS_SUCCESS;
13167 struct wlan_rps_data rps_data;
13168 int count;
13169
13170 if(!hdd_ctxt->cfg_ini->rps_mask)
13171 {
13172 return;
13173 }
13174
13175 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
13176 {
13177 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
13178 }
13179
13180 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
13181
13182 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
13183 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
13184 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
13185
13186 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
13187
13188 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
13189 {
13190 adapter = adapter_node->pAdapter;
13191 if (NULL != adapter) {
13192 strlcpy(rps_data.ifname, adapter->dev->name,
13193 sizeof(rps_data.ifname));
13194 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
13195 (void *)&rps_data,sizeof(rps_data));
13196 }
13197 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
13198 adapter_node = next;
13199 }
13200}
13201
Masti, Narayanraddi26378462016-01-05 18:20:28 +053013202void wlan_hdd_schedule_defer_scan(struct work_struct *work)
13203{
13204 scan_context_t *scan_ctx =
13205 container_of(work, scan_context_t, scan_work.work);
13206
13207 if (NULL == scan_ctx)
13208 {
13209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13210 FL("scan_ctx is NULL"));
13211 return;
13212 }
13213
13214 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
13215 return;
13216
13217 scan_ctx->attempt++;
13218
13219 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
13220#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13221 scan_ctx->dev,
13222#endif
13223 scan_ctx->scan_request);
13224}
13225
13226int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx,
13227 struct wiphy *wiphy,
13228#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13229 struct net_device *dev,
13230#endif
13231 struct cfg80211_scan_request *request)
13232{
13233 scan_context_t *scan_ctx;
13234
13235 ENTER();
13236 if (0 != (wlan_hdd_validate_context(pHddCtx)))
13237 {
13238 return -1;
13239 }
13240
13241 scan_ctx = &pHddCtx->scan_ctxt;
13242
13243 scan_ctx->wiphy = wiphy;
13244#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13245 scan_ctx->dev = dev;
13246#endif
13247
13248 scan_ctx->scan_request = request;
13249
13250 EXIT();
13251 return 0;
13252}
13253
13254void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
13255 struct wiphy *wiphy,
13256#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13257 struct net_device *dev,
13258#endif
13259 struct cfg80211_scan_request *request,
13260 unsigned long delay)
13261{
13262 if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic)
13263 {
13264#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13265 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request);
13266#else
13267 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request);
13268#endif
13269 pHddCtx->scan_ctxt.attempt = 0;
13270 pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC;
13271 }
13272 schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay);
13273}
13274
13275void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx)
13276{
13277 scan_ctx->magic = 0;
13278 scan_ctx->attempt = 0;
13279 scan_ctx->reject = 0;
13280 scan_ctx->scan_request = NULL;
13281
13282 return;
13283}
13284
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013285/**---------------------------------------------------------------------------
13286
Jeff Johnson295189b2012-06-20 16:38:30 -070013287 \brief hdd_wlan_startup() - HDD init function
13288
13289 This is the driver startup code executed once a WLAN device has been detected
13290
13291 \param - dev - Pointer to the underlying device
13292
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013293 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -070013294
13295 --------------------------------------------------------------------------*/
13296
13297int hdd_wlan_startup(struct device *dev )
13298{
13299 VOS_STATUS status;
13300 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070013301 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013302 hdd_context_t *pHddCtx = NULL;
13303 v_CONTEXT_t pVosContext= NULL;
13304#ifdef WLAN_BTAMP_FEATURE
13305 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
13306 WLANBAP_ConfigType btAmpConfig;
13307 hdd_config_t *pConfig;
13308#endif
13309 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013310 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013311 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -070013312
13313 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013314 /*
13315 * cfg80211: wiphy allocation
13316 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013317 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070013318
13319 if(wiphy == NULL)
13320 {
13321 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013322 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013323 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013324 pHddCtx = wiphy_priv(wiphy);
13325
Jeff Johnson295189b2012-06-20 16:38:30 -070013326 //Initialize the adapter context to zeros.
13327 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
13328
Jeff Johnson295189b2012-06-20 16:38:30 -070013329 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013330 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +053013331 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070013332
13333 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
13334
Siddharth Bhalcd92b782015-06-29 12:25:40 +053013335 /* register for riva power on lock to platform driver
13336 * Locking power early to ensure FW doesn't reset by kernel while
13337 * host driver is busy initializing itself */
13338 if (req_riva_power_on_lock("wlan"))
13339 {
13340 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
13341 __func__);
13342 goto err_free_hdd_context;
13343 }
13344
Jeff Johnson295189b2012-06-20 16:38:30 -070013345 /*Get vos context here bcoz vos_open requires it*/
13346 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13347
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -080013348 if(pVosContext == NULL)
13349 {
13350 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
13351 goto err_free_hdd_context;
13352 }
13353
Jeff Johnson295189b2012-06-20 16:38:30 -070013354 //Save the Global VOSS context in adapter context for future.
13355 pHddCtx->pvosContext = pVosContext;
13356
13357 //Save the adapter context in global context for future.
13358 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
13359
Jeff Johnson295189b2012-06-20 16:38:30 -070013360 pHddCtx->parent_dev = dev;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053013361 pHddCtx->last_scan_reject_session_id = 0xFF;
13362 pHddCtx->last_scan_reject_reason = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013363 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053013364 pHddCtx->scan_reject_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013365
13366 init_completion(&pHddCtx->full_pwr_comp_var);
13367 init_completion(&pHddCtx->standby_comp_var);
13368 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013369 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013370 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +053013371 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053013372 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053013373 init_completion(&pHddCtx->mc_sus_event_var);
13374 init_completion(&pHddCtx->tx_sus_event_var);
13375 init_completion(&pHddCtx->rx_sus_event_var);
13376
Amar Singhala49cbc52013-10-08 18:37:44 -070013377
mukul sharma4bd8d2e2015-08-13 20:33:25 +053013378 hdd_init_ll_stats_ctx(pHddCtx);
Anurag Chouhan6ee81542017-02-09 18:09:27 +053013379 hdd_init_nud_stats_ctx(pHddCtx);
mukul sharma4bd8d2e2015-08-13 20:33:25 +053013380
Amar Singhala49cbc52013-10-08 18:37:44 -070013381#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -070013382 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -070013383#else
13384 init_completion(&pHddCtx->driver_crda_req);
13385#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013386
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +053013387#ifdef WLAN_FEATURE_EXTSCAN
13388 init_completion(&pHddCtx->ext_scan_context.response_event);
13389#endif /* WLAN_FEATURE_EXTSCAN */
13390
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013391 spin_lock_init(&pHddCtx->schedScan_lock);
Kapil Gupta137ef892016-12-13 19:38:00 +053013392 vos_spin_lock_init(&pHddCtx->sap_update_info_lock);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013393
Jeff Johnson295189b2012-06-20 16:38:30 -070013394 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
13395
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053013396 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
13397 hdd_processSpoofMacAddrRequest);
Kapil Gupta137ef892016-12-13 19:38:00 +053013398 vos_init_work(&pHddCtx->sap_start_work, hdd_sap_restart_handle);
Abhishek Singh78c691f2017-11-30 13:48:44 +053013399 vos_init_delayed_work(&pHddCtx->ecsa_chan_change_work,
13400 hdd_force_scc_with_ecsa_handle);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053013401
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013402#ifdef FEATURE_WLAN_TDLS
13403 /* tdls_lock is initialized before an hdd_open_adapter ( which is
13404 * invoked by other instances also) to protect the concurrent
13405 * access for the Adapters by TDLS module.
13406 */
13407 mutex_init(&pHddCtx->tdls_lock);
13408#endif
Siddharth Bhal76972212014-10-15 16:22:51 +053013409 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +053013410 mutex_init(&pHddCtx->wmmLock);
13411
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +053013412 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +053013413 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013414
Agarwal Ashish1f422872014-07-22 00:11:55 +053013415 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013416 // Load all config first as TL config is needed during vos_open
13417 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
13418 if(pHddCtx->cfg_ini == NULL)
13419 {
13420 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
13421 goto err_free_hdd_context;
13422 }
13423
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053013424 hdd_request_manager_init();
13425
Jeff Johnson295189b2012-06-20 16:38:30 -070013426 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
13427
13428 // Read and parse the qcom_cfg.ini file
13429 status = hdd_parse_config_ini( pHddCtx );
13430 if ( VOS_STATUS_SUCCESS != status )
13431 {
13432 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
13433 __func__, WLAN_INI_FILE);
13434 goto err_config;
13435 }
Arif Hussaind5218912013-12-05 01:10:55 -080013436#ifdef MEMORY_DEBUG
13437 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
13438 vos_mem_init();
13439
13440 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
13441 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
13442#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013443
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +053013444 /* INI has been read, initialise the configuredMcastBcastFilter with
13445 * INI value as this will serve as the default value
13446 */
13447 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
13448 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
13449 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013450
13451 if (false == hdd_is_5g_supported(pHddCtx))
13452 {
13453 //5Ghz is not supported.
13454 if (1 != pHddCtx->cfg_ini->nBandCapability)
13455 {
13456 hddLog(VOS_TRACE_LEVEL_INFO,
13457 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
13458 pHddCtx->cfg_ini->nBandCapability = 1;
13459 }
13460 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013461
13462 /* If SNR Monitoring is enabled, FW has to parse all beacons
13463 * for calcaluting and storing the average SNR, so set Nth beacon
13464 * filter to 1 to enable FW to parse all the beaocons
13465 */
13466 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
13467 {
13468 /* The log level is deliberately set to WARN as overriding
13469 * nthBeaconFilter to 1 will increase power cosumption and this
13470 * might just prove helpful to detect the power issue.
13471 */
13472 hddLog(VOS_TRACE_LEVEL_WARN,
13473 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
13474 pHddCtx->cfg_ini->nthBeaconFilter = 1;
13475 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013476 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013477 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -070013478 */
Manjeet Singh61016fa2016-12-02 11:10:19 +053013479 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
Jeff Johnson295189b2012-06-20 16:38:30 -070013480 {
Manjeet Singh61016fa2016-12-02 11:10:19 +053013481 hddLog(VOS_TRACE_LEVEL_FATAL,
13482 "%s: wlan_hdd_cfg80211_init return failure", __func__);
13483 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070013484 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013485
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013486 // Update VOS trace levels based upon the cfg.ini
13487 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
13488 pHddCtx->cfg_ini->vosTraceEnableBAP);
13489 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
13490 pHddCtx->cfg_ini->vosTraceEnableTL);
13491 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
13492 pHddCtx->cfg_ini->vosTraceEnableWDI);
13493 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
13494 pHddCtx->cfg_ini->vosTraceEnableHDD);
13495 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
13496 pHddCtx->cfg_ini->vosTraceEnableSME);
13497 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
13498 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +053013499 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
13500 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013501 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
13502 pHddCtx->cfg_ini->vosTraceEnableWDA);
13503 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
13504 pHddCtx->cfg_ini->vosTraceEnableSYS);
13505 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
13506 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013507 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
13508 pHddCtx->cfg_ini->vosTraceEnableSAP);
13509 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
13510 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013511
Jeff Johnson295189b2012-06-20 16:38:30 -070013512 // Update WDI trace levels based upon the cfg.ini
13513 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
13514 pHddCtx->cfg_ini->wdiTraceEnableDAL);
13515 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
13516 pHddCtx->cfg_ini->wdiTraceEnableCTL);
13517 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
13518 pHddCtx->cfg_ini->wdiTraceEnableDAT);
13519 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
13520 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -070013521
Jeff Johnson88ba7742013-02-27 14:36:02 -080013522 if (VOS_FTM_MODE == hdd_get_conparam())
13523 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013524 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
13525 {
13526 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
13527 goto err_free_hdd_context;
13528 }
13529 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +053013530 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +053013531 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -070013532 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -080013533 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013534
Katya Nigame7b69a82015-04-28 15:24:06 +053013535 if( VOS_MONITOR_MODE == hdd_get_conparam())
13536 {
13537 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
13538 {
13539 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
13540 goto err_free_hdd_context;
13541 }
13542 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
13543 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
13544 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
13545 return VOS_STATUS_SUCCESS;
13546 }
13547
Jeff Johnson88ba7742013-02-27 14:36:02 -080013548 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -070013549 if(pHddCtx->cfg_ini->fIsLogpEnabled)
13550 {
13551 status = vos_watchdog_open(pVosContext,
13552 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
13553
13554 if(!VOS_IS_STATUS_SUCCESS( status ))
13555 {
13556 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Ashish Kumar Dhanotiya532bdef2017-05-09 17:31:59 +053013557 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070013558 }
13559 }
13560
13561 pHddCtx->isLogpInProgress = FALSE;
13562 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
13563
Amar Singhala49cbc52013-10-08 18:37:44 -070013564#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070013565 /* initialize the NV module. This is required so that
13566 we can initialize the channel information in wiphy
13567 from the NV.bin data. The channel information in
13568 wiphy needs to be initialized before wiphy registration */
13569
13570 status = vos_nv_open();
13571 if (!VOS_IS_STATUS_SUCCESS(status))
13572 {
13573 /* NV module cannot be initialized */
13574 hddLog( VOS_TRACE_LEVEL_FATAL,
13575 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +053013576 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -070013577 }
13578
13579 status = vos_init_wiphy_from_nv_bin();
13580 if (!VOS_IS_STATUS_SUCCESS(status))
13581 {
13582 /* NV module cannot be initialized */
13583 hddLog( VOS_TRACE_LEVEL_FATAL,
13584 "%s: vos_init_wiphy failed", __func__);
13585 goto err_vos_nv_close;
13586 }
13587
Amar Singhala49cbc52013-10-08 18:37:44 -070013588#endif
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013589 //Initialize the nlink service
13590 if(nl_srv_init() != 0)
13591 {
13592 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
13593 goto err_vos_nv_close;
13594 }
13595
13596#ifdef WLAN_KD_READY_NOTIFIER
13597 pHddCtx->kd_nl_init = 1;
13598#endif /* WLAN_KD_READY_NOTIFIER */
13599
Girish Gowlibf0e1ab2015-01-19 16:05:16 +053013600 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053013601 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070013602 if ( !VOS_IS_STATUS_SUCCESS( status ))
13603 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013604 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013605 goto err_nl_srv;
Jeff Johnson295189b2012-06-20 16:38:30 -070013606 }
13607
Jeff Johnson295189b2012-06-20 16:38:30 -070013608 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
13609
13610 if ( NULL == pHddCtx->hHal )
13611 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013612 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013613 goto err_vosclose;
13614 }
13615
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013616 status = vos_preStart( pHddCtx->pvosContext );
13617 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13618 {
13619 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013620 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013621 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013622
Arif Hussaineaf68602013-12-30 23:10:44 -080013623 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
13624 {
13625 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
13626 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
13627 __func__, enable_dfs_chan_scan);
13628 }
13629 if (0 == enable_11d || 1 == enable_11d)
13630 {
13631 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
13632 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
13633 __func__, enable_11d);
13634 }
13635
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013636 /* Note that the vos_preStart() sequence triggers the cfg download.
13637 The cfg download must occur before we update the SME config
13638 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -070013639 status = hdd_set_sme_config( pHddCtx );
13640
13641 if ( VOS_STATUS_SUCCESS != status )
13642 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013643 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013644 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013645 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013646
Jeff Johnson295189b2012-06-20 16:38:30 -070013647 /* In the integrated architecture we update the configuration from
13648 the INI file and from NV before vOSS has been started so that
13649 the final contents are available to send down to the cCPU */
13650
13651 // Apply the cfg.ini to cfg.dat
13652 if (FALSE == hdd_update_config_dat(pHddCtx))
13653 {
13654 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013655 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013656 }
13657
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013658 // Get mac addr from platform driver
13659 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
13660
13661 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013662 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013663 /* Store the mac addr for first interface */
13664 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
13665
13666 hddLog(VOS_TRACE_LEVEL_ERROR,
13667 "%s: WLAN Mac Addr: "
13668 MAC_ADDRESS_STR, __func__,
13669 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
13670
13671 /* Here, passing Arg2 as 1 because we do not want to change the
13672 last 3 bytes (means non OUI bytes) of first interface mac
13673 addr.
13674 */
13675 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
13676 {
13677 hddLog(VOS_TRACE_LEVEL_ERROR,
13678 "%s: Failed to generate wlan interface mac addr "
13679 "using MAC from ini file ", __func__);
13680 }
13681 }
13682 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
13683 {
13684 // Apply the NV to cfg.dat
13685 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070013686#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
13687 /* There was not a valid set of MAC Addresses in NV. See if the
13688 default addresses were modified by the cfg.ini settings. If so,
13689 we'll use them, but if not, we'll autogenerate a set of MAC
13690 addresses based upon the device serial number */
13691
13692 static const v_MACADDR_t default_address =
13693 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070013694
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013695 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
13696 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013697 {
13698 /* cfg.ini has the default address, invoke autogen logic */
13699
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013700 /* Here, passing Arg2 as 0 because we want to change the
13701 last 3 bytes (means non OUI bytes) of all the interfaces
13702 mac addr.
13703 */
13704 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
13705 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070013706 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013707 hddLog(VOS_TRACE_LEVEL_ERROR,
13708 "%s: Failed to generate wlan interface mac addr "
13709 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
13710 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070013711 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013712 }
13713 else
13714#endif //WLAN_AUTOGEN_MACADDR_FEATURE
13715 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013716 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013717 "%s: Invalid MAC address in NV, using MAC from ini file "
13718 MAC_ADDRESS_STR, __func__,
13719 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
13720 }
13721 }
13722 {
13723 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013724
13725 /* Set the MAC Address Currently this is used by HAL to
13726 * add self sta. Remove this once self sta is added as
13727 * part of session open.
13728 */
Jeff Johnson295189b2012-06-20 16:38:30 -070013729 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
13730 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
13731 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013732
Jeff Johnson295189b2012-06-20 16:38:30 -070013733 if (!HAL_STATUS_SUCCESS( halStatus ))
13734 {
13735 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
13736 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013737 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013738 }
13739 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013740
13741 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
13742 Note: Firmware image will be read and downloaded inside vos_start API */
13743 status = vos_start( pHddCtx->pvosContext );
13744 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13745 {
13746 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053013747 if (isSsrPanicOnFailure())
13748 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013749 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013750 }
13751
Leo Chang6cec3e22014-01-21 15:33:49 -080013752#ifdef FEATURE_WLAN_CH_AVOID
13753 /* Plug in avoid channel notification callback
13754 * This should happen before ADD_SELF_STA
13755 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053013756
13757 /* check the Channel Avoidance is enabled */
13758 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
13759 {
13760 sme_AddChAvoidCallback(pHddCtx->hHal,
13761 hdd_hostapd_ch_avoid_cb);
13762 }
Leo Chang6cec3e22014-01-21 15:33:49 -080013763#endif /* FEATURE_WLAN_CH_AVOID */
13764
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070013765 /* Exchange capability info between Host and FW and also get versioning info from FW */
13766 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070013767
Agarwal Ashishad9281b2014-06-10 14:57:30 +053013768#ifdef CONFIG_ENABLE_LINUX_REG
13769 status = wlan_hdd_init_channels(pHddCtx);
13770 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13771 {
13772 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
13773 __func__);
13774 goto err_vosstop;
13775 }
13776#endif
13777
Jeff Johnson295189b2012-06-20 16:38:30 -070013778 status = hdd_post_voss_start_config( pHddCtx );
13779 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13780 {
13781 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
13782 __func__);
13783 goto err_vosstop;
13784 }
Amar Singhala49cbc52013-10-08 18:37:44 -070013785
13786#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013787 wlan_hdd_cfg80211_update_reg_info( wiphy );
13788
13789 /* registration of wiphy dev with cfg80211 */
13790 if (0 > wlan_hdd_cfg80211_register(wiphy))
13791 {
13792 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
13793 goto err_vosstop;
13794 }
Amar Singhala49cbc52013-10-08 18:37:44 -070013795#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013796
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013797#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013798 /* registration of wiphy dev with cfg80211 */
13799 if (0 > wlan_hdd_cfg80211_register(wiphy))
13800 {
13801 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
13802 goto err_vosstop;
13803 }
13804
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013805 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013806 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13807 {
13808 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
13809 __func__);
13810 goto err_unregister_wiphy;
13811 }
13812#endif
13813
c_hpothu4a298be2014-12-22 21:12:51 +053013814 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
13815
Jeff Johnson295189b2012-06-20 16:38:30 -070013816 if (VOS_STA_SAP_MODE == hdd_get_conparam())
13817 {
13818 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
13819 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13820 }
13821 else
13822 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013823 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
13824 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13825 if (pAdapter != NULL)
13826 {
Katya Nigama7d81d72014-11-12 12:44:34 +053013827 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070013828 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053013829 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
13830 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
13831 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070013832
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053013833 /* Generate the P2P Device Address. This consists of the device's
13834 * primary MAC address with the locally administered bit set.
13835 */
13836 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070013837 }
13838 else
13839 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053013840 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
13841 if (p2p_dev_addr != NULL)
13842 {
13843 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
13844 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
13845 }
13846 else
13847 {
13848 hddLog(VOS_TRACE_LEVEL_FATAL,
13849 "%s: Failed to allocate mac_address for p2p_device",
13850 __func__);
13851 goto err_close_adapter;
13852 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013853 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013854
13855 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
13856 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
13857 if ( NULL == pP2pAdapter )
13858 {
13859 hddLog(VOS_TRACE_LEVEL_FATAL,
13860 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013861 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070013862 goto err_close_adapter;
13863 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013864 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013865 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013866
13867 if( pAdapter == NULL )
13868 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013869 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
13870 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070013871 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013872
Arif Hussain66559122013-11-21 10:11:40 -080013873 if (country_code)
13874 {
13875 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080013876 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080013877 hdd_checkandupdate_dfssetting(pAdapter, country_code);
13878#ifndef CONFIG_ENABLE_LINUX_REG
13879 hdd_checkandupdate_phymode(pAdapter, country_code);
13880#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080013881 ret = sme_ChangeCountryCode(pHddCtx->hHal,
13882 (void *)(tSmeChangeCountryCallback)
13883 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080013884 country_code,
13885 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053013886 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080013887 if (eHAL_STATUS_SUCCESS == ret)
13888 {
Arif Hussaincb607082013-12-20 11:57:42 -080013889 ret = wait_for_completion_interruptible_timeout(
13890 &pAdapter->change_country_code,
13891 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
13892
13893 if (0 >= ret)
13894 {
13895 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13896 "%s: SME while setting country code timed out", __func__);
13897 }
Arif Hussain66559122013-11-21 10:11:40 -080013898 }
13899 else
13900 {
Arif Hussaincb607082013-12-20 11:57:42 -080013901 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13902 "%s: SME Change Country code from module param fail ret=%d",
13903 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080013904 }
13905 }
13906
Jeff Johnson295189b2012-06-20 16:38:30 -070013907#ifdef WLAN_BTAMP_FEATURE
13908 vStatus = WLANBAP_Open(pVosContext);
13909 if(!VOS_IS_STATUS_SUCCESS(vStatus))
13910 {
13911 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13912 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070013913 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070013914 }
13915
13916 vStatus = BSL_Init(pVosContext);
13917 if(!VOS_IS_STATUS_SUCCESS(vStatus))
13918 {
13919 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13920 "%s: Failed to Init BSL",__func__);
13921 goto err_bap_close;
13922 }
13923 vStatus = WLANBAP_Start(pVosContext);
13924 if (!VOS_IS_STATUS_SUCCESS(vStatus))
13925 {
13926 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13927 "%s: Failed to start TL",__func__);
13928 goto err_bap_close;
13929 }
13930
13931 pConfig = pHddCtx->cfg_ini;
13932 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
13933 status = WLANBAP_SetConfig(&btAmpConfig);
13934
13935#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070013936
Mihir Shete9c238772014-10-15 14:35:16 +053013937 /*
13938 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
13939 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
13940 * which is greater than 0xf. So the below check is safe to make
13941 * sure that there is no entry for UapsdMask in the ini
13942 */
13943 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
13944 {
13945 if(IS_DYNAMIC_WMM_PS_ENABLED)
13946 {
13947 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
13948 __func__);
13949 pHddCtx->cfg_ini->UapsdMask =
13950 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
13951 }
13952 else
13953 {
13954 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
13955 __func__);
13956 pHddCtx->cfg_ini->UapsdMask =
13957 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
13958 }
13959 }
13960
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070013961#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
13962 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
13963 {
13964 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
13965 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
13966 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
13967 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
13968 }
13969#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013970
Agarwal Ashish4b87f922014-06-18 03:03:21 +053013971 wlan_hdd_tdls_init(pHddCtx);
13972
Masti, Narayanraddi26378462016-01-05 18:20:28 +053013973 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
13974
13975 vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work,
13976 wlan_hdd_schedule_defer_scan);
13977
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013978 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
13979
Jeff Johnson295189b2012-06-20 16:38:30 -070013980 /* Register with platform driver as client for Suspend/Resume */
13981 status = hddRegisterPmOps(pHddCtx);
13982 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13983 {
13984 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
13985#ifdef WLAN_BTAMP_FEATURE
13986 goto err_bap_stop;
13987#else
Jeff Johnsone7245742012-09-05 17:12:55 -070013988 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070013989#endif //WLAN_BTAMP_FEATURE
13990 }
13991
Yue Ma0d4891e2013-08-06 17:01:45 -070013992 /* Open debugfs interface */
13993 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
13994 {
13995 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13996 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070013997 }
13998
Jeff Johnson295189b2012-06-20 16:38:30 -070013999 /* Register TM level change handler function to the platform */
14000 status = hddDevTmRegisterNotifyCallback(pHddCtx);
14001 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14002 {
14003 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
14004 goto err_unregister_pmops;
14005 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014006
Jeff Johnson295189b2012-06-20 16:38:30 -070014007 // register net device notifier for device change notification
14008 ret = register_netdevice_notifier(&hdd_netdev_notifier);
14009
14010 if(ret < 0)
14011 {
14012 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053014013 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070014014 }
14015
Jeff Johnson295189b2012-06-20 16:38:30 -070014016 //Initialize the BTC service
14017 if(btc_activate_service(pHddCtx) != 0)
14018 {
14019 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053014020 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070014021 }
14022
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053014023#ifdef FEATURE_OEM_DATA_SUPPORT
14024 //Initialize the OEM service
14025 if (oem_activate_service(pHddCtx) != 0)
14026 {
14027 hddLog(VOS_TRACE_LEVEL_FATAL,
14028 "%s: oem_activate_service failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014029 goto err_btc_activate_service;
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053014030 }
14031#endif
14032
Jeff Johnson295189b2012-06-20 16:38:30 -070014033#ifdef PTT_SOCK_SVC_ENABLE
14034 //Initialize the PTT service
14035 if(ptt_sock_activate_svc(pHddCtx) != 0)
14036 {
14037 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014038 goto err_oem_activate_service;
Jeff Johnson295189b2012-06-20 16:38:30 -070014039 }
14040#endif
14041
Abhishek Singh00b71972016-01-07 10:51:04 +053014042#ifdef WLAN_FEATURE_RMC
14043 if (hdd_open_cesium_nl_sock() < 0)
14044 {
14045 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014046 goto err_ptt_sock_activate_svc;
Abhishek Singh00b71972016-01-07 10:51:04 +053014047 }
14048#endif
14049
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014050#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14051 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
14052 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053014053 if(wlan_logging_sock_activate_svc(
14054 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053014055 pHddCtx->cfg_ini->wlanLoggingNumBuf,
14056 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
14057 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053014058 {
14059 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
14060 " failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014061 goto err_open_cesium_nl_sock;
Deepthi Gowri78083a32014-11-04 12:55:51 +053014062 }
14063 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
14064 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053014065 if (!pHddCtx->cfg_ini->gEnableDebugLog)
14066 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053014067 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
14068 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014069 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014070
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014071 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
14072 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053014073 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053014074 pHddCtx->cfg_ini->enableContFWLogging ||
14075 pHddCtx->cfg_ini->enableFwrMemDump )
14076 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014077 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014078 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014079 }
14080 else
14081 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014082 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014083 }
14084
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014085#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014086
Agrawal Ashish17ef5082016-10-17 18:33:21 +053014087#ifdef SAP_AUTH_OFFLOAD
14088 if (!sme_IsFeatureSupportedByFW(SAP_OFFLOADS))
14089 {
14090 hddLog(VOS_TRACE_LEVEL_INFO, FL(" SAP AUTH OFFLOAD not supp by FW"));
14091 pHddCtx->cfg_ini->enable_sap_auth_offload = 0;
14092 }
14093#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014094
Sushant Kaushik215778f2015-05-21 14:05:36 +053014095 if (vos_is_multicast_logging())
14096 wlan_logging_set_log_level();
14097
Jeff Johnson295189b2012-06-20 16:38:30 -070014098 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070014099 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070014100 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070014101 /* Action frame registered in one adapter which will
14102 * applicable to all interfaces
14103 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053014104 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014105 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014106
14107 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053014108 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070014109
Jeff Johnsone7245742012-09-05 17:12:55 -070014110#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
14111 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014112 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070014113 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014114
Jeff Johnsone7245742012-09-05 17:12:55 -070014115#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080014116 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014117 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080014118 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014119
Jeff Johnsone7245742012-09-05 17:12:55 -070014120
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014121 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
14122 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070014123
Katya Nigam5c306ea2014-06-19 15:39:54 +053014124 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070014125 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014126 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053014127
14128#ifdef FEATURE_WLAN_SCAN_PNO
14129 /*SME must send channel update configuration to RIVA*/
14130 sme_UpdateChannelConfig(pHddCtx->hHal);
14131#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053014132 /* Send the update default channel list to the FW*/
14133 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053014134
14135 /* Fwr capabilities received, Set the Dot11 mode */
Abhishek Singh41ebce12016-02-03 10:43:21 +053014136 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
14137 hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode));
Mukul Sharma45063942015-04-01 20:07:59 +053014138 sme_SetDefDot11Mode(pHddCtx->hHal);
14139
Abhishek Singha306a442013-11-07 18:39:01 +053014140#ifndef CONFIG_ENABLE_LINUX_REG
14141 /*updating wiphy so that regulatory user hints can be processed*/
14142 if (wiphy)
14143 {
14144 regulatory_hint(wiphy, "00");
14145 }
14146#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070014147 // Initialize the restart logic
14148 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053014149
Hanumanth Reddy Pothula146bca42016-11-08 12:01:07 +053014150 if (pHddCtx->cfg_ini->fIsLogpEnabled) {
14151 vos_wdthread_init_timer_work(vos_process_wd_timer);
14152 /* Initialize the timer to detect thread stuck issues */
14153 vos_thread_stuck_timer_init(
14154 &((VosContextType*)pVosContext)->vosWatchdog);
14155 }
14156
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070014157 //Register the traffic monitor timer now
14158 if ( pHddCtx->cfg_ini->dynSplitscan)
14159 {
14160 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
14161 VOS_TIMER_TYPE_SW,
14162 hdd_tx_rx_pkt_cnt_stat_timer_handler,
14163 (void *)pHddCtx);
14164 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053014165 wlan_hdd_cfg80211_nan_init(pHddCtx);
14166
Bhargav Shahd0715912015-10-01 18:17:37 +053014167 mutex_init(&pHddCtx->cur_rx_level_lock);
14168 vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
14169 hdd_tcp_delack_compute_function,(void *)pHddCtx);
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053014170 vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW,
14171 wlan_hdd_change_tdls_mode, (void *)pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +053014172
Dino Mycle6fb96c12014-06-10 11:52:40 +053014173#ifdef WLAN_FEATURE_EXTSCAN
14174 sme_EXTScanRegisterCallback(pHddCtx->hHal,
14175 wlan_hdd_cfg80211_extscan_callback,
14176 pHddCtx);
14177#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014178
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053014179#ifdef FEATURE_OEM_DATA_SUPPORT
14180 sme_OemDataRegisterCallback(pHddCtx->hHal,
14181 wlan_hdd_cfg80211_oemdata_callback,
14182 pHddCtx);
14183#endif /* FEATURE_OEM_DATA_SUPPORT */
14184
Gupta, Kapil7c34b322015-09-30 13:12:35 +053014185 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014186#ifdef WLAN_NS_OFFLOAD
14187 // Register IPv6 notifier to notify if any change in IP
14188 // So that we can reconfigure the offload parameters
14189 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
14190 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
14191 if (ret)
14192 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014193 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014194 }
14195 else
14196 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014197 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014198 }
14199#endif
14200
Sravan Kumar Kairamb0edc612016-10-26 13:55:24 +053014201 vos_mem_set((uint8_t *)&pHddCtx->bad_sta, HDD_MAX_STA_COUNT, 0);
14202
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014203 // Register IPv4 notifier to notify if any change in IP
14204 // So that we can reconfigure the offload parameters
14205 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
14206 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
14207 if (ret)
14208 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014209 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014210 }
14211 else
14212 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014213 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014214 }
c_manjeecfd1efb2015-09-25 19:32:34 +053014215 /*Fw mem dump procfs initialization*/
14216 memdump_init();
Bhargav shah23c94942015-10-13 12:48:35 +053014217 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014218
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053014219 pHddCtx->is_ap_mode_wow_supported =
14220 sme_IsFeatureSupportedByFW(SAP_MODE_WOW);
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053014221
Hanumanth Reddy Pothulae92bcc12017-05-19 13:56:35 +053014222 pHddCtx->is_fatal_event_log_sup =
14223 sme_IsFeatureSupportedByFW(FATAL_EVENT_LOGGING);
14224 hddLog(VOS_TRACE_LEVEL_INFO, FL("FATAL_EVENT_LOGGING: %d"),
14225 pHddCtx->is_fatal_event_log_sup);
14226
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053014227 hdd_assoc_registerFwdEapolCB(pVosContext);
14228
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053014229 mutex_init(&pHddCtx->cache_channel_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070014230 goto success;
14231
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014232err_open_cesium_nl_sock:
14233#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14234 hdd_close_cesium_nl_sock();
14235#endif
14236
14237err_ptt_sock_activate_svc:
14238#ifdef PTT_SOCK_SVC_ENABLE
14239 ptt_sock_deactivate_svc(pHddCtx);
14240#endif
14241
14242err_oem_activate_service:
14243#ifdef FEATURE_OEM_DATA_SUPPORT
14244 oem_deactivate_service();
14245#endif
14246
14247err_btc_activate_service:
14248 btc_deactivate_service();
14249
Jeff Johnson295189b2012-06-20 16:38:30 -070014250err_reg_netdev:
14251 unregister_netdevice_notifier(&hdd_netdev_notifier);
14252
Jeff Johnson295189b2012-06-20 16:38:30 -070014253err_unregister_pmops:
14254 hddDevTmUnregisterNotifyCallback(pHddCtx);
14255 hddDeregisterPmOps(pHddCtx);
14256
Yue Ma0d4891e2013-08-06 17:01:45 -070014257 hdd_debugfs_exit(pHddCtx);
14258
Jeff Johnson295189b2012-06-20 16:38:30 -070014259#ifdef WLAN_BTAMP_FEATURE
14260err_bap_stop:
14261 WLANBAP_Stop(pVosContext);
14262#endif
14263
14264#ifdef WLAN_BTAMP_FEATURE
14265err_bap_close:
14266 WLANBAP_Close(pVosContext);
14267#endif
14268
Jeff Johnson295189b2012-06-20 16:38:30 -070014269err_close_adapter:
14270 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053014271#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053014272err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053014273#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053014274 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053014275 hdd_wlan_free_wiphy_channels(wiphy);
14276
Jeff Johnson295189b2012-06-20 16:38:30 -070014277err_vosstop:
14278 vos_stop(pVosContext);
14279
Amar Singhala49cbc52013-10-08 18:37:44 -070014280err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070014281 status = vos_sched_close( pVosContext );
14282 if (!VOS_IS_STATUS_SUCCESS(status)) {
14283 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
14284 "%s: Failed to close VOSS Scheduler", __func__);
14285 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
14286 }
Amar Singhala49cbc52013-10-08 18:37:44 -070014287 vos_close(pVosContext );
14288
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053014289err_nl_srv:
14290#ifdef WLAN_KD_READY_NOTIFIER
14291 nl_srv_exit(pHddCtx->ptt_pid);
14292#else
14293 nl_srv_exit();
14294#endif /* WLAN_KD_READY_NOTIFIER */
Amar Singhal0a402232013-10-11 20:57:16 -070014295err_vos_nv_close:
14296
c_hpothue6a36282014-03-19 12:27:38 +053014297#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070014298 vos_nv_close();
14299
c_hpothu70f8d812014-03-22 22:59:23 +053014300#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014301
14302err_wdclose:
14303 if(pHddCtx->cfg_ini->fIsLogpEnabled)
14304 vos_watchdog_close(pVosContext);
14305
Jeff Johnson295189b2012-06-20 16:38:30 -070014306err_config:
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053014307 hdd_request_manager_deinit();
Jeff Johnson295189b2012-06-20 16:38:30 -070014308 kfree(pHddCtx->cfg_ini);
14309 pHddCtx->cfg_ini= NULL;
14310
14311err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014312 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053014313 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070014314 wiphy_free(wiphy) ;
14315 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070014316 VOS_BUG(1);
14317
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080014318 if (hdd_is_ssr_required())
14319 {
14320 /* WDI timeout had happened during load, so SSR is needed here */
14321 subsystem_restart("wcnss");
14322 msleep(5000);
14323 }
14324 hdd_set_ssr_required (VOS_FALSE);
14325
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014326 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070014327
14328success:
14329 EXIT();
14330 return 0;
14331}
14332
14333/**---------------------------------------------------------------------------
14334
Jeff Johnson32d95a32012-09-10 13:15:23 -070014335 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070014336
Jeff Johnson32d95a32012-09-10 13:15:23 -070014337 This is the driver entry point - called in different timeline depending
14338 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070014339
14340 \param - None
14341
14342 \return - 0 for success, non zero for failure
14343
14344 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070014345static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070014346{
14347 VOS_STATUS status;
14348 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014349 struct device *dev = NULL;
14350 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014351#ifdef HAVE_WCNSS_CAL_DOWNLOAD
14352 int max_retries = 0;
14353#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014354#ifdef HAVE_CBC_DONE
14355 int max_cbc_retries = 0;
14356#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014357
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014358#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14359 wlan_logging_sock_init_svc();
14360#endif
14361
Jeff Johnson295189b2012-06-20 16:38:30 -070014362 ENTER();
14363
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014364 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070014365
14366 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
14367 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
14368
Jeff Johnson295189b2012-06-20 16:38:30 -070014369#ifdef ANI_BUS_TYPE_PCI
14370
14371 dev = wcnss_wlan_get_device();
14372
14373#endif // ANI_BUS_TYPE_PCI
14374
14375#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014376
14377#ifdef HAVE_WCNSS_CAL_DOWNLOAD
14378 /* wait until WCNSS driver downloads NV */
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053014379 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014380 msleep(1000);
14381 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014382
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053014383 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014384 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014385 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014386#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14387 wlan_logging_sock_deinit_svc();
14388#endif
14389
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014390 return -ENODEV;
14391 }
14392#endif
14393
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014394#ifdef HAVE_CBC_DONE
14395 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
14396 msleep(1000);
14397 }
14398 if (max_cbc_retries >= 10) {
14399 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
14400 }
14401#endif
14402
Jeff Johnson295189b2012-06-20 16:38:30 -070014403 dev = wcnss_wlan_get_device();
14404#endif // ANI_BUS_TYPE_PLATFORM
14405
14406
14407 do {
14408 if (NULL == dev) {
14409 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
14410 ret_status = -1;
14411 break;
14412 }
14413
Jeff Johnson295189b2012-06-20 16:38:30 -070014414#ifdef TIMER_MANAGER
14415 vos_timer_manager_init();
14416#endif
14417
14418 /* Preopen VOSS so that it is ready to start at least SAL */
14419 status = vos_preOpen(&pVosContext);
14420
14421 if (!VOS_IS_STATUS_SUCCESS(status))
14422 {
14423 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
14424 ret_status = -1;
14425 break;
14426 }
14427
Sushant Kaushik02beb352015-06-04 15:15:01 +053014428 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053014429 hdd_register_debug_callback();
14430
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014431#ifndef MODULE
14432 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
14433 */
14434 hdd_set_conparam((v_UINT_t)con_mode);
14435#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014436
14437 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014438 if (hdd_wlan_startup(dev))
14439 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014440 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014441 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014442 vos_preClose( &pVosContext );
14443 ret_status = -1;
14444 break;
14445 }
14446
Jeff Johnson295189b2012-06-20 16:38:30 -070014447 } while (0);
14448
14449 if (0 != ret_status)
14450 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014451#ifdef TIMER_MANAGER
14452 vos_timer_exit();
14453#endif
14454#ifdef MEMORY_DEBUG
14455 vos_mem_exit();
14456#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014457 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014458#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14459 wlan_logging_sock_deinit_svc();
14460#endif
14461
Jeff Johnson295189b2012-06-20 16:38:30 -070014462 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
14463 }
14464 else
14465 {
14466 //Send WLAN UP indication to Nlink Service
14467 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
14468
14469 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070014470 }
14471
14472 EXIT();
14473
14474 return ret_status;
14475}
14476
Jeff Johnson32d95a32012-09-10 13:15:23 -070014477/**---------------------------------------------------------------------------
14478
14479 \brief hdd_module_init() - Init Function
14480
14481 This is the driver entry point (invoked when module is loaded using insmod)
14482
14483 \param - None
14484
14485 \return - 0 for success, non zero for failure
14486
14487 --------------------------------------------------------------------------*/
14488#ifdef MODULE
14489static int __init hdd_module_init ( void)
14490{
14491 return hdd_driver_init();
14492}
Jeff Johnson32d95a32012-09-10 13:15:23 -070014493#else /* #ifdef MODULE */
14494static int __init hdd_module_init ( void)
14495{
14496 /* Driver initialization is delayed to fwpath_changed_handler */
14497 return 0;
14498}
Jeff Johnson32d95a32012-09-10 13:15:23 -070014499#endif /* #ifdef MODULE */
14500
Jeff Johnson295189b2012-06-20 16:38:30 -070014501
14502/**---------------------------------------------------------------------------
14503
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014504 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070014505
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014506 This is the driver exit point (invoked when module is unloaded using rmmod
14507 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070014508
14509 \param - None
14510
14511 \return - None
14512
14513 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014514static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070014515{
14516 hdd_context_t *pHddCtx = NULL;
14517 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053014518 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053014519 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014520
14521 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
14522
14523 //Get the global vos context
14524 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14525
14526 if(!pVosContext)
14527 {
14528 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
14529 goto done;
14530 }
14531
14532 //Get the HDD context.
14533 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
14534
14535 if(!pHddCtx)
14536 {
14537 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
14538 }
Katya Nigame7b69a82015-04-28 15:24:06 +053014539 else if (VOS_MONITOR_MODE == hdd_get_conparam())
14540 {
14541 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
14542 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
14543 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
14544 hdd_wlan_exit(pHddCtx);
14545 vos_preClose( &pVosContext );
14546 goto done;
14547 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014548 else
14549 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053014550 /* We wait for active entry threads to exit from driver
14551 * by waiting until rtnl_lock is available.
14552 */
14553 rtnl_lock();
14554 rtnl_unlock();
14555
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014556 INIT_COMPLETION(pHddCtx->ssr_comp_var);
14557 if ((pHddCtx->isLogpInProgress) && (FALSE ==
14558 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
14559 {
Siddharth Bhala204f572015-01-17 02:03:36 +053014560 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014561 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053014562 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
14563 msecs_to_jiffies(30000));
14564 if(!rc)
14565 {
14566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14567 "%s:SSR timedout, fatal error", __func__);
14568 VOS_BUG(0);
14569 }
14570 }
14571
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014572 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
14573 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070014574
c_hpothu8adb97b2014-12-08 19:38:20 +053014575 /* Driver Need to send country code 00 in below condition
14576 * 1) If gCountryCodePriority is set to 1; and last country
14577 * code set is through 11d. This needs to be done in case
14578 * when NV country code is 00.
14579 * This Needs to be done as when kernel store last country
14580 * code and if stored country code is not through 11d,
14581 * in sme_HandleChangeCountryCodeByUser we will disable 11d
14582 * in next load/unload as soon as we get any country through
14583 * 11d. In sme_HandleChangeCountryCodeByUser
14584 * pMsg->countryCode will be last countryCode and
14585 * pMac->scan.countryCode11d will be country through 11d so
14586 * due to mismatch driver will disable 11d.
14587 *
14588 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053014589
c_hpothu8adb97b2014-12-08 19:38:20 +053014590 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053014591 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053014592 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053014593 {
14594 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053014595 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053014596 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
14597 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053014598
c_hpothu8adb97b2014-12-08 19:38:20 +053014599 //Do all the cleanup before deregistering the driver
14600 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070014601 }
14602
Jeff Johnson295189b2012-06-20 16:38:30 -070014603 vos_preClose( &pVosContext );
14604
14605#ifdef TIMER_MANAGER
14606 vos_timer_exit();
14607#endif
14608#ifdef MEMORY_DEBUG
14609 vos_mem_exit();
14610#endif
14611
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014612#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14613 wlan_logging_sock_deinit_svc();
14614#endif
14615
Jeff Johnson295189b2012-06-20 16:38:30 -070014616done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014617 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014618
Jeff Johnson295189b2012-06-20 16:38:30 -070014619 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
14620}
14621
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014622/**---------------------------------------------------------------------------
14623
14624 \brief hdd_module_exit() - Exit function
14625
14626 This is the driver exit point (invoked when module is unloaded using rmmod)
14627
14628 \param - None
14629
14630 \return - None
14631
14632 --------------------------------------------------------------------------*/
14633static void __exit hdd_module_exit(void)
14634{
14635 hdd_driver_exit();
14636}
14637
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014638#ifdef MODULE
14639static int fwpath_changed_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014640 const struct kernel_param *kp)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014641{
Jeff Johnson76052702013-04-16 13:55:05 -070014642 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014643}
14644
14645static int con_mode_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014646 const struct kernel_param *kp)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014647{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070014648 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014649}
14650#else /* #ifdef MODULE */
14651/**---------------------------------------------------------------------------
14652
Jeff Johnson76052702013-04-16 13:55:05 -070014653 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014654
Jeff Johnson76052702013-04-16 13:55:05 -070014655 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014656 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070014657 - invoked when module parameter fwpath is modified from userspace to signal
14658 initializing the WLAN driver or when con_mode is modified from userspace
14659 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014660
14661 \return - 0 for success, non zero for failure
14662
14663 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070014664static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014665{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014666 int ret_status;
14667
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014668 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014669 ret_status = hdd_driver_init();
14670 wlan_hdd_inited = ret_status ? 0 : 1;
14671 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014672 }
14673
14674 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070014675
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014676 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070014677
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014678 ret_status = hdd_driver_init();
14679 wlan_hdd_inited = ret_status ? 0 : 1;
14680 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014681}
14682
Jeff Johnson295189b2012-06-20 16:38:30 -070014683/**---------------------------------------------------------------------------
14684
Jeff Johnson76052702013-04-16 13:55:05 -070014685 \brief fwpath_changed_handler() - Handler Function
14686
14687 Handle changes to the fwpath parameter
14688
14689 \return - 0 for success, non zero for failure
14690
14691 --------------------------------------------------------------------------*/
14692static int fwpath_changed_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014693 const struct kernel_param *kp)
Jeff Johnson76052702013-04-16 13:55:05 -070014694{
14695 int ret;
14696
14697 ret = param_set_copystring(kmessage, kp);
14698 if (0 == ret)
14699 ret = kickstart_driver();
14700 return ret;
14701}
14702
14703/**---------------------------------------------------------------------------
14704
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014705 \brief con_mode_handler() -
14706
14707 Handler function for module param con_mode when it is changed by userspace
14708 Dynamically linked - do nothing
14709 Statically linked - exit and init driver, as in rmmod and insmod
14710
Jeff Johnson76052702013-04-16 13:55:05 -070014711 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014712
Jeff Johnson76052702013-04-16 13:55:05 -070014713 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014714
14715 --------------------------------------------------------------------------*/
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014716static int con_mode_handler(const char *kmessage,
14717 const struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014718{
Jeff Johnson76052702013-04-16 13:55:05 -070014719 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014720
Jeff Johnson76052702013-04-16 13:55:05 -070014721 ret = param_set_int(kmessage, kp);
14722 if (0 == ret)
14723 ret = kickstart_driver();
14724 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014725}
14726#endif /* #ifdef MODULE */
14727
14728/**---------------------------------------------------------------------------
14729
Jeff Johnson295189b2012-06-20 16:38:30 -070014730 \brief hdd_get_conparam() -
14731
14732 This is the driver exit point (invoked when module is unloaded using rmmod)
14733
14734 \param - None
14735
14736 \return - tVOS_CON_MODE
14737
14738 --------------------------------------------------------------------------*/
14739tVOS_CON_MODE hdd_get_conparam ( void )
14740{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014741#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070014742 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014743#else
14744 return (tVOS_CON_MODE)curr_con_mode;
14745#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014746}
14747void hdd_set_conparam ( v_UINT_t newParam )
14748{
14749 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014750#ifndef MODULE
14751 curr_con_mode = con_mode;
14752#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014753}
14754/**---------------------------------------------------------------------------
14755
14756 \brief hdd_softap_sta_deauth() - function
14757
14758 This to take counter measure to handle deauth req from HDD
14759
14760 \param - pAdapter - Pointer to the HDD
14761
14762 \param - enable - boolean value
14763
14764 \return - None
14765
14766 --------------------------------------------------------------------------*/
14767
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014768VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
14769 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070014770{
Jeff Johnson295189b2012-06-20 16:38:30 -070014771 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014772 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014773 struct hdd_cache_sta_info *cache_sta_info;
14774 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014775
14776 ENTER();
14777
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014778 hddLog(LOG1, "hdd_softap_sta_deauth:(%pK, false)",
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070014779 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014780
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014781 if (!pSapCtx) {
14782 hddLog(LOGE, "sap context is NULL");
14783 return vosStatus;
14784 }
14785
14786 cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
14787 pDelStaParams->peerMacAddr);
14788 if (cache_sta_info) {
14789 cache_sta_info->reason_code = pDelStaParams->reason_code;
14790 cache_sta_info->rx_rate =
14791 wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
14792 WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
14793 &cache_sta_info->rssi);
14794 }
14795
Jeff Johnson295189b2012-06-20 16:38:30 -070014796 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014797 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014798 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070014799
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014800 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070014801
14802 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014803 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070014804}
14805
14806/**---------------------------------------------------------------------------
14807
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014808 \brief hdd_del_all_sta() - function
14809
14810 This function removes all the stations associated on stopping AP/P2P GO.
14811
14812 \param - pAdapter - Pointer to the HDD
14813
14814 \return - None
14815
14816 --------------------------------------------------------------------------*/
14817
14818int hdd_del_all_sta(hdd_adapter_t *pAdapter)
14819{
14820 v_U16_t i;
14821 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014822 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14823 ptSapContext pSapCtx = NULL;
14824 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14825 if(pSapCtx == NULL){
14826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14827 FL("psapCtx is NULL"));
14828 return 1;
14829 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014830 ENTER();
14831
14832 hddLog(VOS_TRACE_LEVEL_INFO,
14833 "%s: Delete all STAs associated.",__func__);
14834 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
14835 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
14836 )
14837 {
14838 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
14839 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014840 if ((pSapCtx->aStaInfo[i].isUsed) &&
14841 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014842 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014843 struct tagCsrDelStaParams delStaParams;
14844
14845 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014846 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014847 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
14848 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014849 &delStaParams);
14850 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014851 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014852 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014853 }
14854 }
14855 }
14856
14857 EXIT();
14858 return 0;
14859}
14860
14861/**---------------------------------------------------------------------------
14862
Jeff Johnson295189b2012-06-20 16:38:30 -070014863 \brief hdd_softap_sta_disassoc() - function
14864
14865 This to take counter measure to handle deauth req from HDD
14866
14867 \param - pAdapter - Pointer to the HDD
14868
14869 \param - enable - boolean value
14870
14871 \return - None
14872
14873 --------------------------------------------------------------------------*/
14874
14875void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
14876{
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014877 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14878 struct hdd_cache_sta_info *cache_sta_info;
14879 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014880
14881 ENTER();
14882
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014883 hddLog( LOGE, "hdd_softap_sta_disassoc:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014884
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014885 if (!pSapCtx) {
14886 hddLog(LOGE, "sap context is NULL");
14887 return ;
14888 }
14889
Jeff Johnson295189b2012-06-20 16:38:30 -070014890 //Ignore request to disassoc bcmc station
14891 if( pDestMacAddress[0] & 0x1 )
14892 return;
14893
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014894 cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
14895 pDestMacAddress);
14896 if (cache_sta_info) {
14897 cache_sta_info->reason_code = eSIR_MAC_DEAUTH_LEAVING_BSS_REASON;
14898 cache_sta_info->rx_rate =
14899 wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
14900 WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
14901 &cache_sta_info->rssi);
14902 }
14903
Jeff Johnson295189b2012-06-20 16:38:30 -070014904 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
14905}
14906
14907void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
14908{
14909 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14910
14911 ENTER();
14912
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014913 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014914
14915 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
14916}
14917
Jeff Johnson295189b2012-06-20 16:38:30 -070014918/**---------------------------------------------------------------------------
14919 *
14920 * \brief hdd_get__concurrency_mode() -
14921 *
14922 *
14923 * \param - None
14924 *
14925 * \return - CONCURRENCY MODE
14926 *
14927 * --------------------------------------------------------------------------*/
14928tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
14929{
14930 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
14931 hdd_context_t *pHddCtx;
14932
14933 if (NULL != pVosContext)
14934 {
14935 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
14936 if (NULL != pHddCtx)
14937 {
14938 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
14939 }
14940 }
14941
14942 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014943 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014944 return VOS_STA;
14945}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053014946v_BOOL_t
14947wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
14948{
14949 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014950
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053014951 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
14952 if (pAdapter == NULL)
14953 {
14954 hddLog(VOS_TRACE_LEVEL_INFO,
14955 FL("GO doesn't exist"));
14956 return TRUE;
14957 }
14958 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
14959 {
14960 hddLog(VOS_TRACE_LEVEL_INFO,
14961 FL("GO started"));
14962 return TRUE;
14963 }
14964 else
14965 /* wait till GO changes its interface to p2p device */
14966 hddLog(VOS_TRACE_LEVEL_INFO,
14967 FL("Del_bss called, avoid apps suspend"));
14968 return FALSE;
14969
14970}
Jeff Johnson295189b2012-06-20 16:38:30 -070014971/* Decide whether to allow/not the apps power collapse.
14972 * Allow apps power collapse if we are in connected state.
14973 * if not, allow only if we are in IMPS */
14974v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
14975{
14976 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080014977 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080014978 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070014979 hdd_config_t *pConfig = pHddCtx->cfg_ini;
14980 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14981 hdd_adapter_t *pAdapter = NULL;
14982 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080014983 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014984
Jeff Johnson295189b2012-06-20 16:38:30 -070014985 if (VOS_STA_SAP_MODE == hdd_get_conparam())
14986 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014987
Yathish9f22e662012-12-10 14:21:35 -080014988 concurrent_state = hdd_get_concurrency_mode();
14989
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053014990 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
14991 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
14992 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080014993#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053014994
Yathish9f22e662012-12-10 14:21:35 -080014995 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053014996 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080014997 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
14998 return TRUE;
14999#endif
15000
Jeff Johnson295189b2012-06-20 16:38:30 -070015001 /*loop through all adapters. TBD fix for Concurrency */
15002 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15003 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15004 {
15005 pAdapter = pAdapterNode->pAdapter;
15006 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
15007 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15008 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080015009 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053015010 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053015011 && pmcState != STOPPED && pmcState != STANDBY &&
15012 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080015013 (eANI_BOOLEAN_TRUE == scanRspPending) ||
15014 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070015015 {
Mukul Sharma4be88422015-03-09 20:29:07 +053015016 if(pmcState == FULL_POWER &&
15017 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
15018 {
15019 /*
15020 * When SCO indication comes from Coex module , host will
15021 * enter in to full power mode, but this should not prevent
15022 * apps processor power collapse.
15023 */
15024 hddLog(LOG1,
15025 FL("Allow apps power collapse"
15026 "even when sco indication is set"));
15027 return TRUE;
15028 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080015029 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Deepthi Gowri03a979f2016-11-03 15:20:19 +053015030 "pmcState = %d scanRspPending = %d "
15031 "inMiddleOfRoaming = %d connected = %d",
15032 __func__, pmcState, scanRspPending,
15033 inMiddleOfRoaming, hdd_connIsConnected(
15034 WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )));
15035 wlan_hdd_get_tdls_stats(pAdapter);
15036 return FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015037 }
15038 }
15039 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15040 pAdapterNode = pNext;
15041 }
15042 return TRUE;
15043}
15044
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080015045/* Decides whether to send suspend notification to Riva
15046 * if any adapter is in BMPS; then it is required */
15047v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
15048{
15049 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
15050 hdd_config_t *pConfig = pHddCtx->cfg_ini;
15051
15052 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
15053 {
15054 return TRUE;
15055 }
15056 return FALSE;
15057}
15058
Jeff Johnson295189b2012-06-20 16:38:30 -070015059void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15060{
15061 switch(mode)
15062 {
Chilam Ngc4244af2013-04-01 15:37:32 -070015063 case VOS_STA_MODE:
15064 case VOS_P2P_CLIENT_MODE:
15065 case VOS_P2P_GO_MODE:
15066 case VOS_STA_SAP_MODE:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015067 case VOS_MONITOR_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070015068 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053015069 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070015070 break;
15071 default:
15072 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015073 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015074 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
15075 "Number of open sessions for mode %d = %d"),
15076 pHddCtx->concurrency_mode, mode,
15077 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070015078}
15079
15080
15081void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15082{
15083 switch(mode)
15084 {
Chilam Ngc4244af2013-04-01 15:37:32 -070015085 case VOS_STA_MODE:
15086 case VOS_P2P_CLIENT_MODE:
15087 case VOS_P2P_GO_MODE:
15088 case VOS_STA_SAP_MODE:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015089 case VOS_MONITOR_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053015090 pHddCtx->no_of_open_sessions[mode]--;
15091 if (!(pHddCtx->no_of_open_sessions[mode]))
15092 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015093 break;
15094 default:
15095 break;
15096 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015097 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
15098 "Number of open sessions for mode %d = %d"),
15099 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
15100
15101}
15102/**---------------------------------------------------------------------------
15103 *
15104 * \brief wlan_hdd_incr_active_session()
15105 *
15106 * This function increments the number of active sessions
15107 * maintained per device mode
15108 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
15109 * Incase of SAP/P2P GO upon bss start it is incremented
15110 *
15111 * \param pHddCtx - HDD Context
15112 * \param mode - device mode
15113 *
15114 * \return - None
15115 *
15116 * --------------------------------------------------------------------------*/
15117void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15118{
15119 switch (mode) {
15120 case VOS_STA_MODE:
15121 case VOS_P2P_CLIENT_MODE:
15122 case VOS_P2P_GO_MODE:
15123 case VOS_STA_SAP_MODE:
15124 pHddCtx->no_of_active_sessions[mode]++;
15125 break;
15126 default:
15127 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
15128 break;
15129 }
15130 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
15131 mode,
15132 pHddCtx->no_of_active_sessions[mode]);
15133}
15134
15135/**---------------------------------------------------------------------------
15136 *
15137 * \brief wlan_hdd_decr_active_session()
15138 *
15139 * This function decrements the number of active sessions
15140 * maintained per device mode
15141 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
15142 * Incase of SAP/P2P GO upon bss stop it is decremented
15143 *
15144 * \param pHddCtx - HDD Context
15145 * \param mode - device mode
15146 *
15147 * \return - None
15148 *
15149 * --------------------------------------------------------------------------*/
15150void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15151{
Bhargav Shahd0715912015-10-01 18:17:37 +053015152
Agarwal Ashish51325b52014-06-16 16:50:49 +053015153 switch (mode) {
15154 case VOS_STA_MODE:
15155 case VOS_P2P_CLIENT_MODE:
15156 case VOS_P2P_GO_MODE:
15157 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053015158 if (pHddCtx->no_of_active_sessions[mode] > 0)
15159 pHddCtx->no_of_active_sessions[mode]--;
15160 else
15161 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
15162 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053015163 break;
15164 default:
15165 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
15166 break;
15167 }
15168 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
15169 mode,
15170 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070015171}
15172
Jeff Johnsone7245742012-09-05 17:12:55 -070015173/**---------------------------------------------------------------------------
15174 *
15175 * \brief wlan_hdd_restart_init
15176 *
15177 * This function initalizes restart timer/flag. An internal function.
15178 *
15179 * \param - pHddCtx
15180 *
15181 * \return - None
15182 *
15183 * --------------------------------------------------------------------------*/
15184
15185static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
15186{
15187 /* Initialize */
15188 pHddCtx->hdd_restart_retries = 0;
15189 atomic_set(&pHddCtx->isRestartInProgress, 0);
15190 vos_timer_init(&pHddCtx->hdd_restart_timer,
15191 VOS_TIMER_TYPE_SW,
15192 wlan_hdd_restart_timer_cb,
15193 pHddCtx);
15194}
15195/**---------------------------------------------------------------------------
15196 *
15197 * \brief wlan_hdd_restart_deinit
15198 *
15199 * This function cleans up the resources used. An internal function.
15200 *
15201 * \param - pHddCtx
15202 *
15203 * \return - None
15204 *
15205 * --------------------------------------------------------------------------*/
15206
15207static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
15208{
15209
15210 VOS_STATUS vos_status;
15211 /* Block any further calls */
15212 atomic_set(&pHddCtx->isRestartInProgress, 1);
15213 /* Cleanup */
15214 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
15215 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015216 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070015217 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
15218 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015219 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070015220
15221}
15222
15223/**---------------------------------------------------------------------------
15224 *
15225 * \brief wlan_hdd_framework_restart
15226 *
15227 * This function uses a cfg80211 API to start a framework initiated WLAN
15228 * driver module unload/load.
15229 *
15230 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
15231 *
15232 *
15233 * \param - pHddCtx
15234 *
15235 * \return - VOS_STATUS_SUCCESS: Success
15236 * VOS_STATUS_E_EMPTY: Adapter is Empty
15237 * VOS_STATUS_E_NOMEM: No memory
15238
15239 * --------------------------------------------------------------------------*/
15240
15241static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
15242{
15243 VOS_STATUS status = VOS_STATUS_SUCCESS;
15244 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015245 int len = (sizeof (struct ieee80211_mgmt));
15246 struct ieee80211_mgmt *mgmt = NULL;
15247
15248 /* Prepare the DEAUTH managment frame with reason code */
15249 mgmt = kzalloc(len, GFP_KERNEL);
15250 if(mgmt == NULL)
15251 {
15252 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15253 "%s: memory allocation failed (%d bytes)", __func__, len);
15254 return VOS_STATUS_E_NOMEM;
15255 }
15256 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070015257
15258 /* Iterate over all adapters/devices */
15259 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015260 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
15261 {
15262 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015263 FL("fail to get adapter: %pK %d"), pAdapterNode, status);
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015264 goto end;
15265 }
15266
Jeff Johnsone7245742012-09-05 17:12:55 -070015267 do
15268 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015269 if(pAdapterNode->pAdapter &&
15270 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070015271 {
15272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15273 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
15274 pAdapterNode->pAdapter->dev->name,
15275 pAdapterNode->pAdapter->device_mode,
15276 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015277 /*
15278 * CFG80211 event to restart the driver
15279 *
15280 * 'cfg80211_send_unprot_deauth' sends a
15281 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
15282 * of SME(Linux Kernel) state machine.
15283 *
15284 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
15285 * the driver.
15286 *
15287 */
Abhishek Singh00b71972016-01-07 10:51:04 +053015288
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053015289#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
15290 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
15291#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015292 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053015293#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070015294 }
15295 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15296 pAdapterNode = pNext;
15297 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
15298
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015299 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015300 /* Free the allocated management frame */
15301 kfree(mgmt);
15302
Jeff Johnsone7245742012-09-05 17:12:55 -070015303 /* Retry until we unload or reach max count */
15304 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
15305 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
15306
15307 return status;
15308
15309}
15310/**---------------------------------------------------------------------------
15311 *
15312 * \brief wlan_hdd_restart_timer_cb
15313 *
15314 * Restart timer callback. An internal function.
15315 *
15316 * \param - User data:
15317 *
15318 * \return - None
15319 *
15320 * --------------------------------------------------------------------------*/
15321
15322void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
15323{
15324 hdd_context_t *pHddCtx = usrDataForCallback;
15325 wlan_hdd_framework_restart(pHddCtx);
15326 return;
15327
15328}
15329
15330
15331/**---------------------------------------------------------------------------
15332 *
15333 * \brief wlan_hdd_restart_driver
15334 *
15335 * This function sends an event to supplicant to restart the WLAN driver.
15336 *
15337 * This function is called from vos_wlanRestart.
15338 *
15339 * \param - pHddCtx
15340 *
15341 * \return - VOS_STATUS_SUCCESS: Success
15342 * VOS_STATUS_E_EMPTY: Adapter is Empty
15343 * VOS_STATUS_E_ALREADY: Request already in progress
15344
15345 * --------------------------------------------------------------------------*/
15346VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
15347{
15348 VOS_STATUS status = VOS_STATUS_SUCCESS;
15349
15350 /* A tight check to make sure reentrancy */
15351 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
15352 {
Mihir Shetefd528652014-06-23 19:07:50 +053015353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070015354 "%s: WLAN restart is already in progress", __func__);
15355
15356 return VOS_STATUS_E_ALREADY;
15357 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070015358 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080015359#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053015360 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070015361#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070015362
Jeff Johnsone7245742012-09-05 17:12:55 -070015363 return status;
15364}
15365
Bhargav Shahd0715912015-10-01 18:17:37 +053015366/**
15367 * hdd_get_total_sessions() - provide total number of active sessions
15368 * @pHddCtx: Valid Global HDD context pointer
15369 *
15370 * This function iterates through pAdaptors and find the number of all active
15371 * sessions. This active sessions includes connected sta, p2p client and number
15372 * of client connected to sap/p2p go.
15373 *
15374 * Return: Total number of active sessions.
15375 */
15376v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx)
15377{
15378 v_U8_t active_session = 0;
15379 hdd_station_ctx_t *pHddStaCtx;
15380 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15381 hdd_adapter_t *pAdapter;
15382 VOS_STATUS status;
15383
15384 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
15385 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
15386 pAdapter = pAdapterNode->pAdapter;
15387 switch (pAdapter->device_mode) {
15388 case VOS_STA_MODE:
15389 case VOS_P2P_CLIENT_MODE:
15390 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15391 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15392 active_session += 1;
15393 break;
15394 case VOS_STA_SAP_MODE:
15395 case VOS_P2P_GO_MODE:
15396 active_session += hdd_softap_get_connected_sta(pAdapter);
15397 break;
15398 default:
15399 break;
15400 }
15401
15402 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
15403 pAdapterNode = pNext;
15404 }
15405
15406 return active_session;
15407}
15408
15409/**
15410 * hdd_set_delack_value() - Set delack value
15411 * @pHddCtx: Valid Global HDD context pointer
15412 * @next_rx_level: Value to set for delack
15413 *
15414 * This function compare present value and next value of delack. If the both
15415 * are diffrent then it sets next value .
15416 *
15417 * Return: void.
15418 */
15419void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
15420{
15421 if (pHddCtx->cur_rx_level != next_rx_level) {
15422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15423 "%s: TCP DELACK trigger level %d",
15424 __func__, next_rx_level);
15425 mutex_lock(&pHddCtx->cur_rx_level_lock);
15426 pHddCtx->cur_rx_level = next_rx_level;
15427 mutex_unlock(&pHddCtx->cur_rx_level_lock);
15428 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &next_rx_level,
15429 sizeof(next_rx_level));
15430 }
15431}
15432
15433/**
15434 * hdd_set_default_stop_delack_timer() - Start delack timer
15435 * @pHddCtx: Valid Global HDD context pointer
15436 *
15437 * This function stop delack timer and set delack value to default..
15438 *
15439 * Return: void.
15440 */
15441
15442void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
15443{
15444 if (VOS_TIMER_STATE_RUNNING !=
15445 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
15446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15447 "%s: Can not stop timer", __func__);
15448 return;
15449 }
15450
15451 vos_timer_stop(&pHddCtx->delack_timer);
15452 hdd_set_delack_value(pHddCtx, TP_IND_LOW);
15453}
15454
15455/**
15456 * hdd_start_delack_timer() - Start delack timer
15457 * @pHddCtx: Valid Global HDD context pointer
15458 *
15459 * This function starts the delack timer for tcpDelAckComputeInterval time
15460 * interval.The default timer value is 2 second.
15461 *
15462 * Return: void.
15463 */
15464void hdd_start_delack_timer(hdd_context_t *pHddCtx)
15465{
15466 if (VOS_TIMER_STATE_RUNNING ==
15467 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
15468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15469 "%s: Timer is already running", __func__);
15470 return;
15471 }
15472
15473 vos_timer_start(&pHddCtx->delack_timer,
15474 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
15475}
15476
15477/**
15478 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
15479 * @pHddCtx: Valid Global HDD context pointer
15480 *
15481 * This function updates the prev_rx_packets count from the corresponding
15482 * pAdapter states. This prev_rx_packets will diffed with the packet count
15483 * at the end of delack timer. That can give number of RX packet is spacific
15484 * time.
15485 *
15486 * Return: void.
15487 */
15488void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
15489{
15490 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15491 hdd_adapter_t *pAdapter;
15492 VOS_STATUS status;
15493
15494 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15495 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
15496 pAdapter = pAdapterNode->pAdapter;
15497 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
15498 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15499 pAdapterNode = pNext;
15500 }
15501}
15502
15503/**
15504 * hdd_manage_delack_timer() - start\stop delack timer
15505 * @pHddCtx: Valid Global HDD context pointer
15506 *
15507 * This function check the number of concerent session present, it starts the
15508 * delack timer if only one session is present.
15509 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
15510 *
15511 * Return: void.
15512 */
15513void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
15514{
15515 uint8_t sessions;
15516
15517 if (!pHddCtx->cfg_ini->enable_delack) {
15518 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15519 "%s: TCP DELACK is not enabled", __func__);
15520 return;
15521 }
15522
15523 /* Blindly stop timer of BTCOEX and TDLS Session is up */
15524 if (pHddCtx->mode != 0) {
15525 hdd_set_default_stop_delack_timer(pHddCtx);
15526 return;
15527 }
15528
15529 sessions = hdd_get_total_sessions(pHddCtx);
15530 if (sessions == 1) {
15531 hdd_update_prev_rx_packet_count(pHddCtx);
15532 hdd_start_delack_timer(pHddCtx);
15533 } else {
15534 hdd_set_default_stop_delack_timer(pHddCtx);
15535 }
15536}
15537
Mihir Shetee1093ba2014-01-21 20:13:32 +053015538/**---------------------------------------------------------------------------
15539 *
15540 * \brief wlan_hdd_init_channels
15541 *
15542 * This function is used to initialize the channel list in CSR
15543 *
15544 * This function is called from hdd_wlan_startup
15545 *
15546 * \param - pHddCtx: HDD context
15547 *
15548 * \return - VOS_STATUS_SUCCESS: Success
15549 * VOS_STATUS_E_FAULT: Failure reported by SME
15550
15551 * --------------------------------------------------------------------------*/
15552static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
15553{
15554 eHalStatus status;
15555
15556 status = sme_InitChannels(pHddCtx->hHal);
15557 if (HAL_STATUS_SUCCESS(status))
15558 {
15559 return VOS_STATUS_SUCCESS;
15560 }
15561 else
15562 {
15563 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
15564 __func__, status);
15565 return VOS_STATUS_E_FAULT;
15566 }
15567}
15568
Mihir Shete04206452014-11-20 17:50:58 +053015569#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053015570VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053015571{
15572 eHalStatus status;
15573
Agarwal Ashish6db9d532014-09-30 18:19:10 +053015574 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053015575 if (HAL_STATUS_SUCCESS(status))
15576 {
15577 return VOS_STATUS_SUCCESS;
15578 }
15579 else
15580 {
15581 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
15582 __func__, status);
15583 return VOS_STATUS_E_FAULT;
15584 }
15585}
Mihir Shete04206452014-11-20 17:50:58 +053015586#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070015587/*
15588 * API to find if there is any STA or P2P-Client is connected
15589 */
15590VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
15591{
15592 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
15593}
Jeff Johnsone7245742012-09-05 17:12:55 -070015594
Mihir Shetee2ae82a2015-03-16 14:08:49 +053015595
15596/*
15597 * API to find if the firmware will send logs using DXE channel
15598 */
15599v_U8_t hdd_is_fw_logging_enabled(void)
15600{
15601 hdd_context_t *pHddCtx;
15602
15603 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
15604 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
15605
Sachin Ahuja084313e2015-05-21 17:57:10 +053015606 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053015607}
15608
Agarwal Ashish57e84372014-12-05 18:26:53 +053015609/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053015610 * API to find if the firmware will send trace logs using DXE channel
15611 */
15612v_U8_t hdd_is_fw_ev_logging_enabled(void)
15613{
15614 hdd_context_t *pHddCtx;
15615
15616 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
15617 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
15618
15619 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
15620}
15621/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053015622 * API to find if there is any session connected
15623 */
15624VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
15625{
15626 return sme_is_any_session_connected(pHddCtx->hHal);
15627}
15628
15629
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015630int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
15631{
15632 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15633 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053015634 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053015635 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015636
15637 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053015638 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015639 if (pScanInfo->mScanPending)
15640 {
c_hpothua3d45d52015-01-05 14:11:17 +053015641 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
15642 eCSR_SCAN_ABORT_DEFAULT);
15643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15644 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015645
c_hpothua3d45d52015-01-05 14:11:17 +053015646 /* If there is active scan command lets wait for the completion else
15647 * there is no need to wait as scan command might be in the SME pending
15648 * command list.
15649 */
15650 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
15651 {
Mukul Sharmab392b642017-08-17 17:45:29 +053015652 status = wait_for_completion_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015653 &pScanInfo->abortscan_event_var,
15654 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053015655 if (0 >= status)
15656 {
15657 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053015658 "%s: Timeout or Interrupt occurred while waiting for abort"
15659 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053015660 return -ETIMEDOUT;
15661 }
15662 }
15663 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
15664 {
15665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15666 FL("hdd_abort_mac_scan failed"));
15667 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015668 }
15669 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053015670 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015671}
15672
Abhishek Singh7d624e12015-11-30 14:29:27 +053015673/**
15674 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
15675 * user space
15676 * @frame_ind: Management frame data to be informed.
15677 *
15678 * This function is used to indicate management frame to
15679 * user space
15680 *
15681 * Return: None
15682 *
15683 */
15684void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
15685{
15686 hdd_context_t *hdd_ctx = NULL;
15687 hdd_adapter_t *adapter = NULL;
15688 v_CONTEXT_t vos_context = NULL;
15689
15690 /* Get the global VOSS context.*/
15691 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
15692 if (!vos_context) {
15693 hddLog(LOGE, FL("Global VOS context is Null"));
15694 return;
15695 }
15696 /* Get the HDD context.*/
15697 hdd_ctx =
15698 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
15699
15700 if (0 != wlan_hdd_validate_context(hdd_ctx))
15701 {
15702 return;
15703 }
15704 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
15705 frame_ind->sessionId);
15706
15707 if ((NULL != adapter) &&
15708 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
15709 __hdd_indicate_mgmt_frame(adapter,
15710 frame_ind->frameLen,
15711 frame_ind->frameBuf,
15712 frame_ind->frameType,
15713 frame_ind->rxChan,
15714 frame_ind->rxRssi);
15715 return;
15716
15717}
15718
c_hpothu225aa7c2014-10-22 17:45:13 +053015719VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
15720{
15721 hdd_adapter_t *pAdapter;
15722 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15723 VOS_STATUS vosStatus;
15724
15725 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15726 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
15727 {
15728 pAdapter = pAdapterNode->pAdapter;
15729 if (NULL != pAdapter)
15730 {
15731 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
15732 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
15733 WLAN_HDD_P2P_GO == pAdapter->device_mode)
15734 {
15735 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
15736 pAdapter->device_mode);
15737 if (VOS_STATUS_SUCCESS !=
15738 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
15739 {
15740 hddLog(LOGE, FL("failed to abort ROC"));
15741 return VOS_STATUS_E_FAILURE;
15742 }
15743 }
15744 }
15745 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15746 pAdapterNode = pNext;
15747 }
15748 return VOS_STATUS_SUCCESS;
15749}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053015750
Mihir Shete0be28772015-02-17 18:42:14 +053015751hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
15752{
15753 hdd_adapter_t *pAdapter;
15754 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15755 hdd_cfg80211_state_t *cfgState;
15756 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
15757 VOS_STATUS vosStatus;
15758
15759 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
15760 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
15761 {
15762 pAdapter = pAdapterNode->pAdapter;
15763 if (NULL != pAdapter)
15764 {
15765 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
15766 pRemainChanCtx = cfgState->remain_on_chan_ctx;
15767 if (pRemainChanCtx)
15768 break;
15769 }
15770 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
15771 pAdapterNode = pNext;
15772 }
15773 return pRemainChanCtx;
15774}
15775
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053015776/**
15777 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
15778 *
15779 * @pHddCtx: HDD context within host driver
15780 * @dfsScanMode: dfsScanMode passed from ioctl
15781 *
15782 */
15783
15784VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
15785 tANI_U8 dfsScanMode)
15786{
15787 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15788 hdd_adapter_t *pAdapter;
15789 VOS_STATUS vosStatus;
15790 hdd_station_ctx_t *pHddStaCtx;
15791 eHalStatus status = eHAL_STATUS_SUCCESS;
15792
15793 if(!pHddCtx)
15794 {
15795 hddLog(LOGE, FL("HDD context is Null"));
15796 return eHAL_STATUS_FAILURE;
15797 }
15798
15799 if (pHddCtx->scan_info.mScanPending)
15800 {
15801 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
15802 pHddCtx->scan_info.sessionId);
15803 hdd_abort_mac_scan(pHddCtx,
15804 pHddCtx->scan_info.sessionId,
15805 eCSR_SCAN_ABORT_DEFAULT);
15806 }
15807
15808 if (!dfsScanMode)
15809 {
15810 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
15811 while ((NULL != pAdapterNode) &&
15812 (VOS_STATUS_SUCCESS == vosStatus))
15813 {
15814 pAdapter = pAdapterNode->pAdapter;
15815
15816 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
15817 {
15818 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15819
15820 if(!pHddStaCtx)
15821 {
15822 hddLog(LOGE, FL("HDD STA context is Null"));
15823 return eHAL_STATUS_FAILURE;
15824 }
15825
15826 /* if STA is already connected on DFS channel,
15827 disconnect immediately*/
15828 if (hdd_connIsConnected(pHddStaCtx) &&
15829 (NV_CHANNEL_DFS ==
15830 vos_nv_getChannelEnabledState(
15831 pHddStaCtx->conn_info.operationChannel)))
15832 {
15833 status = sme_RoamDisconnect(pHddCtx->hHal,
15834 pAdapter->sessionId,
15835 eCSR_DISCONNECT_REASON_UNSPECIFIED);
15836 hddLog(LOG1, FL("Client connected on DFS channel %d,"
15837 "sme_RoamDisconnect returned with status: %d"
15838 "for sessionid: %d"), pHddStaCtx->conn_info.
15839 operationChannel, status, pAdapter->sessionId);
15840 }
15841 }
15842
15843 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
15844 &pNext);
15845 pAdapterNode = pNext;
15846 }
15847 }
15848
15849 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
15850 sme_UpdateDFSRoamMode(pHddCtx->hHal,
15851 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
15852
15853 status = sme_HandleDFSChanScan(pHddCtx->hHal);
15854 if (!HAL_STATUS_SUCCESS(status))
15855 {
15856 hddLog(LOGE,
15857 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
15858 return status;
15859 }
15860
15861 return status;
15862}
15863
Nirav Shah7e3c8132015-06-22 23:51:42 +053015864static int hdd_log2_ceil(unsigned value)
15865{
15866 /* need to switch to unsigned math so that negative values
15867 * will right-shift towards 0 instead of -1
15868 */
15869 unsigned tmp = value;
15870 int log2 = -1;
15871
15872 if (value == 0)
15873 return 0;
15874
15875 while (tmp) {
15876 log2++;
15877 tmp >>= 1;
15878 }
15879 if (1U << log2 != value)
15880 log2++;
15881
15882 return log2;
15883}
15884
15885/**
15886 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
15887 * @pAdapter: adapter handle
15888 *
15889 * Return: vos status
15890 */
15891VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
15892{
15893 int hash_elem, log2, i;
15894
15895 spin_lock_bh( &pAdapter->sta_hash_lock);
15896 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
15897 spin_unlock_bh( &pAdapter->sta_hash_lock);
15898 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15899 "%s: hash already attached for session id %d",
15900 __func__, pAdapter->sessionId);
15901 return VOS_STATUS_SUCCESS;
15902 }
15903 spin_unlock_bh( &pAdapter->sta_hash_lock);
15904
15905 hash_elem = WLAN_MAX_STA_COUNT;
15906 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
15907 log2 = hdd_log2_ceil(hash_elem);
15908 hash_elem = 1 << log2;
15909
15910 pAdapter->sta_id_hash.mask = hash_elem - 1;
15911 pAdapter->sta_id_hash.idx_bits = log2;
15912 pAdapter->sta_id_hash.bins =
15913 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
15914 if (!pAdapter->sta_id_hash.bins) {
15915 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15916 "%s: malloc failed for session %d",
15917 __func__, pAdapter->sessionId);
15918 return VOS_STATUS_E_NOMEM;
15919 }
15920
15921 for (i = 0; i < hash_elem; i++)
15922 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
15923
15924 spin_lock_bh( &pAdapter->sta_hash_lock);
15925 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
15926 spin_unlock_bh( &pAdapter->sta_hash_lock);
15927 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15928 "%s: Station ID Hash attached for session id %d",
15929 __func__, pAdapter->sessionId);
15930
15931 return VOS_STATUS_SUCCESS;
15932}
15933
15934/**
15935 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
15936 * @pAdapter: adapter handle
15937 *
15938 * Return: vos status
15939 */
15940VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
15941{
15942 int hash_elem, i;
15943 v_SIZE_t size;
15944
15945 spin_lock_bh( &pAdapter->sta_hash_lock);
15946 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
15947 spin_unlock_bh( &pAdapter->sta_hash_lock);
15948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15949 "%s: hash not initialized for session id %d",
15950 __func__, pAdapter->sessionId);
15951 return VOS_STATUS_SUCCESS;
15952 }
15953
15954 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
15955 spin_unlock_bh( &pAdapter->sta_hash_lock);
15956
15957 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
15958
15959 /* free all station info*/
15960 for (i = 0; i < hash_elem; i++) {
15961 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
15962 if (size != 0) {
15963 VOS_STATUS status;
15964 hdd_staid_hash_node_t *sta_info_node = NULL;
15965 hdd_staid_hash_node_t *next_node = NULL;
15966 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
15967 (hdd_list_node_t**) &sta_info_node );
15968
15969 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
15970 {
15971 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
15972 &sta_info_node->node);
15973 vos_mem_free(sta_info_node);
15974
15975 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
15976 (hdd_list_node_t*)sta_info_node,
15977 (hdd_list_node_t**)&next_node);
15978 sta_info_node = next_node;
15979 }
15980 }
15981 }
15982
15983 vos_mem_free(pAdapter->sta_id_hash.bins);
15984 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15985 "%s: Station ID Hash detached for session id %d",
15986 __func__, pAdapter->sessionId);
15987 return VOS_STATUS_SUCCESS;
15988}
15989
15990/**
15991 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
15992 * @pAdapter: adapter handle
15993 * @mac_addr_in: input mac address
15994 *
15995 * Return: index derived from mac address
15996 */
15997int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
15998 v_MACADDR_t *mac_addr_in)
15999{
16000 uint16 index;
16001 struct hdd_align_mac_addr_t * mac_addr =
16002 (struct hdd_align_mac_addr_t *)mac_addr_in;
16003
16004 index = mac_addr->bytes_ab ^
16005 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
16006 index ^= index >> pAdapter->sta_id_hash.idx_bits;
16007 index &= pAdapter->sta_id_hash.mask;
16008 return index;
16009}
16010
16011/**
16012 * hdd_sta_id_hash_add_entry() - add entry in hash
16013 * @pAdapter: adapter handle
16014 * @sta_id: station id
16015 * @mac_addr: mac address
16016 *
16017 * Return: vos status
16018 */
16019VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
16020 v_U8_t sta_id, v_MACADDR_t *mac_addr)
16021{
16022 uint16 index;
16023 hdd_staid_hash_node_t *sta_info_node = NULL;
16024
Nirav Shah7e3c8132015-06-22 23:51:42 +053016025 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
16026 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
16027 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053016028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16029 "%s: malloc failed", __func__);
16030 return VOS_STATUS_E_NOMEM;
16031 }
16032
16033 sta_info_node->sta_id = sta_id;
16034 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
16035
Nirav Shah303ed5c2015-08-24 10:29:25 +053016036 spin_lock_bh( &pAdapter->sta_hash_lock);
16037 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16038 spin_unlock_bh( &pAdapter->sta_hash_lock);
16039 vos_mem_free(sta_info_node);
16040 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16041 "%s: hash is not initialized for session id %d",
16042 __func__, pAdapter->sessionId);
16043 return VOS_STATUS_E_FAILURE;
16044 }
16045
Nirav Shah7e3c8132015-06-22 23:51:42 +053016046 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
16047 (hdd_list_node_t*) sta_info_node );
16048 spin_unlock_bh( &pAdapter->sta_hash_lock);
16049 return VOS_STATUS_SUCCESS;
16050}
16051
16052/**
16053 * hdd_sta_id_hash_remove_entry() - remove entry from hash
16054 * @pAdapter: adapter handle
16055 * @sta_id: station id
16056 * @mac_addr: mac address
16057 *
16058 * Return: vos status
16059 */
16060VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
16061 v_U8_t sta_id, v_MACADDR_t *mac_addr)
16062{
16063 uint16 index;
16064 VOS_STATUS status;
16065 hdd_staid_hash_node_t *sta_info_node = NULL;
16066 hdd_staid_hash_node_t *next_node = NULL;
16067
16068 spin_lock_bh( &pAdapter->sta_hash_lock);
16069 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16070 spin_unlock_bh( &pAdapter->sta_hash_lock);
16071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16072 "%s: hash is not initialized for session id %d",
16073 __func__, pAdapter->sessionId);
16074 return VOS_STATUS_E_FAILURE;
16075 }
16076
16077 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
16078 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
16079 (hdd_list_node_t**) &sta_info_node );
16080
16081 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16082 {
16083 if (sta_info_node->sta_id == sta_id) {
16084 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
16085 &sta_info_node->node);
16086 vos_mem_free(sta_info_node);
16087 break;
16088 }
16089 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
16090 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
16091 sta_info_node = next_node;
16092 }
16093 spin_unlock_bh( &pAdapter->sta_hash_lock);
16094 return status;
16095}
16096
16097/**
16098 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
16099 * @pAdapter: adapter handle
16100 * @mac_addr_in: mac address
16101 *
16102 * Return: station id
16103 */
16104int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
16105 v_MACADDR_t *mac_addr_in)
16106{
16107 uint8 is_found = 0;
16108 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
16109 uint16 index;
16110 VOS_STATUS status;
16111 hdd_staid_hash_node_t *sta_info_node = NULL;
16112 hdd_staid_hash_node_t *next_node = NULL;
16113
16114 spin_lock_bh( &pAdapter->sta_hash_lock);
16115 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16116 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053016117 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053016118 FL("hash is not initialized for session id %d"),
16119 pAdapter->sessionId);
16120 return HDD_WLAN_INVALID_STA_ID;
16121 }
16122
16123 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
16124 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
16125 (hdd_list_node_t**) &sta_info_node );
16126
16127 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16128 {
16129 if (vos_mem_compare(&sta_info_node->mac_addr,
16130 mac_addr_in, sizeof(v_MACADDR_t))) {
16131 is_found = 1;
16132 sta_id = sta_info_node->sta_id;
16133 break;
16134 }
16135 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
16136 (hdd_list_node_t*)sta_info_node,
16137 (hdd_list_node_t**)&next_node);
16138 sta_info_node = next_node;
16139 }
16140 spin_unlock_bh( &pAdapter->sta_hash_lock);
16141 return sta_id;
16142}
16143
c_manjeecfd1efb2015-09-25 19:32:34 +053016144/*FW memory dump feature*/
16145/**
16146 * This structure hold information about the /proc file
16147 *
16148 */
16149static struct proc_dir_entry *proc_file, *proc_dir;
16150
16151/**
16152 * memdump_read() - perform read operation in memory dump proc file
16153 *
16154 * @file - handle for the proc file.
16155 * @buf - pointer to user space buffer.
16156 * @count - number of bytes to be read.
16157 * @pos - offset in the from buffer.
16158 *
16159 * This function performs read operation for the memory dump proc file.
16160 *
16161 * Return: number of bytes read on success, error code otherwise.
16162 */
16163static ssize_t memdump_read(struct file *file, char __user *buf,
16164 size_t count, loff_t *pos)
16165{
16166 int status;
16167 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
16168 size_t ret_count;
c_manjeef1495642015-10-13 18:35:01 +053016169 loff_t bytes_left;
c_manjeecfd1efb2015-09-25 19:32:34 +053016170 ENTER();
16171
16172 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
16173 status = wlan_hdd_validate_context(hdd_ctx);
16174 if (0 != status) {
16175 return -EINVAL;
16176 }
16177
16178 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
16179 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
16180 return -EINVAL;
16181 }
16182
16183 /* run fs_read_handler in an atomic context*/
16184 vos_ssr_protect(__func__);
c_manjeef1495642015-10-13 18:35:01 +053016185 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left);
16186 if(bytes_left == 0)
c_manjeecfd1efb2015-09-25 19:32:34 +053016187 {
16188 /*Free the fwr mem dump buffer */
16189 wlan_free_fwr_mem_dump_buffer();
16190 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeef1495642015-10-13 18:35:01 +053016191 ret_count=0;
c_manjeecfd1efb2015-09-25 19:32:34 +053016192 }
16193 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
16194 vos_ssr_unprotect(__func__);
16195 EXIT();
16196 return ret_count;
16197}
16198
16199/**
16200 * struct memdump_fops - file operations for memory dump feature
16201 * @read - read function for memory dump operation.
16202 *
16203 * This structure initialize the file operation handle for memory
16204 * dump feature
16205 */
16206static const struct file_operations memdump_fops = {
16207 read: memdump_read
16208};
16209
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016210struct fw_mem_dump_priv {
16211 uint32_t status;
16212};
16213
c_manjeecfd1efb2015-09-25 19:32:34 +053016214/*
16215* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
16216* To be passed by HDD to WDA and called upon receiving of response
16217* from firmware
16218* @fwMemDumpReqContext : memory dump request context
16219* @dump_rsp : dump response from HAL
16220* Returns none
16221*/
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016222void wlan_hdd_fw_mem_dump_cb(void *context,
c_manjeecfd1efb2015-09-25 19:32:34 +053016223 tAniFwrDumpRsp *dump_rsp)
16224{
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016225 struct hdd_request *request;
16226 struct fw_mem_dump_priv *priv;
c_manjeecfd1efb2015-09-25 19:32:34 +053016227
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016228 request = hdd_request_get(context);
16229 if (!request) {
16230 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
16231 return;
16232 }
c_manjeecfd1efb2015-09-25 19:32:34 +053016233
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016234 ENTER();
16235
16236 priv = hdd_request_priv(request);
16237 priv->status = dump_rsp->dump_status;
16238
16239 /* report the status to requesting function and free mem.*/
16240 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
16241 hddLog(LOGE, FL("fw dump request declined by fwr"));
16242 //set the request completion variable
16243 hdd_request_complete(request);
16244 //Free the allocated fwr dump
16245 wlan_free_fwr_mem_dump_buffer();
16246 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
16247 } else {
16248 hddLog(LOG1, FL("fw dump request accepted by fwr"));
16249 /* register the HDD callback which will be called by SVC */
16250 wlan_set_svc_fw_mem_dump_req_cb(
16251 (void*)wlan_hdd_fw_mem_dump_req_cb,
16252 context);
16253 }
16254
16255 hdd_request_put(request);
16256
16257 EXIT();
c_manjeecfd1efb2015-09-25 19:32:34 +053016258}
16259
16260/**
16261 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
16262 *
16263 * This function removes file/dir under proc file system that was
16264 * processing firmware memory dump
16265 *
16266 * Return: None
16267 */
16268static void memdump_procfs_remove(void)
16269{
16270 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
16271 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
16272 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
16273 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
16274 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
16275}
16276
16277/**
16278 * memdump_procfs_init() - Initialize procfs for memory dump
16279 *
16280 * @vos_ctx - Global vos context.
16281 *
16282 * This function create file under proc file system to be used later for
16283 * processing firmware memory dump
16284 *
16285 * Return: 0 on success, error code otherwise.
16286 */
16287static int memdump_procfs_init(void *vos_ctx)
16288{
16289 hdd_context_t *hdd_ctx;
16290
16291 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16292 if (!hdd_ctx) {
16293 hddLog(LOGE , FL("Invalid HDD context"));
16294 return -EINVAL;
16295 }
16296
16297 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
16298 if (proc_dir == NULL) {
16299 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
16300 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
16301 PROCFS_MEMDUMP_DIR);
16302 return -ENOMEM;
16303 }
16304
16305 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
16306 S_IRUSR | S_IWUSR, proc_dir,
16307 &memdump_fops, hdd_ctx);
16308 if (proc_file == NULL) {
16309 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
16310 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
16311 PROCFS_MEMDUMP_NAME);
16312 return -ENOMEM;
16313 }
16314
16315 hddLog(LOG1 , FL("/proc/%s/%s created"),
16316 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
16317
16318 return 0;
16319}
16320
16321/**
16322 * memdump_init() - Initialization function for memory dump feature
16323 *
16324 * This function creates proc file for memdump feature and registers
16325 * HDD callback function with SME.
16326 *
16327 * Return - 0 on success, error otherwise
16328 */
16329int memdump_init(void)
16330{
16331 hdd_context_t *hdd_ctx;
16332 void *vos_ctx;
16333 int status = 0;
16334
16335 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
16336 if (!vos_ctx) {
16337 hddLog(LOGE, FL("Invalid VOS context"));
16338 return -EINVAL;
16339 }
16340
16341 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16342 if (!hdd_ctx) {
16343 hddLog(LOGE , FL("Invalid HDD context"));
16344 return -EINVAL;
16345 }
16346
16347 status = memdump_procfs_init(vos_ctx);
16348 if (status) {
16349 hddLog(LOGE , FL("Failed to create proc file"));
16350 return status;
16351 }
16352
16353 return 0;
16354}
16355
16356/**
16357 * memdump_deinit() - De initialize memdump feature
16358 *
16359 * This function removes proc file created for memdump feature.
16360 *
16361 * Return: None
16362 */
16363int memdump_deinit(void)
16364{
16365 hdd_context_t *hdd_ctx;
16366 void *vos_ctx;
16367
16368 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
16369 if (!vos_ctx) {
16370 hddLog(LOGE, FL("Invalid VOS context"));
16371 return -EINVAL;
16372 }
16373
16374 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16375 if(!hdd_ctx) {
16376 hddLog(LOGE , FL("Invalid HDD context"));
16377 return -EINVAL;
16378 }
16379
16380 memdump_procfs_remove();
16381 return 0;
16382}
16383
16384/**
16385 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
16386 * Return: HAL status
16387 */
16388
16389int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
16390{
16391 tAniFwrDumpReq fw_mem_dump_req={0};
16392 eHalStatus status = eHAL_STATUS_FAILURE;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016393 int ret=0, dump_status;
16394 void *cookie;
16395 struct hdd_request *request;
16396 struct fw_mem_dump_priv *priv;
16397 static const struct hdd_request_params params = {
16398 .priv_size = sizeof(*priv),
16399 .timeout_ms = FW_MEM_DUMP_TIMEOUT_MS,
16400 };
16401
c_manjeecfd1efb2015-09-25 19:32:34 +053016402 ENTER();
c_manjeef1495642015-10-13 18:35:01 +053016403
c_manjeecfd1efb2015-09-25 19:32:34 +053016404 /*Check whether a dump request is already going on
16405 *Caution this function will free previously held memory if new dump request is allowed*/
16406 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
16407 hddLog(LOGE, FL("Fw memdump already in progress"));
16408 return -EBUSY;
16409 }
16410 //Allocate memory for fw mem dump buffer
16411 ret = wlan_fwr_mem_dump_buffer_allocation();
16412 if(ret == -EFAULT)
16413 {
16414 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
16415 return ret;
16416 }
16417 if (0 != ret) {
16418 hddLog(LOGE, FL("Fwr mem Allocation failed"));
16419 return -ENOMEM;
16420 }
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016421
16422 request = hdd_request_alloc(&params);
16423 if (!request) {
16424 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
16425 return VOS_STATUS_E_NOMEM;
16426 }
16427 cookie = hdd_request_cookie(request);
c_manjeef1495642015-10-13 18:35:01 +053016428
c_manjeecfd1efb2015-09-25 19:32:34 +053016429 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016430 fw_mem_dump_req.fwMemDumpReqContext = cookie;
c_manjeecfd1efb2015-09-25 19:32:34 +053016431 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
16432 if(eHAL_STATUS_SUCCESS != status)
16433 {
16434 hddLog(VOS_TRACE_LEVEL_ERROR,
16435 "%s: fw_mem_dump_req failed ", __func__);
16436 wlan_free_fwr_mem_dump_buffer();
c_manjeef1495642015-10-13 18:35:01 +053016437 ret = -EFAULT;
16438 goto cleanup;
c_manjeecfd1efb2015-09-25 19:32:34 +053016439 }
c_manjeef1495642015-10-13 18:35:01 +053016440 /*wait for fw mem dump completion to send event to userspace*/
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016441 ret = hdd_request_wait_for_response(request);
16442 if (ret)
c_manjeef1495642015-10-13 18:35:01 +053016443 {
16444 hddLog(VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016445 "%s: fw_mem_dump_req timeout %d ", __func__,ret);
Abhishek Singh4eca9822015-12-09 18:07:34 +053016446 ret = -ETIMEDOUT;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016447 }else {
16448 priv = hdd_request_priv(request);
16449 dump_status = priv->status;
c_manjeef1495642015-10-13 18:35:01 +053016450 }
16451cleanup:
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016452 hdd_request_put(request);
16453 if(!ret && !dump_status)
Abhishek Singh4eca9822015-12-09 18:07:34 +053016454 ret = -EFAULT;
c_manjeecfd1efb2015-09-25 19:32:34 +053016455
c_manjeef1495642015-10-13 18:35:01 +053016456 EXIT();
Abhishek Singh4eca9822015-12-09 18:07:34 +053016457 return ret;
c_manjeef1495642015-10-13 18:35:01 +053016458}
16459
16460/**
16461 * HDD callback which will be called by SVC to indicate mem dump completion.
16462 */
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016463void wlan_hdd_fw_mem_dump_req_cb(void *context)
c_manjeef1495642015-10-13 18:35:01 +053016464{
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016465 struct hdd_request *request;
16466 struct fw_mem_dump_priv *priv;
16467
16468 request = hdd_request_get(context);
16469 if (!request) {
16470 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
16471 return;
16472 }
16473
16474 priv = hdd_request_priv(request);
16475 priv->status = true;
16476
16477 hdd_request_complete(request);
16478 hdd_request_put(request);
c_manjeecfd1efb2015-09-25 19:32:34 +053016479}
16480
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053016481void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
16482{
16483 if (NULL == pAdapter)
16484 {
16485 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
16486 return;
16487 }
16488 init_completion(&pAdapter->session_open_comp_var);
16489 init_completion(&pAdapter->session_close_comp_var);
16490 init_completion(&pAdapter->disconnect_comp_var);
16491 init_completion(&pAdapter->linkup_event_var);
16492 init_completion(&pAdapter->cancel_rem_on_chan_var);
16493 init_completion(&pAdapter->rem_on_chan_ready_event);
16494 init_completion(&pAdapter->pno_comp_var);
16495#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16496 init_completion(&pAdapter->offchannel_tx_event);
16497#endif
16498 init_completion(&pAdapter->tx_action_cnf_event);
16499#ifdef FEATURE_WLAN_TDLS
16500 init_completion(&pAdapter->tdls_add_station_comp);
16501 init_completion(&pAdapter->tdls_del_station_comp);
16502 init_completion(&pAdapter->tdls_mgmt_comp);
16503 init_completion(&pAdapter->tdls_link_establish_req_comp);
16504#endif
16505
16506#ifdef WLAN_FEATURE_RMC
16507 init_completion(&pAdapter->ibss_peer_info_comp);
16508#endif /* WLAN_FEATURE_RMC */
16509 init_completion(&pAdapter->ula_complete);
16510 init_completion(&pAdapter->change_country_code);
16511
16512#ifdef FEATURE_WLAN_BATCH_SCAN
16513 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
16514 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
16515#endif
Kapil Gupta2b44acb2016-12-30 16:49:51 +053016516 init_completion(&pAdapter->wlan_suspend_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053016517
16518 return;
16519}
c_manjeecfd1efb2015-09-25 19:32:34 +053016520
Anurag Chouhan0b29de02016-12-16 13:18:40 +053016521#ifdef MDNS_OFFLOAD
16522
16523/**
16524 * hdd_mdns_enable_offload_done() - mdns enable offload response api
16525 * @padapter: holds adapter
16526 * @status: response status
16527 *
16528 * Return - None
16529 */
16530void hdd_mdns_enable_offload_done(void *padapter, VOS_STATUS status)
16531{
16532 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16533
16534 ENTER();
16535
16536 if (NULL == adapter)
16537 {
16538 hddLog(VOS_TRACE_LEVEL_ERROR,
16539 "%s: adapter is NULL",__func__);
16540 return;
16541 }
16542
16543 adapter->mdns_status.mdns_enable_status = status;
16544 vos_event_set(&adapter->mdns_status.vos_event);
16545 return;
16546}
16547
16548/**
16549 * hdd_mdns_fqdn_offload_done() - mdns fqdn offload response api
16550 * @padapter: holds adapter
16551 * @status: responce status
16552 *
16553 * Return - None
16554 */
16555void hdd_mdns_fqdn_offload_done(void *padapter, VOS_STATUS status)
16556{
16557 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16558
16559 ENTER();
16560
16561 if (NULL == adapter)
16562 {
16563 hddLog(VOS_TRACE_LEVEL_ERROR,
16564 "%s: adapter is NULL",__func__);
16565 return;
16566 }
16567
16568 adapter->mdns_status.mdns_fqdn_status = status;
16569 return;
16570}
16571
16572/**
16573 * hdd_mdns_resp_offload_done() - mdns resp offload response api
16574 * @padapter: holds adapter
16575 * @status: responce status
16576 *
16577 * Return - None
16578 */
16579void hdd_mdns_resp_offload_done(void *padapter, VOS_STATUS status)
16580{
16581 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16582
16583 ENTER();
16584
16585 if (NULL == adapter)
16586 {
16587 hddLog(VOS_TRACE_LEVEL_ERROR,
16588 "%s: adapter is NULL",__func__);
16589 return;
16590 }
16591
16592 adapter->mdns_status.mdns_resp_status = status;
16593 return;
16594}
16595
16596/**
16597 * wlan_hdd_mdns_process_response_dname() - Process mDNS domain name
16598 * @response: Pointer to a struct hdd_mdns_resp_info
16599 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16600 *
16601 * This function will pack the whole domain name without compression. It will
16602 * add the leading len for each field and add zero length octet to terminate
16603 * the domain name.
16604 *
16605 * Return: Return boolean. TRUE for success, FALSE for fail.
16606 */
16607static bool
16608wlan_hdd_mdns_process_response_dname(struct hdd_mdns_resp_info *response,
16609 sir_mdns_resp_info resp_info)
16610{
16611 uint8_t num;
16612 uint16_t idx;
16613 uint8_t len = 0;
16614
16615 if ((response == NULL) || (response->data == NULL) ||
16616 (response->offset == NULL)) {
16617 hddLog(LOGE, FL("Either data or offset in response is NULL!"));
16618 return FALSE;
16619 }
16620
16621 if ((resp_info == NULL) ||
16622 (resp_info->resp_len >= MAX_MDNS_RESP_LEN)) {
16623 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16624 return FALSE;
16625 }
16626
16627 for (num = 0; num < response->num_entries; num++) {
16628 response->offset[num] =
16629 resp_info->resp_len + MDNS_HEADER_LEN;
16630 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16631 len = strlen((char *)&response->data[idx]);
16632 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
16633 hddLog(LOGE, FL("resp_len exceeds %d!"),
16634 MAX_MDNS_RESP_LEN);
16635 return FALSE;
16636 }
16637 resp_info->resp_data[resp_info->resp_len] = len;
16638 resp_info->resp_len++;
16639 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
16640 &response->data[idx], len);
16641 resp_info->resp_len += len;
16642 }
16643
16644 /* The domain name terminates with the zero length octet */
16645 if (num == response->num_entries) {
16646 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
16647 hddLog(LOGE, FL("resp_len exceeds %d!"),
16648 MAX_MDNS_RESP_LEN);
16649 return FALSE;
16650 }
16651 resp_info->resp_data[resp_info->resp_len] = 0;
16652 resp_info->resp_len++;
16653 }
16654
16655 return TRUE;
16656}
16657
16658/**
16659 * wlan_hdd_mdns_format_response_u16() - Form uint16_t response data
16660 * @value: The uint16_t value is formed to the struct tSirMDNSResponseInfo
16661 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16662 *
16663 * Return: None
16664 */
16665static void wlan_hdd_mdns_format_response_u16(uint16_t value,
16666 sir_mdns_resp_info resp_info)
16667{
16668 uint8_t val_u8;
16669
16670 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
16671 return;
16672 val_u8 = (value & 0xff00) >> 8;
16673 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16674 val_u8 = value & 0xff;
16675 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16676}
16677
16678/**
16679 * wlan_hdd_mdns_format_response_u32() - Form uint32_t response data
16680 * @value: The uint32_t value is formed to the struct tSirMDNSResponseInfo
16681 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16682 *
16683 * Return: None
16684 */
16685static void wlan_hdd_mdns_format_response_u32(uint32_t value,
16686 sir_mdns_resp_info resp_info)
16687{
16688 uint8_t val_u8;
16689
16690 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
16691 return;
16692 val_u8 = (value & 0xff000000) >> 24;
16693 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16694 val_u8 = (value & 0xff0000) >> 16;
16695 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16696 val_u8 = (value & 0xff00) >> 8;
16697 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16698 val_u8 = value & 0xff;
16699 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16700}
16701
16702/**
16703 * wlan_hdd_mdns_process_response_misc() - Process misc info in mDNS response
16704 * @resp_type: Response type for mDNS
16705 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16706 *
16707 * This function will pack the response type, class and TTL (Time To Live).
16708 *
16709 * Return: Return boolean. TRUE for success, FALSE for fail.
16710 */
16711static bool wlan_hdd_mdns_process_response_misc(uint16_t resp_type,
16712 sir_mdns_resp_info resp_info)
16713{
16714 uint16_t len;
16715
16716 if (resp_info == NULL) {
16717 hddLog(LOGE, FL("resp_info is NULL!"));
16718 return FALSE;
16719 }
16720
16721 len = resp_info->resp_len + (2 * sizeof(uint16_t) + sizeof(uint32_t));
16722 if (len >= MAX_MDNS_RESP_LEN) {
16723 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16724 return FALSE;
16725 }
16726
16727 /* Fill Type, Class, TTL */
16728 wlan_hdd_mdns_format_response_u16(resp_type, resp_info);
16729 wlan_hdd_mdns_format_response_u16(MDNS_CLASS, resp_info);
16730 wlan_hdd_mdns_format_response_u32(MDNS_TTL, resp_info);
16731
16732 return TRUE;
16733}
16734
16735/**
16736 * wlan_hdd_mdns_compress_data() - Compress the domain name in mDNS response
16737 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16738 * @response_dst: The response which domain name is compressed.
16739 * @response_src: The response which domain name is matched with response_dst.
16740 * Its offset is used for data compression.
16741 * @num_matched: The number of matched entries between response_dst and
16742 * response_src
16743 *
16744 * This function will form the different fields of domain name in response_dst
16745 * if any. Then use the offset of the matched domain name in response_src to
16746 * compress the matched domain name.
16747 *
16748 * Return: Return boolean. TRUE for success, FALSE for fail.
16749 */
16750static bool
16751wlan_hdd_mdns_compress_data(sir_mdns_resp_info resp_info,
16752 struct hdd_mdns_resp_info *response_dst,
16753 struct hdd_mdns_resp_info *response_src,
16754 uint8_t num_matched)
16755{
16756 uint8_t num, num_diff;
16757 uint16_t value, idx;
16758 uint8_t len = 0;
16759
16760 if ((response_src == NULL) || (response_dst == NULL) ||
16761 (resp_info == NULL)) {
16762 hddLog(LOGE, FL("response info is NULL!"));
16763 return FALSE;
16764 }
16765
16766 if (response_dst->num_entries < num_matched) {
16767 hddLog(LOGE, FL("num_entries is less than num_matched!"));
16768 return FALSE;
16769 }
16770
16771 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
16772 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16773 return FALSE;
16774 }
16775
16776 num_diff = response_dst->num_entries - num_matched;
16777 if ((num_diff > 0) && (response_dst->data == NULL)) {
16778 hddLog(LOGE, FL("response_dst->data is NULL!"));
16779 return FALSE;
16780 }
16781
16782 /*
16783 * Handle the unmatched string at the beginning
16784 * Store the length of octets and the octets
16785 */
16786 for (num = 0; num < num_diff; num++) {
16787 response_dst->offset[num] =
16788 resp_info->resp_len + MDNS_HEADER_LEN;
16789 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16790 len = strlen((char *)&response_dst->data[idx]);
16791 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
16792 hddLog(LOGE, FL("resp_len exceeds %d!"),
16793 MAX_MDNS_RESP_LEN);
16794 return FALSE;
16795 }
16796 resp_info->resp_data[resp_info->resp_len] = len;
16797 resp_info->resp_len++;
16798 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
16799 &response_dst->data[idx], len);
16800 resp_info->resp_len += len;
16801 }
16802 /*
16803 * Handle the matched string from the end
16804 * Just keep the offset and mask the leading two bit
16805 */
16806 if (response_src->num_entries >= num_matched) {
16807 num_diff = response_src->num_entries - num_matched;
16808 value = response_src->offset[num_diff];
16809 if (value > 0) {
16810 value |= 0xc000;
16811 if ((resp_info->resp_len + sizeof(uint16_t)) >=
16812 MAX_MDNS_RESP_LEN) {
16813 hddLog(LOGE, FL("resp_len exceeds %d!"),
16814 MAX_MDNS_RESP_LEN);
16815 return FALSE;
16816 }
16817 wlan_hdd_mdns_format_response_u16(value, resp_info);
16818 return TRUE;
16819 }
16820 }
16821 return FALSE;
16822}
16823
16824/**
16825 * wlan_hdd_mdns_reset_response() - Reset the response info
16826 * @response: The response which info is reset.
16827 *
16828 * Return: None
16829 */
16830static void wlan_hdd_mdns_reset_response(struct hdd_mdns_resp_info *response)
16831{
16832 if (response == NULL)
16833 return;
16834 response->num_entries = 0;
16835 response->data = NULL;
16836 response->offset = NULL;
16837}
16838
16839/**
16840 * wlan_hdd_mdns_init_response() - Initialize the response info
16841 * @response: The response which info is initiatized.
16842 * @resp_dname: The domain name string which might be tokenized.
16843 *
16844 * This function will allocate the memory for both response->data and
16845 * response->offset. Besides, it will also tokenize the domain name to some
16846 * entries and fill response->num_entries with the num of entries.
16847 *
16848 * Return: Return boolean. TRUE for success, FALSE for fail.
16849 */
16850static bool wlan_hdd_mdns_init_response(struct hdd_mdns_resp_info *response,
16851 uint8_t *resp_dname, char separator)
16852{
16853 uint16_t size;
16854
16855 if ((resp_dname == NULL) || (response == NULL)) {
16856 hddLog(LOGE, FL("resp_dname or response is NULL!"));
16857 return FALSE;
16858 }
16859
16860 size = MAX_NUM_FIELD_DOMAINNAME * MAX_LEN_DOMAINNAME_FIELD;
16861 response->data = vos_mem_malloc(size);
16862 if (response->data) {
16863 vos_mem_zero(response->data, size);
16864 if (VOS_STATUS_SUCCESS !=
16865 hdd_string_to_string_array((char *)resp_dname,
16866 response->data,
16867 separator,
16868 &response->num_entries,
16869 MAX_NUM_FIELD_DOMAINNAME,
16870 MAX_LEN_DOMAINNAME_FIELD)) {
16871 hddLog(LOGE, FL("hdd_string_to_string_array fail!"));
16872 goto err_init_resp;
16873 }
16874
16875 if ((response->num_entries > 0) &&
16876 (strlen((char *)&response->data[0]) > 0)) {
16877 size = sizeof(uint16_t) * response->num_entries;
16878 response->offset = vos_mem_malloc(size);
16879 if (response->offset) {
16880 vos_mem_zero(response->offset, size);
16881 return TRUE;
16882 }
16883 }
16884 }
16885
16886err_init_resp:
16887 if (response->data)
16888 vos_mem_free(response->data);
16889 wlan_hdd_mdns_reset_response(response);
16890 return FALSE;
16891}
16892
16893/**
16894 * wlan_hdd_mdns_find_entries_from_end() - Find the matched entries
16895 * @response1: The response info is used to be compared.
16896 * @response2: The response info is used to be compared.
16897 *
16898 * This function will find the matched entries from the end.
16899 *
16900 * Return: Return the number of the matched entries.
16901 */
16902static uint8_t
16903wlan_hdd_mdns_find_entries_from_end(struct hdd_mdns_resp_info *response1,
16904 struct hdd_mdns_resp_info *response2)
16905{
16906 uint8_t min, len1, i;
16907 uint16_t num1, num2;
16908 uint8_t num_matched = 0;
16909
16910 min = VOS_MIN(response1->num_entries, response2->num_entries);
16911
16912 for (i = 1; i <= min; i++) {
16913 num1 = (response1->num_entries - i);
16914 num1 *= MAX_LEN_DOMAINNAME_FIELD;
16915 num2 = (response2->num_entries - i);
16916 num2 *= MAX_LEN_DOMAINNAME_FIELD;
16917 len1 = strlen((char *)&response1->data[num1]);
16918
16919 if ((len1 == 0) ||
16920 (len1 != strlen((char *)&response2->data[num2])))
16921 break;
16922 if (memcmp(&response1->data[num1],
16923 &response2->data[num2], len1))
16924 break;
16925 else
16926 num_matched++;
16927 }
16928
16929 return num_matched;
16930}
16931
16932/**
16933 * wlan_hdd_mdns_find_max() - Find the maximum number of the matched entries
16934 * @matchedlist: Pointer to the array of struct hdd_mdns_resp_matched
16935 * @numlist: The number of the elements in the array matchedlist.
16936 *
16937 * Find the max number of the matched entries among the array matchedlist.
16938 *
16939 * Return: None
16940 */
16941static void wlan_hdd_mdns_find_max(struct hdd_mdns_resp_matched *matchedlist,
16942 uint8_t numlist)
16943{
16944 int j;
16945 struct hdd_mdns_resp_matched tmp;
16946
16947 /* At least two values are used for sorting */
16948 if ((numlist < 2) || (matchedlist == NULL)) {
16949 hddLog(LOGE, FL("At least two values are used for sorting!"));
16950 return;
16951 }
16952
16953 for (j = 0; j < numlist-1; j++) {
16954 if (matchedlist[j].num_matched >
16955 matchedlist[j+1].num_matched) {
16956 vos_mem_copy(&tmp, &matchedlist[j],
16957 sizeof(struct hdd_mdns_resp_matched));
16958 vos_mem_copy(&matchedlist[j], &matchedlist[j+1],
16959 sizeof(struct hdd_mdns_resp_matched));
16960 vos_mem_copy(&matchedlist[j+1], &tmp,
16961 sizeof(struct hdd_mdns_resp_matched));
16962 }
16963 }
16964}
16965
16966/**
16967 * wlan_hdd_mdns_pack_response_type_a() - Pack Type A response
16968 * @ini_config: Pointer to the struct hdd_config_t
16969 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
16970 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
16971 *
16972 * Type A response include QName, response type, class, TTL and Ipv4.
16973 *
16974 * Return: Return boolean. TRUE for success, FALSE for fail.
16975 */
16976static bool
16977wlan_hdd_mdns_pack_response_type_a(hdd_config_t *ini_config,
16978 sir_mdns_resp_info resp_info,
16979 struct hdd_mdns_resp_info *resptype_a)
16980{
16981 uint16_t value;
16982 uint32_t len;
16983
16984 ENTER();
16985 if ((ini_config == NULL) || (resp_info == NULL) ||
16986 (resptype_a == NULL)) {
16987 hddLog(LOGE, FL("ini_config or response info is NULL!"));
16988 return FALSE;
16989 }
16990
16991 /* No Type A response */
16992 if (strlen((char *)ini_config->mdns_resp_type_a) <= 0)
16993 return TRUE;
16994
16995 /* Wrong response is assigned, just ignore this response */
16996 if (!wlan_hdd_mdns_init_response(resptype_a,
16997 ini_config->mdns_resp_type_a, '.'))
16998 return TRUE;
16999
17000 /* Process response domain name */
17001 if (!wlan_hdd_mdns_process_response_dname(resptype_a, resp_info)) {
17002 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17003 MDNS_TYPE_A);
17004 return FALSE;
17005 }
17006
17007 /* Process response Type, Class, TTL */
17008 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_A, resp_info)) {
17009 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17010 MDNS_TYPE_A);
17011 return FALSE;
17012 }
17013
17014 /* Process response RDLength, RData */
17015 len = sizeof(uint16_t) + sizeof(uint32_t);
17016 len += resp_info->resp_len;
17017 if (len >= MAX_MDNS_RESP_LEN) {
17018 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17019 return FALSE;
17020 }
17021 value = sizeof(uint32_t);
17022 wlan_hdd_mdns_format_response_u16(value, resp_info);
17023 wlan_hdd_mdns_format_response_u32(ini_config->mdns_resp_type_a_ipv4,
17024 resp_info);
17025
17026 EXIT();
17027 return TRUE;
17028}
17029
17030/**
17031 * wlan_hdd_mdns_pack_response_type_txt() - Pack Type Txt response
17032 * @ini_config: Pointer to the struct hdd_config_t
17033 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17034 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type txt
17035 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17036 *
17037 * Type Txt response include QName, response type, class, TTL and text content.
17038 * Also, it will find the matched QName from resptype_A and compress the data.
17039 *
17040 * Return: Return boolean. TRUE for success, FALSE for fail.
17041 */
17042static bool
17043wlan_hdd_mdns_pack_response_type_txt(hdd_config_t *ini_config,
17044 sir_mdns_resp_info resp_info,
17045 struct hdd_mdns_resp_info *resptype_txt,
17046 struct hdd_mdns_resp_info *resptype_a)
17047{
17048 uint8_t num_matched;
17049 uint8_t num;
17050 uint16_t idx;
17051 uint16_t value = 0;
17052 uint32_t len;
17053 uint32_t total_len;
17054 bool status;
17055 struct hdd_mdns_resp_info resptype_content;
17056
17057 ENTER();
17058
17059 if ((ini_config == NULL) || (resp_info == NULL) ||
17060 (resptype_txt == NULL)) {
17061 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17062 return FALSE;
17063 }
17064
17065 /* No Type Txt response */
17066 if (strlen((char *)ini_config->mdns_resp_type_txt) <= 0)
17067 return TRUE;
17068
17069 /* Wrong response is assigned, just ignore this response */
17070 if (!wlan_hdd_mdns_init_response(resptype_txt,
17071 ini_config->mdns_resp_type_txt, '.'))
17072 return TRUE;
17073
17074 /*
17075 * For data compression
17076 * Check if any strings are matched with Type A response
17077 */
17078 if (resptype_a && (resptype_a->num_entries > 0)) {
17079 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_txt,
17080 resptype_a);
17081 if (num_matched > 0) {
17082 if (!wlan_hdd_mdns_compress_data(resp_info,
17083 resptype_txt, resptype_a, num_matched)) {
17084 hddLog(LOGE, FL("Fail to compress mDNS "
17085 "response (%d)!"), MDNS_TYPE_TXT);
17086 return FALSE;
17087 }
17088 } else {
17089 /*
17090 * num_matched is zero. Error!
17091 * At least ".local" is needed.
17092 */
17093 hddLog(LOGE, FL("No matched string! Fail to pack mDNS "
17094 "response (%d)!"), MDNS_TYPE_TXT);
17095 return FALSE;
17096 }
17097 } else {
17098 /* no TypeA response, so show the whole data */
17099 if (!wlan_hdd_mdns_process_response_dname(resptype_txt,
17100 resp_info)) {
17101 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17102 MDNS_TYPE_TXT);
17103 return FALSE;
17104 }
17105 }
17106
17107 /* Process response Type, Class, TTL */
17108 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_TXT, resp_info)) {
17109 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17110 MDNS_TYPE_TXT);
17111 return FALSE;
17112 }
17113
17114 /*
17115 * Process response RDLength, RData.
17116 * TypeTxt RData include len.
17117 */
17118 status = wlan_hdd_mdns_init_response(&resptype_content,
17119 ini_config->mdns_resp_type_txt_content,
17120 '/');
17121 if (status == FALSE) {
17122 hddLog(LOGE, FL("wlan_hdd_mdns_init_response FAIL"));
17123 return FALSE;
17124 }
17125
17126 for (num = 0; num < resptype_content.num_entries; num++) {
17127 idx = num * MAX_LEN_DOMAINNAME_FIELD;
17128 value += strlen((char *)&resptype_content.data[idx]);
17129 }
17130
17131 /* content len is uint16_t */
17132 total_len = sizeof(uint16_t);
17133 total_len += resp_info->resp_len + value +
17134 resptype_content.num_entries;
17135
17136 if (total_len >= MAX_MDNS_RESP_LEN) {
17137 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17138 return FALSE;
17139 }
17140 wlan_hdd_mdns_format_response_u16(value + resptype_content.num_entries,
17141 resp_info);
17142
17143 for (num = 0; num < resptype_content.num_entries; num++) {
17144 idx = num * MAX_LEN_DOMAINNAME_FIELD;
17145 len = strlen((char *)&resptype_content.data[idx]);
17146 resp_info->resp_data[resp_info->resp_len] = len;
17147 resp_info->resp_len++;
17148
17149 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
17150 &resptype_content.data[idx], len);
17151
17152 resp_info->resp_len += len;
17153 hddLog(LOG1, FL("index = %d, len = %d, str = %s"),
17154 num, len, &resptype_content.data[idx]);
17155 }
17156
17157 EXIT();
17158 return TRUE;
17159}
17160
17161/**
17162 * wlan_hdd_mdns_pack_response_type_ptr_dname() - Pack Type PTR domain name
17163 * @ini_config: Pointer to the struct hdd_config_t
17164 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17165 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17166 * domain name
17167 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17168 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17169 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17170 *
17171 * The Type Ptr response include Type PTR domain name in its data field.
17172 * Also, it will find the matched QName from the existing resptype_ptr,
17173 * resptype_txt, resptype_a and then compress the data.
17174 *
17175 * Return: Return boolean. TRUE for success, FALSE for fail.
17176 */
17177static bool
17178wlan_hdd_mdns_pack_response_type_ptr_dname(hdd_config_t *ini_config,
17179 sir_mdns_resp_info resp_info,
17180 struct hdd_mdns_resp_info *resptype_ptr_dn,
17181 struct hdd_mdns_resp_info *resptype_ptr,
17182 struct hdd_mdns_resp_info *resptype_txt,
17183 struct hdd_mdns_resp_info *resptype_a)
17184{
17185 uint8_t num_matched, numlist, size;
17186 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17187 struct hdd_mdns_resp_info *resp;
17188
17189 if ((ini_config == NULL) || (resp_info == NULL) ||
17190 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
17191 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17192 return FALSE;
17193 }
17194
17195 /* No Type Ptr domain name response */
17196 if (strlen((char *)ini_config->mdns_resp_type_ptr_dname) <= 0)
17197 return TRUE;
17198
17199 /* Wrong response is assigned, just ignore this response */
17200 if (!wlan_hdd_mdns_init_response(resptype_ptr_dn,
17201 ini_config->mdns_resp_type_ptr_dname, '.'))
17202 return TRUE;
17203
17204 /*
17205 * For data compression
17206 * Check if any strings are matched with previous
17207 * response.
17208 */
17209 numlist = 0;
17210 size = (MAX_MDNS_RESP_TYPE-1);
17211 size *= sizeof(struct hdd_mdns_resp_matched);
17212 vos_mem_zero(matchedlist, size);
17213 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr_dn,
17214 resptype_ptr);
17215 if (num_matched > 0) {
17216 matchedlist[numlist].num_matched = num_matched;
17217 matchedlist[numlist].type = MDNS_TYPE_PTR;
17218 numlist++;
17219 }
17220 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17221 num_matched = wlan_hdd_mdns_find_entries_from_end(
17222 resptype_ptr_dn, resptype_txt);
17223 if (num_matched > 0) {
17224 matchedlist[numlist].num_matched = num_matched;
17225 matchedlist[numlist].type = MDNS_TYPE_TXT;
17226 numlist++;
17227 }
17228 }
17229 if (resptype_a && (resptype_a->num_entries > 0)) {
17230 num_matched = wlan_hdd_mdns_find_entries_from_end(
17231 resptype_ptr_dn,resptype_a);
17232 if (num_matched > 0) {
17233 matchedlist[numlist].num_matched = num_matched;
17234 matchedlist[numlist].type = MDNS_TYPE_A;
17235 numlist++;
17236 }
17237 }
17238 if (numlist > 0) {
17239 if (numlist > 1)
17240 wlan_hdd_mdns_find_max(matchedlist, numlist);
17241 resp = NULL;
17242 switch (matchedlist[numlist-1].type) {
17243 case MDNS_TYPE_A:
17244 resp = resptype_a;
17245 break;
17246 case MDNS_TYPE_TXT:
17247 resp = resptype_txt;
17248 break;
17249 case MDNS_TYPE_PTR:
17250 resp = resptype_ptr;
17251 break;
17252 default:
17253 hddLog(LOGE, FL("Fail to compress mDNS response "
17254 "(%d)!"), MDNS_TYPE_PTR_DNAME);
17255 return FALSE;
17256 }
17257 num_matched = matchedlist[numlist-1].num_matched;
17258 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_ptr_dn,
17259 resp, num_matched)) {
17260 hddLog(LOGE, FL("Fail to compress mDNS response "
17261 "(%d)!"), MDNS_TYPE_PTR_DNAME);
17262 return FALSE;
17263 }
17264 } else {
17265 /* num = 0 -> no matched string */
17266 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr_dn,
17267 resp_info)) {
17268 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17269 MDNS_TYPE_PTR_DNAME);
17270 return FALSE;
17271 }
17272 }
17273
17274 return TRUE;
17275}
17276
17277/**
17278 * wlan_hdd_mdns_pack_response_type_ptr() - Pack Type PTR response
17279 * @ini_config: Pointer to the struct hdd_config_t
17280 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17281 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17282 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17283 * domain name
17284 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17285 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17286 *
17287 * The Type Ptr response include QName, response type, class, TTL and
17288 * Type PTR domain name. Also, it will find the matched QName from the
17289 * existing resptype_txt, resptype_a and then compress the data.
17290 *
17291 * Return: Return boolean. TRUE for success, FALSE for fail.
17292 */
17293static bool
17294wlan_hdd_mdns_pack_response_type_ptr(hdd_config_t *ini_config,
17295 sir_mdns_resp_info resp_info,
17296 struct hdd_mdns_resp_info *resptype_ptr,
17297 struct hdd_mdns_resp_info *resptype_ptr_dn,
17298 struct hdd_mdns_resp_info *resptype_txt,
17299 struct hdd_mdns_resp_info *resptype_a)
17300{
17301 uint8_t num_matched, num_matched1;
17302 uint16_t value;
17303 uint8_t val_u8;
17304 uint32_t offset_data_len, len;
17305
17306 ENTER();
17307 if ((ini_config == NULL) || (resp_info == NULL) ||
17308 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
17309 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17310 return FALSE;
17311 }
17312
17313 /* No Type Ptr response */
17314 if (strlen((char *)ini_config->mdns_resp_type_ptr) <= 0)
17315 return TRUE;
17316
17317 /* Wrong response is assigned, just ignore this response */
17318 if (!wlan_hdd_mdns_init_response(resptype_ptr,
17319 ini_config->mdns_resp_type_ptr, '.'))
17320 return TRUE;
17321
17322 /*
17323 * For data compression
17324 * Check if any strings are matched with Type A response
17325 */
17326 num_matched = 0;
17327 num_matched1 = 0;
17328 if (resptype_a && (resptype_a->num_entries > 0)) {
17329 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr,
17330 resptype_a);
17331 }
17332 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17333 num_matched1 = wlan_hdd_mdns_find_entries_from_end(
17334 resptype_ptr, resptype_txt);
17335 }
17336 if ((num_matched != num_matched1) ||
17337 ((num_matched > 0) && (num_matched1 > 0))) {
17338 if (num_matched >= num_matched1) {
17339 if (!wlan_hdd_mdns_compress_data(resp_info,
17340 resptype_ptr, resptype_a, num_matched)) {
17341 hddLog(LOGE, FL("Fail to compress mDNS "
17342 "response (%d)!"), MDNS_TYPE_PTR);
17343 return FALSE;
17344 }
17345 } else {
17346 /* num_matched is less than num_matched1 */
17347 if (!wlan_hdd_mdns_compress_data(resp_info,
17348 resptype_ptr, resptype_txt, num_matched1)) {
17349 hddLog(LOGE, FL("Fail to compress mDNS "
17350 "response (%d)!"), MDNS_TYPE_PTR);
17351 return FALSE;
17352 }
17353 }
17354 } else {
17355 /*
17356 * Both num_matched and num_matched1 are zero.
17357 * no TypeA & TypeTxt
17358 */
17359 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr,
17360 resp_info)) {
17361 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17362 MDNS_TYPE_PTR);
17363 return FALSE;
17364 }
17365 }
17366
17367 /* Process response Type, Class, TTL */
17368 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_PTR, resp_info)) {
17369 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17370 MDNS_TYPE_PTR);
17371 return FALSE;
17372 }
17373
17374 /*
17375 * Process response RDLength, RData (Ptr domain name)
17376 * Save the offset of RData length
17377 */
17378 offset_data_len = resp_info->resp_len;
17379 resp_info->resp_len += sizeof(uint16_t);
17380
17381 if (!wlan_hdd_mdns_pack_response_type_ptr_dname(ini_config, resp_info,
17382 resptype_ptr_dn, resptype_ptr,
17383 resptype_txt, resptype_a)) {
17384 return FALSE;
17385 }
17386 /* Set the RData length */
17387 len = offset_data_len + sizeof(uint16_t);
17388 if ((resptype_ptr_dn->num_entries > 0) &&
17389 (resp_info->resp_len > len)) {
17390 value = resp_info->resp_len - len;
17391 val_u8 = (value & 0xff00) >> 8;
17392 resp_info->resp_data[offset_data_len] = val_u8;
17393 val_u8 = value & 0xff;
17394 resp_info->resp_data[offset_data_len+1] = val_u8;
17395 } else {
17396 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17397 MDNS_TYPE_PTR);
17398 return FALSE;
17399 }
17400
17401 EXIT();
17402 return TRUE;
17403}
17404
17405/**
17406 * wlan_hdd_mdns_pack_response_type_srv_target()- Pack Type Service Target
17407 * @ini_config: Pointer to the struct hdd_config_t
17408 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17409 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
17410 * target
17411 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
17412 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17413 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17414 * domain name
17415 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17416 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17417 *
17418 * The Type service target is one of the data field in the Type SRV response.
17419 * Also, it will find the matched QName from the existing resptype_srv,
17420 * resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and then compress
17421 * the data.
17422 *
17423 * Return: Return boolean. TRUE for success, FALSE for fail.
17424 */
17425static bool
17426wlan_hdd_mdns_pack_response_type_srv_target(hdd_config_t *ini_config,
17427 sir_mdns_resp_info resp_info,
17428 struct hdd_mdns_resp_info *resptype_srv_tgt,
17429 struct hdd_mdns_resp_info *resptype_srv,
17430 struct hdd_mdns_resp_info *resptype_ptr,
17431 struct hdd_mdns_resp_info *resptype_ptr_dn,
17432 struct hdd_mdns_resp_info *resptype_txt,
17433 struct hdd_mdns_resp_info *resptype_a)
17434{
17435 uint8_t num_matched, num, size;
17436 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17437 struct hdd_mdns_resp_info *resp;
17438
17439 if ((ini_config == NULL) || (resp_info == NULL) ||
17440 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
17441 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17442 return FALSE;
17443 }
17444
17445 /* No Type Srv Target response */
17446 if (strlen((char *)ini_config->mdns_resp_type_srv_target) <= 0)
17447 return TRUE;
17448
17449 /* Wrong response is assigned, just ignore this response */
17450 if (!wlan_hdd_mdns_init_response(resptype_srv_tgt,
17451 ini_config->mdns_resp_type_srv_target, '.'))
17452 return TRUE;
17453
17454 /*
17455 * For data compression
17456 * Check if any strings are matched with previous response.
17457 */
17458 num = 0;
17459 size = (MAX_MDNS_RESP_TYPE-1);
17460 size *= sizeof(struct hdd_mdns_resp_matched);
17461 vos_mem_zero(matchedlist, size);
17462 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv_tgt,
17463 resptype_srv);
17464 if (num_matched > 0) {
17465 matchedlist[num].num_matched = num_matched;
17466 matchedlist[num].type = MDNS_TYPE_SRV;
17467 num++;
17468 }
17469 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
17470 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
17471 num_matched = wlan_hdd_mdns_find_entries_from_end(
17472 resptype_srv_tgt, resptype_ptr_dn);
17473 if (num_matched > 0) {
17474 matchedlist[num].num_matched = num_matched;
17475 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
17476 num++;
17477 }
17478 }
17479 num_matched = wlan_hdd_mdns_find_entries_from_end(
17480 resptype_srv_tgt, resptype_ptr);
17481 if (num_matched > 0) {
17482 matchedlist[num].num_matched = num_matched;
17483 matchedlist[num].type = MDNS_TYPE_PTR;
17484 num++;
17485 }
17486 }
17487 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17488 num_matched = wlan_hdd_mdns_find_entries_from_end(
17489 resptype_srv_tgt, resptype_txt);
17490 if (num_matched > 0) {
17491 matchedlist[num].num_matched = num_matched;
17492 matchedlist[num].type = MDNS_TYPE_TXT;
17493 num++;
17494 }
17495 }
17496 if (resptype_a && (resptype_a->num_entries > 0)) {
17497 num_matched = wlan_hdd_mdns_find_entries_from_end(
17498 resptype_srv_tgt, resptype_a);
17499 if (num_matched > 0) {
17500 matchedlist[num].num_matched = num_matched;
17501 matchedlist[num].type = MDNS_TYPE_A;
17502 num++;
17503 }
17504 }
17505 if (num > 0) {
17506 if (num > 1)
17507 wlan_hdd_mdns_find_max(matchedlist, num);
17508 resp = NULL;
17509 switch (matchedlist[num-1].type) {
17510 case MDNS_TYPE_A:
17511 resp = resptype_a;
17512 break;
17513 case MDNS_TYPE_TXT:
17514 resp = resptype_txt;
17515 break;
17516 case MDNS_TYPE_PTR:
17517 resp = resptype_ptr;
17518 break;
17519 case MDNS_TYPE_PTR_DNAME:
17520 resp = resptype_ptr_dn;
17521 break;
17522 case MDNS_TYPE_SRV:
17523 resp = resptype_srv;
17524 break;
17525 default:
17526 hddLog(LOGE, FL("Fail to compress mDNS response "
17527 "(%d)!"), MDNS_TYPE_SRV_TARGET);
17528 return FALSE;
17529 }
17530 num_matched = matchedlist[num-1].num_matched;
17531 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv_tgt,
17532 resp, num_matched)) {
17533 hddLog(LOGE, FL("Fail to compress mDNS response "
17534 "(%d)!"), MDNS_TYPE_SRV_TARGET);
17535 return FALSE;
17536 }
17537 } else {
17538 /* num = 0 -> no matched string */
17539 if (!wlan_hdd_mdns_process_response_dname(resptype_srv_tgt,
17540 resp_info)) {
17541 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17542 MDNS_TYPE_SRV_TARGET);
17543 return FALSE;
17544 }
17545 }
17546
17547 return TRUE;
17548}
17549
17550/**
17551 * wlan_hdd_mdns_pack_response_type_srv()- Pack Type Service response
17552 * @ini_config: Pointer to the struct hdd_config_t
17553 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17554 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
17555 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
17556 * target
17557 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17558 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17559 * domain name
17560 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17561 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17562 *
17563 * The Type SRV (Service) response include QName, response type, class, TTL
17564 * and four kinds of data fields. Also, it will find the matched QName from
17565 * the existing resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and
17566 * then compress the data.
17567 *
17568 * Return: Return boolean. TRUE for success, FALSE for fail.
17569 */
17570static bool
17571wlan_hdd_mdns_pack_response_type_srv(hdd_config_t *ini_config,
17572 sir_mdns_resp_info resp_info,
17573 struct hdd_mdns_resp_info *resptype_srv,
17574 struct hdd_mdns_resp_info *resptype_srv_tgt,
17575 struct hdd_mdns_resp_info *resptype_ptr,
17576 struct hdd_mdns_resp_info *resptype_ptr_dn,
17577 struct hdd_mdns_resp_info *resptype_txt,
17578 struct hdd_mdns_resp_info *resptype_a)
17579{
17580 uint8_t num_matched, num, size;
17581 uint16_t value;
17582 uint8_t val_u8;
17583 uint32_t offset_data_len, len;
17584 struct hdd_mdns_resp_info *resp;
17585 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17586
17587 ENTER();
17588
17589 if ((ini_config == NULL) || (resp_info == NULL) ||
17590 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
17591 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17592 return FALSE;
17593 }
17594
17595 /* No Type Srv response */
17596 if (strlen((char *)ini_config->mdns_resp_type_srv) <= 0)
17597 return TRUE;
17598
17599 /* Wrong response is assigned, just ignore this response */
17600 if (!wlan_hdd_mdns_init_response(resptype_srv,
17601 ini_config->mdns_resp_type_srv, '.'))
17602 return TRUE;
17603
17604 /*
17605 * For data compression
17606 * Check if any strings are matched with Type A response
17607 */
17608 num = 0;
17609 size = (MAX_MDNS_RESP_TYPE-1);
17610 size *= sizeof(struct hdd_mdns_resp_matched);
17611 vos_mem_zero(matchedlist, size);
17612 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
17613 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
17614 num_matched = wlan_hdd_mdns_find_entries_from_end(
17615 resptype_srv,
17616 resptype_ptr_dn);
17617 if (num_matched > 0) {
17618 matchedlist[num].num_matched = num_matched;
17619 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
17620 num++;
17621 }
17622 }
17623 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17624 resptype_ptr);
17625 if (num_matched > 0) {
17626 matchedlist[num].num_matched = num_matched;
17627 matchedlist[num].type = MDNS_TYPE_PTR;
17628 num++;
17629 }
17630 }
17631 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17632 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17633 resptype_txt);
17634 if (num_matched > 0) {
17635 matchedlist[num].num_matched =num_matched;
17636 matchedlist[num].type = MDNS_TYPE_TXT;
17637 num++;
17638 }
17639 }
17640 if (resptype_a && (resptype_a->num_entries > 0)) {
17641 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17642 resptype_a);
17643 if (num_matched > 0) {
17644 matchedlist[num].num_matched = num_matched;
17645 matchedlist[num].type = MDNS_TYPE_A;
17646 num++;
17647 }
17648 }
17649 if (num > 0) {
17650 if (num > 1)
17651 wlan_hdd_mdns_find_max(matchedlist, num);
17652 resp = NULL;
17653 switch (matchedlist[num-1].type) {
17654 case MDNS_TYPE_A:
17655 resp = resptype_a;
17656 break;
17657 case MDNS_TYPE_TXT:
17658 resp = resptype_txt;
17659 break;
17660 case MDNS_TYPE_PTR:
17661 resp = resptype_ptr;
17662 break;
17663 case MDNS_TYPE_PTR_DNAME:
17664 resp = resptype_ptr_dn;
17665 break;
17666 default:
17667 hddLog(LOGE, FL("Fail to compress mDNS response "
17668 "(%d)!"), MDNS_TYPE_SRV);
17669 return FALSE;
17670 }
17671 num_matched = matchedlist[num-1].num_matched;
17672 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv,
17673 resp, num_matched)) {
17674 hddLog(LOGE, FL("Fail to compress mDNS response "
17675 "(%d)!"), MDNS_TYPE_SRV);
17676 return FALSE;
17677 }
17678 } else {
17679 /* num = 0 -> no matched string */
17680 if (!wlan_hdd_mdns_process_response_dname(resptype_srv,
17681 resp_info)) {
17682 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17683 MDNS_TYPE_SRV);
17684 return FALSE;
17685 }
17686 }
17687
17688 /* Process response Type, Class, TTL */
17689 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_SRV, resp_info)) {
17690 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17691 MDNS_TYPE_SRV);
17692 return FALSE;
17693 }
17694
17695 /*
17696 * Process response RDLength, RData (Srv target name)
17697 * Save the offset of RData length
17698 */
17699 offset_data_len = resp_info->resp_len;
17700 resp_info->resp_len += sizeof(uint16_t);
17701
17702 len = resp_info->resp_len + (3 * sizeof(uint16_t));
17703 if (len >= MAX_MDNS_RESP_LEN) {
17704 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17705 return FALSE;
17706 }
17707
17708 /* set Srv Priority */
17709 value = ini_config->mdns_resp_type_srv_priority;
17710 wlan_hdd_mdns_format_response_u16(value, resp_info);
17711 /* set Srv Weight */
17712 value = ini_config->mdns_resp_type_srv_weight;
17713 wlan_hdd_mdns_format_response_u16(value, resp_info);
17714 /* set Srv Port */
17715 value = ini_config->mdns_resp_type_srv_port;
17716 wlan_hdd_mdns_format_response_u16(value, resp_info);
17717
17718 if (!wlan_hdd_mdns_pack_response_type_srv_target(ini_config, resp_info,
17719 resptype_srv_tgt, resptype_srv,
17720 resptype_ptr, resptype_ptr_dn,
17721 resptype_txt, resptype_a)) {
17722 return FALSE;
17723 }
17724 /* Set the RData length */
17725 len = offset_data_len + sizeof(uint16_t);
17726 if ((resptype_srv_tgt->num_entries > 0) &&
17727 (resp_info->resp_len > len)) {
17728 value = resp_info->resp_len - len;
17729 val_u8 = (value & 0xff00) >> 8;
17730 resp_info->resp_data[offset_data_len] = val_u8;
17731 val_u8 = value & 0xff;
17732 resp_info->resp_data[offset_data_len+1] = val_u8;
17733 } else {
17734 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17735 MDNS_TYPE_SRV);
17736 return FALSE;
17737 }
17738
17739 EXIT();
17740 return TRUE;
17741}
17742
17743/**
17744 * wlan_hdd_mdns_free_mem() - Free the allocated memory
17745 * @response: Pointer to the struct hdd_mdns_resp_info
17746 *
17747 * Return: None
17748 */
17749static void wlan_hdd_mdns_free_mem(struct hdd_mdns_resp_info *response)
17750{
17751 if (response && response->data)
17752 vos_mem_free(response->data);
17753 if (response && response->offset)
17754 vos_mem_free(response->offset);
17755}
17756
17757/**
17758 * wlan_hdd_mdns_pack_response() - Pack mDNS response
17759 * @ini_config: Pointer to the struct hdd_config_t
17760 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17761 *
17762 * This function will pack four types of responses (Type A, Type Txt, Type Ptr
17763 * and Type Service). Each response contains QName, response type, class, TTL
17764 * and data fields.
17765 *
17766 * Return: Return boolean. TRUE for success, FALSE for fail.
17767 */
17768static bool wlan_hdd_mdns_pack_response(hdd_config_t *ini_config,
17769 sir_mdns_resp_info resp_info)
17770{
17771 struct hdd_mdns_resp_info resptype_a, resptype_txt;
17772 struct hdd_mdns_resp_info resptype_ptr, resptype_ptr_dn;
17773 struct hdd_mdns_resp_info resptype_srv, resptype_srv_tgt;
17774 uint32_t num_res_records = 0;
17775 bool status = FALSE;
17776
17777 ENTER();
17778
17779 wlan_hdd_mdns_reset_response(&resptype_a);
17780 wlan_hdd_mdns_reset_response(&resptype_txt);
17781 wlan_hdd_mdns_reset_response(&resptype_ptr);
17782 wlan_hdd_mdns_reset_response(&resptype_ptr_dn);
17783 wlan_hdd_mdns_reset_response(&resptype_srv);
17784 wlan_hdd_mdns_reset_response(&resptype_srv_tgt);
17785
17786 resp_info->resp_len = 0;
17787
17788 /* Process Type A response */
17789 if (!wlan_hdd_mdns_pack_response_type_a(ini_config, resp_info,
17790 &resptype_a))
17791 goto err_resptype_a;
17792
17793 if ((resptype_a.num_entries > 0) &&
17794 (strlen((char *)&resptype_a.data[0]) > 0))
17795 num_res_records++;
17796
17797 /* Process Type TXT response */
17798 if (!wlan_hdd_mdns_pack_response_type_txt(ini_config, resp_info,
17799 &resptype_txt, &resptype_a))
17800 goto err_resptype_txt;
17801
17802 if ((resptype_txt.num_entries > 0) &&
17803 (strlen((char *)&resptype_txt.data[0]) > 0))
17804 num_res_records++;
17805
17806 /* Process Type PTR response */
17807 if (!wlan_hdd_mdns_pack_response_type_ptr(ini_config, resp_info,
17808 &resptype_ptr, &resptype_ptr_dn,
17809 &resptype_txt, &resptype_a))
17810 goto err_resptype_ptr;
17811
17812 if ((resptype_ptr.num_entries > 0) &&
17813 (strlen((char *)&resptype_ptr.data[0]) > 0))
17814 num_res_records++;
17815
17816 /* Process Type SRV response */
17817 if (!wlan_hdd_mdns_pack_response_type_srv(ini_config, resp_info,
17818 &resptype_srv, &resptype_srv_tgt,
17819 &resptype_ptr, &resptype_ptr_dn,
17820 &resptype_txt, &resptype_a))
17821 goto err_resptype_srv;
17822
17823 if ((resptype_srv.num_entries > 0) &&
17824 (strlen((char *)&resptype_srv.data[0]) > 0))
17825 num_res_records++;
17826
17827 resp_info->resourceRecord_count = num_res_records;
17828 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
17829 "%s: Pack mDNS response data successfully!", __func__);
17830 status = TRUE;
17831
17832err_resptype_srv:
17833 wlan_hdd_mdns_free_mem(&resptype_srv);
17834 wlan_hdd_mdns_free_mem(&resptype_srv_tgt);
17835
17836err_resptype_ptr:
17837 wlan_hdd_mdns_free_mem(&resptype_ptr);
17838 wlan_hdd_mdns_free_mem(&resptype_ptr_dn);
17839
17840err_resptype_txt:
17841 wlan_hdd_mdns_free_mem(&resptype_txt);
17842
17843err_resptype_a:
17844 wlan_hdd_mdns_free_mem(&resptype_a);
17845
17846 EXIT();
17847 return status;
17848}
17849
17850/**
17851 * wlan_hdd_set_mdns_offload() - Enable mDNS offload
17852 * @hostapd_adapter: Pointer to the struct hdd_adapter_t
17853 *
17854 * This function will set FQDN/unique FQDN (full qualified domain name)
17855 * and the mDNS response. Then send them to SME.
17856 *
17857 * Return: Return boolean. TRUE for success, FALSE for fail.
17858 */
17859bool wlan_hdd_set_mdns_offload(hdd_adapter_t *hostapd_adapter)
17860{
17861 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
17862 sir_mdns_offload_info mdns_offload_info;
17863 sir_mdns_fqdn_info mdns_fqdn_info;
17864 sir_mdns_resp_info mdns_resp_info;
17865 uint32_t fqdn_len, ufqdn_len;
17866
17867 ENTER();
17868
17869 /* 1. Prepare the MDNS fqdn request to send to SME */
17870 fqdn_len = strlen(hdd_ctx->cfg_ini->mdns_fqdn);
17871 ufqdn_len = strlen(hdd_ctx->cfg_ini->mdns_uniquefqdn);
17872 if ((fqdn_len == 0) && (ufqdn_len == 0)) {
17873 hddLog(LOGE, FL("No mDNS FQDN or UFQDN is assigned fqdn_len %d,"
17874 "ufqdn_len %d!"), fqdn_len, ufqdn_len);
17875 return FALSE;
17876 }
17877
17878 mdns_fqdn_info = vos_mem_malloc(sizeof(*mdns_fqdn_info));
17879 if (NULL == mdns_fqdn_info) {
17880 hddLog(LOGE, FL("could not allocate tSirMDNSFqdnInfo!"));
17881 return FALSE;
17882 }
17883 /* MDNS fqdn request */
17884 if (fqdn_len > 0) {
17885 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
17886 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
17887 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_GENERAL;
17888 mdns_fqdn_info->fqdn_len = fqdn_len;
17889 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
17890 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
17891 vos_mem_copy(mdns_fqdn_info->fqdn_data,
17892 hdd_ctx->cfg_ini->mdns_fqdn,
17893 mdns_fqdn_info->fqdn_len);
17894
17895 if (eHAL_STATUS_SUCCESS !=
17896 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
17897 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
17898 vos_mem_free(mdns_fqdn_info);
17899 return FALSE;
17900 }
17901 }
17902 /* MDNS unique fqdn request */
17903 if (ufqdn_len > 0) {
17904 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
17905 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
17906 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_UNIQUE;
17907 mdns_fqdn_info->fqdn_len = ufqdn_len;
17908 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
17909 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
17910 vos_mem_copy(mdns_fqdn_info->fqdn_data,
17911 hdd_ctx->cfg_ini->mdns_uniquefqdn,
17912 mdns_fqdn_info->fqdn_len);
17913 if (eHAL_STATUS_SUCCESS !=
17914 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
17915 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
17916 vos_mem_free(mdns_fqdn_info);
17917 return FALSE;
17918 }
17919 }
17920 vos_mem_free(mdns_fqdn_info);
17921
17922 /* 2. Prepare the MDNS response request to send to SME */
17923 mdns_resp_info = vos_mem_malloc(sizeof(*mdns_resp_info));
17924 if (NULL == mdns_resp_info) {
17925 hddLog(LOGE, FL("could not allocate tSirMDNSResponseInfo!"));
17926 return FALSE;
17927 }
17928
17929 vos_mem_zero(mdns_resp_info, sizeof(*mdns_resp_info));
17930 mdns_resp_info->bss_idx = hostapd_adapter->sessionId;
17931 mdns_resp_info->mdns_resp_callback = hdd_mdns_resp_offload_done;
17932 mdns_resp_info->mdns_resp_cb_context = hostapd_adapter;
17933 if (!wlan_hdd_mdns_pack_response(hdd_ctx->cfg_ini, mdns_resp_info)) {
17934 hddLog(LOGE, FL("wlan_hdd_pack_mdns_response fail!"));
17935 vos_mem_free(mdns_resp_info);
17936 return FALSE;
17937 }
17938 if (eHAL_STATUS_SUCCESS !=
17939 sme_set_mdns_resp(hdd_ctx->hHal, mdns_resp_info)) {
17940 hddLog(LOGE, FL("sme_set_mdns_resp fail!"));
17941 vos_mem_free(mdns_resp_info);
17942 return FALSE;
17943 }
17944 vos_mem_free(mdns_resp_info);
17945
17946 /* 3. Prepare the MDNS Enable request to send to SME */
17947 mdns_offload_info = vos_mem_malloc(sizeof(*mdns_offload_info));
17948 if (NULL == mdns_offload_info) {
17949 hddLog(LOGE, FL("could not allocate tSirMDNSOffloadInfo!"));
17950 return FALSE;
17951 }
17952
17953 vos_mem_zero(mdns_offload_info, sizeof(*mdns_offload_info));
17954
17955 mdns_offload_info->bss_idx = hostapd_adapter->sessionId;
17956 mdns_offload_info->enable = hdd_ctx->cfg_ini->enable_mdns_offload;
17957 mdns_offload_info->mdns_enable_callback = hdd_mdns_enable_offload_done;
17958 mdns_offload_info->mdns_enable_cb_context = hostapd_adapter;
17959 if (eHAL_STATUS_SUCCESS !=
17960 sme_set_mdns_offload(hdd_ctx->hHal, mdns_offload_info)) {
17961 hddLog(LOGE, FL("sme_set_mdns_offload fail!"));
17962 vos_mem_free(mdns_offload_info);
17963 return FALSE;
17964 }
17965
17966 vos_mem_free(mdns_offload_info);
17967 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
17968 "%s: enable mDNS offload successfully!", __func__);
17969 return TRUE;
17970}
Manjeet Singh3ed79242017-01-11 19:04:32 +053017971
17972
Anurag Chouhan0b29de02016-12-16 13:18:40 +053017973#endif /* MDNS_OFFLOAD */
c_manjeecfd1efb2015-09-25 19:32:34 +053017974
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053017975/**
17976 * wlan_hdd_start_sap() - This function starts bss of SAP.
17977 * @ap_adapter: SAP adapter
17978 *
17979 * This function will process the starting of sap adapter.
17980 *
17981 * Return: void.
17982 */
17983void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter)
17984{
17985 hdd_ap_ctx_t *hdd_ap_ctx;
17986 hdd_hostapd_state_t *hostapd_state;
17987 VOS_STATUS vos_status;
17988 hdd_context_t *hdd_ctx;
17989 tsap_Config_t *pConfig;
17990
17991 if (NULL == ap_adapter) {
17992 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17993 FL("ap_adapter is NULL here"));
17994 return;
17995 }
17996
17997 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
17998 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
17999 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
18000 pConfig = &ap_adapter->sessionCtx.ap.sapConfig;
18001
18002 mutex_lock(&hdd_ctx->sap_lock);
18003 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
18004 goto end;
18005
18006 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
18007 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
18008 goto end;
18009 }
18010
18011 vos_event_reset(&hostapd_state->vosEvent);
18012 if (WLANSAP_StartBss(hdd_ctx->pvosContext, hdd_hostapd_SAPEventCB,
18013 &hdd_ap_ctx->sapConfig, (v_PVOID_t)ap_adapter->dev)
18014 != VOS_STATUS_SUCCESS) {
18015 goto end;
18016 }
18017
18018 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
18019 FL("Waiting for SAP to start"));
18020 vos_status = vos_wait_single_event(&hostapd_state->vosEvent, 10000);
18021 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
18022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18023 FL("SAP Start failed"));
18024 goto end;
18025 }
18026 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
18027 FL("SAP Start Success"));
18028 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
18029
18030 wlan_hdd_incr_active_session(hdd_ctx, ap_adapter->device_mode);
18031 hostapd_state->bCommit = TRUE;
18032
18033end:
18034 mutex_unlock(&hdd_ctx->sap_lock);
18035 return;
18036}
18037
Manjeet Singh3ed79242017-01-11 19:04:32 +053018038#ifdef WLAN_FEATURE_TSF
18039
18040/**
18041 * hdd_tsf_cb() - handle tsf request callback
18042 *
18043 * @pcb_cxt: pointer to the hdd_contex
18044 * @ptsf: pointer to struct stsf
18045 *
18046 * Based on the request sent .
18047 *
18048 * Return: Describe the execute result of this routine
18049 */
18050static int hdd_tsf_cb(void *pcb_ctx, struct stsf *ptsf)
18051{
18052 hdd_context_t *hddctx;
18053 int status;
18054 hdd_adapter_t* adapter = (hdd_adapter_t*)pcb_ctx;
18055
18056 if (pcb_ctx == NULL || ptsf == NULL) {
18057 hddLog(VOS_TRACE_LEVEL_ERROR,
18058 FL("HDD context is not valid"));
18059 return -EINVAL;
18060 }
18061
18062 hddctx = (hdd_context_t *)pcb_ctx;
18063 status = wlan_hdd_validate_context(hddctx);
18064 if (0 != status)
18065 return -EINVAL;
18066
18067 if (NULL == adapter) {
18068 hddLog(VOS_TRACE_LEVEL_ERROR,
18069 FL("failed to find adapter"));
18070 return -EINVAL;
18071 }
18072
18073 hddLog(VOS_TRACE_LEVEL_INFO,
18074 FL("tsf cb handle event, device_mode is %d"),
18075 adapter->device_mode);
18076
18077 /* copy the return value to hdd_tsf_ctx in adapter*/
18078 if (ptsf->tsf_req_status) {
18079
18080 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18081 adapter->tsf_cap_ctx.tsf_get_state = TSF_NOT_RETURNED_BY_FW;
18082 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18083 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
18084 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18085
18086 hddLog(VOS_TRACE_LEVEL_ERROR, FL("tsf req failure :%d"),
18087 ptsf->tsf_req_status);
18088 return ptsf->tsf_req_status;
18089 }
18090 /* If this is a get request.Store the tsf values in adapter. */
18091 if (!ptsf->set_tsf_req) {
18092 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18093 adapter->tsf_cap_ctx.tsf_low = ptsf->tsf_low;
18094 adapter->tsf_cap_ctx.tsf_high = ptsf->tsf_high;
18095 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
18096 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18097 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18098
18099 hddLog(VOS_TRACE_LEVEL_INFO,
18100 FL("hdd_get_tsf_cb sta=%u, tsf_low=%u, tsf_high=%u"),
18101 adapter->sessionId, ptsf->tsf_low, ptsf->tsf_high);
18102 }
18103 else {
18104 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18105 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
18106 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
18107 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18108 }
18109 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18110 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
18111 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18112
18113 /* free allocated mem */
18114 vos_mem_free(ptsf);
18115
18116 return 0;
18117}
18118
18119/**
18120 * hdd_capture_tsf() - capture tsf
18121 *
18122 * @adapter: pointer to adapter
18123 * @buf: pointer to upper layer buf
18124 * @len : the length of buf
18125 *
18126 * This function returns tsf value to uplayer.
18127 *
18128 * Return: Describe the execute result of this routine
18129 */
18130int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
18131{
18132 int ret = 0;
18133 hdd_station_ctx_t *hdd_sta_ctx;
18134 hdd_context_t *hdd_ctx;
18135 tSirCapTsfParams cap_tsf_params;
18136 VOS_STATUS status;
18137
18138 if (adapter == NULL || buf == NULL) {
18139 hddLog(VOS_TRACE_LEVEL_ERROR,
18140 FL("invalid pointer"));
18141 return -EINVAL;
18142 }
18143 if (len != 1)
18144 return -EINVAL;
18145
18146 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
18147
18148 if (wlan_hdd_validate_context(hdd_ctx)) {
18149 hddLog(VOS_TRACE_LEVEL_ERROR,
18150 FL("invalid hdd ctx"));
18151 return -EINVAL;
18152 }
18153 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18154 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
18155 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18156 if (hdd_sta_ctx->conn_info.connState !=
18157 eConnectionState_Associated) {
18158
18159 hddLog(VOS_TRACE_LEVEL_INFO,
18160 FL("failed to cap tsf, not connect with ap"));
18161 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
18162 return ret;
18163 }
18164 }
18165 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
18166 adapter->device_mode == WLAN_HDD_P2P_GO) &&
18167 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
18168 hddLog(VOS_TRACE_LEVEL_INFO,
18169 FL("Soft AP / P2p GO not beaconing"));
18170 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
18171 return ret;
18172 }
18173 if (adapter->tsf_cap_ctx.tsf_capture_state == TSF_CAP_STATE) {
18174 hddLog(VOS_TRACE_LEVEL_INFO,
18175 FL("current in capture state, pls reset"));
18176 buf[0] = TSF_CURRENT_IN_CAP_STATE;
18177 } else {
18178 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
18179 buf[0] = TSF_RETURN;
18180 cap_tsf_params.session_id = adapter->sessionId;
18181 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
18182 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
18183
18184 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18185 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
18186 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
18187 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18188
18189 ret = sme_capture_tsf_req(hdd_ctx->hHal, cap_tsf_params);
18190
18191 if (ret != VOS_STATUS_SUCCESS) {
18192 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
18193 buf[0] = TSF_CAPTURE_FAIL;
18194 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18195 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18196 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18197 return -EINVAL;
18198 }
18199 /* wait till we get a response from fw */
18200 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
18201 tsf_capture_done_event,
18202 HDD_TSF_CAP_REQ_TIMEOUT);
18203
18204 if (!VOS_IS_STATUS_SUCCESS(status)) {
18205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18206 ("capture tsf vos wait for single_event failed!! %d"),
18207 adapter->tsf_cap_ctx.tsf_get_state);
18208
18209 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18210 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18211 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18212
18213 return -EINVAL;
18214 }
18215 }
18216 buf[0] = TSF_RETURN;
18217 hddLog(VOS_TRACE_LEVEL_INFO,
18218 FL("ioctl return cap tsf cmd, ret = %d"), ret);
18219 return ret;
18220}
18221
18222/**
18223 * hdd_indicate_tsf() - return tsf to uplayer
18224 *
18225 * @adapter: pointer to adapter
18226 * @buf: pointer to uplayer buf
18227 * @len : the length of buf
18228 *
18229 * This function returns tsf value to uplayer.
18230 *
18231 * Return: Describe the execute result of this routine
18232 */
18233int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
18234{
18235 int ret = 0;
18236 hdd_station_ctx_t *hdd_sta_ctx;
18237 hdd_context_t *hdd_ctx;
18238 tSirCapTsfParams cap_tsf_params;
18239 VOS_STATUS status;
18240
18241 if (adapter == NULL || buf == NULL) {
18242 hddLog(VOS_TRACE_LEVEL_ERROR,
18243 FL("invalid pointer"));
18244 return -EINVAL;
18245 }
18246 if (len != 3)
18247 return -EINVAL;
18248
18249 buf [1] = 0;
18250 buf [2] = 0;
18251 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
18252
18253 if (wlan_hdd_validate_context(hdd_ctx)) {
18254 hddLog(VOS_TRACE_LEVEL_ERROR,
18255 FL("invalid hdd ctx"));
18256 return -EINVAL;
18257 }
18258 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18259 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
18260 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18261 if (hdd_sta_ctx->conn_info.connState !=
18262 eConnectionState_Associated) {
18263
18264 hddLog(VOS_TRACE_LEVEL_INFO,
18265 FL("failed to cap tsf, not connect with ap"));
18266 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
18267 return ret;
18268 }
18269 }
18270 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
18271 adapter->device_mode == WLAN_HDD_P2P_GO) &&
18272 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
18273 hddLog(VOS_TRACE_LEVEL_INFO,
18274 FL("Soft AP / P2p GO not beaconing"));
18275 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
18276 return ret;
18277 }
18278
18279 if (adapter->tsf_cap_ctx.tsf_capture_state != TSF_CAP_STATE ||
18280 adapter->tsf_cap_ctx.tsf_get_state != TSF_CURRENT_IN_CAP_STATE ) {
18281 hddLog(VOS_TRACE_LEVEL_INFO,
18282 FL("Not in capture state,Enter capture state first"));
18283 buf[0] = TSF_GET_FAIL;
18284 } else {
18285 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
18286 cap_tsf_params.session_id = adapter->sessionId;
18287 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
18288 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
18289
18290 ret = sme_get_tsf_req(hdd_ctx->hHal, cap_tsf_params);
18291
18292 if (ret != VOS_STATUS_SUCCESS) {
18293 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
18294 buf[0] = TSF_CAPTURE_FAIL;
18295 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18296 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18297 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18298 return -EINVAL;
18299 }
18300 /* wait till we get a response from fw */
18301 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
18302 tsf_capture_done_event,
18303 HDD_TSF_GET_REQ_TIMEOUT);
18304
18305 if (!VOS_IS_STATUS_SUCCESS(status)) {
18306 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18307 ("capture tsf vos wait for single_event failed!! %d"),
18308 status);
18309
18310 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18311 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18312 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18313 return status;
18314 }
18315 buf[1] = adapter->tsf_cap_ctx.tsf_low;
18316 buf[2] = adapter->tsf_cap_ctx.tsf_high;
18317
18318 hddLog(VOS_TRACE_LEVEL_INFO,
18319 FL("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u"),
18320 buf[0], buf[1], buf[2]);
18321 }
18322 hddLog(VOS_TRACE_LEVEL_INFO,
18323 FL("ioctl return cap tsf cmd, ret = %d"), ret);
18324 return ret;
18325}
18326
18327void wlan_hdd_tsf_init(hdd_adapter_t *adapter)
18328{
18329
18330 if (adapter == NULL) {
18331 hddLog(VOS_TRACE_LEVEL_ERROR,
18332 FL("TSF init on a null adapter!"));
18333 return;
18334 }
18335
18336 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
18337 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18338 vos_event_init(&adapter->tsf_cap_ctx.tsf_capture_done_event);
18339 vos_spin_lock_init(&adapter->tsf_cap_ctx.tsf_lock);
18340 adapter->tsf_cap_ctx.tsf_high = 0;
18341 adapter->tsf_cap_ctx.tsf_low = 0;
18342}
18343
18344#endif
18345
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +053018346bool hdd_is_memdump_supported(void)
18347{
18348#ifdef WLAN_FEATURE_MEMDUMP
18349 return true;
18350#endif
18351 return false;
18352}
18353
Jeff Johnson295189b2012-06-20 16:38:30 -070018354//Register the module init/exit functions
18355module_init(hdd_module_init);
18356module_exit(hdd_module_exit);
18357
18358MODULE_LICENSE("Dual BSD/GPL");
18359MODULE_AUTHOR("Qualcomm Atheros, Inc.");
18360MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
18361
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018362static const struct kernel_param_ops con_mode_ops = {
18363 .set = con_mode_handler,
18364 .get = param_get_int,
18365};
18366
18367static const struct kernel_param_ops fwpath_ops = {
18368 .set = fwpath_changed_handler,
18369 .get = param_get_string,
18370};
18371
18372module_param_cb(con_mode, &con_mode_ops, &con_mode,
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070018373 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070018374
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018375module_param_cb(fwpath, &fwpath_ops, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070018376 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080018377
18378module_param(enable_dfs_chan_scan, int,
18379 S_IRUSR | S_IRGRP | S_IROTH);
18380
18381module_param(enable_11d, int,
18382 S_IRUSR | S_IRGRP | S_IROTH);
18383
18384module_param(country_code, charp,
18385 S_IRUSR | S_IRGRP | S_IROTH);