blob: 776c2082e3ddf8cd59c095815dbb6bf26268f86f [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Arunk Khandavalli95608be2019-01-22 13:12:54 +05302 * Copyright (c) 2012-2019 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>
Rajeev Kumar Sirasanagandlaf8fc27c2018-12-06 14:56:43 +053065#include <vos_nvitem.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <vos_sched.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067#include <linux/etherdevice.h>
68#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070069#ifdef ANI_BUS_TYPE_PLATFORM
70#include <linux/wcnss_wlan.h>
71#endif //ANI_BUS_TYPE_PLATFORM
72#ifdef ANI_BUS_TYPE_PCI
73#include "wcnss_wlan.h"
74#endif /* ANI_BUS_TYPE_PCI */
75#include <wlan_hdd_tx_rx.h>
76#include <palTimer.h>
77#include <wniApi.h>
78#include <wlan_nlink_srv.h>
79#include <wlan_btc_svc.h>
80#include <wlan_hdd_cfg.h>
81#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053082#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070083#include <wlan_hdd_wowl.h>
84#include <wlan_hdd_misc.h>
85#include <wlan_hdd_wext.h>
86#ifdef WLAN_BTAMP_FEATURE
87#include <bap_hdd_main.h>
88#include <bapInternal.h>
89#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053090#include "wlan_hdd_trace.h"
91#include "vos_types.h"
92#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070093#include <linux/wireless.h>
94#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053095#include <linux/inetdevice.h>
96#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070097#include "wlan_hdd_cfg80211.h"
98#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070099#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700100int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700101#include "sapApi.h"
102#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700103#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530104#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
105#include <soc/qcom/subsystem_restart.h>
106#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700107#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530108#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#include <wlan_hdd_hostapd.h>
110#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700111#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700112#include "wlan_hdd_dev_pwr.h"
113#ifdef WLAN_BTAMP_FEATURE
114#include "bap_hdd_misc.h"
115#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700116#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700117#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800118#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530119#ifdef FEATURE_WLAN_TDLS
120#include "wlan_hdd_tdls.h"
121#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700122#include "wlan_hdd_debugfs.h"
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530123#include "sapInternal.h"
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +0530124#include "wlan_hdd_request_manager.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700125
126#ifdef MODULE
127#define WLAN_MODULE_NAME module_name(THIS_MODULE)
128#else
129#define WLAN_MODULE_NAME "wlan"
130#endif
131
132#ifdef TIMER_MANAGER
133#define TIMER_MANAGER_STR " +TIMER_MANAGER"
134#else
135#define TIMER_MANAGER_STR ""
136#endif
137
138#ifdef MEMORY_DEBUG
139#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
140#else
141#define MEMORY_DEBUG_STR ""
142#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530143#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700144/* the Android framework expects this param even though we don't use it */
145#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700146static char fwpath_buffer[BUF_LEN];
147static struct kparam_string fwpath = {
148 .string = fwpath_buffer,
149 .maxlen = BUF_LEN,
150};
Arif Hussain66559122013-11-21 10:11:40 -0800151
152static char *country_code;
153static int enable_11d = -1;
154static int enable_dfs_chan_scan = -1;
155
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 }
Ashish Kumar Dhanotiya445b3b92018-06-07 12:38:12 +0530763 else
764 {
765 /* New country Supports DFS as well resetting value back from .ini */
766 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter),
767 cfg_param->enableDFSChnlScan);
768 }
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700769
770}
771
Abhishek Singh00b71972016-01-07 10:51:04 +0530772#ifdef WLAN_FEATURE_RMC
773static int hdd_parse_setrmcenable_command(tANI_U8 *pValue, tANI_U8 *pRmcEnable)
774{
775 tANI_U8 *inPtr = pValue;
776 int tempInt;
777 int v = 0;
778 char buf[32];
779 *pRmcEnable = 0;
780
781 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
782 /*no argument after the command*/
783 if (NULL == inPtr)
784 {
785 return 0;
786 }
787
788 /*no space after the command*/
789 else if (SPACE_ASCII_VALUE != *inPtr)
790 {
791 return 0;
792 }
793
794 /*removing empty spaces*/
795 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
796
797 /*no argument followed by spaces*/
798 if ('\0' == *inPtr)
799 {
800 return 0;
801 }
802
803 /* getting the first argument which enables or disables RMC
804 * for input IP v4 address*/
Ashish Kumar Dhanotiya54d31a32017-08-04 17:12:44 +0530805 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530806 v = kstrtos32(buf, 10, &tempInt);
807 if ( v < 0)
808 {
809 return -EINVAL;
810 }
811
812 *pRmcEnable = tempInt;
813
814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
815 "ucRmcEnable: %d", *pRmcEnable);
816
817 return 0;
818}
819
820/* Function header left blank Intentionally */
821static int hdd_parse_setrmcactionperiod_command(tANI_U8 *pValue,
822 tANI_U32 *pActionPeriod)
823{
824 tANI_U8 *inPtr = pValue;
825 int tempInt;
826 int v = 0;
827 char buf[32];
828 *pActionPeriod = 0;
829
830 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
831 /*no argument after the command*/
832 if (NULL == inPtr)
833 {
834 return -EINVAL;
835 }
836
837 /*no space after the command*/
838 else if (SPACE_ASCII_VALUE != *inPtr)
839 {
840 return -EINVAL;
841 }
842
843 /*removing empty spaces*/
844 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
845
846 /*no argument followed by spaces*/
847 if ('\0' == *inPtr)
848 {
849 return 0;
850 }
851
852 /* getting the first argument which enables or disables RMC
853 * for input IP v4 address*/
Ashish Kumar Dhanotiya54d31a32017-08-04 17:12:44 +0530854 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530855 v = kstrtos32(buf, 10, &tempInt);
856 if ( v < 0)
857 {
858 return -EINVAL;
859 }
860
861 /* Range checking for passed paramter */
862 if (tempInt < WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN ||
863 tempInt > WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX)
864 {
865 return -EINVAL;
866 }
867
868 *pActionPeriod = tempInt;
869
870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
871 "uActionPeriod: %d", *pActionPeriod);
872
873 return 0;
874}
Dundi Ravitejae110a042018-04-18 13:11:37 +0530875
876/**
877 * hdd_set_vowifi_mode() - Process VOWIFI command.
878 * @hdd_ctx: context handler
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530879 * @enable: Value to be sent as a part of the VOWIFI command
880 *
Dundi Ravitejae110a042018-04-18 13:11:37 +0530881 * Invoke the SME api if station is connected in 2.4 GHz band.
882 * Also start split scan if VOWIFIMODE and dynamic split scan
883 * both are enabled.
884
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530885 * Return: void
886 */
887void hdd_set_vowifi_mode(hdd_context_t *hdd_ctx, bool enable)
888{
889 tANI_U8 sta_chan;
890
Dundi Ravitejaab9d3092018-04-05 18:24:40 +0530891 if (!hdd_ctx->cfg_ini) {
892 hddLog(LOGE, "cfg_ini got NULL");
893 return;
894 }
895
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530896 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
897
Dundi Ravitejae110a042018-04-18 13:11:37 +0530898 if (CSR_IS_CHANNEL_24GHZ(sta_chan))
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530899 sme_set_vowifi_mode(hdd_ctx->hHal, enable);
Dundi Ravitejae110a042018-04-18 13:11:37 +0530900 else
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
902 "VoWiFi command rejected as not connected in 2.4GHz");
Dundi Ravitejae110a042018-04-18 13:11:37 +0530903
904 if (enable && hdd_ctx->cfg_ini->dynSplitscan) {
905 hdd_ctx->is_vowifi_enabled = true;
906 hdd_ctx->issplitscan_enabled = TRUE;
907 sme_enable_disable_split_scan(hdd_ctx->hHal,
908 hdd_ctx->cfg_ini->nNumStaChanCombinedConc,
909 hdd_ctx->cfg_ini->nNumP2PChanCombinedConc);
910 } else {
911 hdd_ctx->is_vowifi_enabled = false;
Dundi Ravitejaab9d3092018-04-05 18:24:40 +0530912 }
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530913}
Abhishek Singh00b71972016-01-07 10:51:04 +0530914
915/* Function header left blank Intentionally */
916static int hdd_parse_setrmcrate_command(tANI_U8 *pValue,
917 tANI_U32 *pRate, tTxrateinfoflags *pTxFlags)
918{
919 tANI_U8 *inPtr = pValue;
920 int tempInt;
921 int v = 0;
922 char buf[32];
923 *pRate = 0;
924 *pTxFlags = 0;
925
926 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
927 /*no argument after the command*/
928 if (NULL == inPtr)
929 {
930 return -EINVAL;
931 }
932
933 /*no space after the command*/
934 else if (SPACE_ASCII_VALUE != *inPtr)
935 {
936 return -EINVAL;
937 }
938
939 /*removing empty spaces*/
940 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
941
942 /*no argument followed by spaces*/
943 if ('\0' == *inPtr)
944 {
945 return 0;
946 }
947
948 /*
949 * getting the first argument which sets multicast rate.
950 */
Ashish Kumar Dhanotiya06f9f202017-08-04 15:26:27 +0530951 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530952 v = kstrtos32(buf, 10, &tempInt);
953 if ( v < 0)
954 {
955 return -EINVAL;
956 }
957
958 /*
959 * Validate the multicast rate.
960 */
961 switch (tempInt)
962 {
963 default:
964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
965 "Unsupported rate: %d", tempInt);
966 return -EINVAL;
967 case 0:
968 case 6:
969 case 9:
970 case 12:
971 case 18:
972 case 24:
973 case 36:
974 case 48:
975 case 54:
976 *pTxFlags = eHAL_TX_RATE_LEGACY;
977 *pRate = tempInt * 10;
978 break;
979 case 65:
980 *pTxFlags = eHAL_TX_RATE_HT20;
981 *pRate = tempInt * 10;
982 break;
983 case 72:
984 *pTxFlags = eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;
985 *pRate = 722; /* fractional rate 72.2 Mbps */
986 break;
987 }
988
989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
990 "Rate: %d", *pRate);
991
992 return 0;
993}
994
995/**---------------------------------------------------------------------------
996
997 \brief hdd_cfg80211_get_ibss_peer_info_cb() - Callback function for IBSS
998 Peer Info request
999
1000 This is an asynchronous callback function from SME when the peer info
1001 is received
1002
1003 \pUserData -> Adapter private data
1004 \pPeerInfoRsp -> Peer info response
1005
1006 \return - 0 for success non-zero for failure
1007 --------------------------------------------------------------------------*/
1008static void
1009hdd_cfg80211_get_ibss_peer_info_cb(v_VOID_t *pUserData, v_VOID_t *pPeerInfoRsp)
1010{
1011 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pUserData;
1012 tSirPeerInfoRspParams *pPeerInfo = (tSirPeerInfoRspParams *)pPeerInfoRsp;
1013 hdd_station_ctx_t *pStaCtx;
1014 v_U8_t i;
1015
1016 /*Sanity check*/
1017 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
1018 {
1019 hddLog(LOGE,
1020 FL("invalid adapter or adapter has invalid magic"));
1021 return;
1022 }
1023
1024 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1025 if (NULL != pStaCtx && NULL != pPeerInfo &&
1026 eHAL_STATUS_SUCCESS == pPeerInfo->status)
1027 {
1028 pStaCtx->ibss_peer_info.status = pPeerInfo->status;
1029 pStaCtx->ibss_peer_info.numIBSSPeers = pPeerInfo->numPeers;
1030
1031 /* Paranoia check */
1032 if (pPeerInfo->numPeers < HDD_MAX_NUM_IBSS_STA)
1033 {
1034 for (i = 0; i < pPeerInfo->numPeers; i++)
1035 {
1036 memcpy(&pStaCtx->ibss_peer_info.ibssPeerList[i],
1037 &pPeerInfo->peerInfoParams[i],
1038 sizeof(hdd_ibss_peer_info_params_t));
1039 }
1040 hddLog(LOG1,
1041 FL("Peer Info copied in HDD"));
1042 }
1043 else
1044 {
1045 hddLog(LOGE,
1046 FL(" Number of peers %d returned is more than limit %d"),
1047 pPeerInfo->numPeers, HDD_MAX_NUM_IBSS_STA);
1048 }
1049 }
1050 else
1051 {
1052 hddLog(LOG1,
1053 FL("peerInfo returned is NULL"));
1054 }
1055
1056 complete(&pAdapter->ibss_peer_info_comp);
1057}
1058
1059/**---------------------------------------------------------------------------
1060
1061 \brief hdd_cfg80211_get_ibss_peer_info_all() -
1062
1063 Request function to get IBSS peer info from lower layers
1064
1065 \pAdapter -> Adapter context
1066
1067 \return - 0 for success non-zero for failure
1068 --------------------------------------------------------------------------*/
1069static
1070VOS_STATUS hdd_cfg80211_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
1071{
1072 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1073 long status;
1074 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1075
1076 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1077
1078 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1079 hdd_cfg80211_get_ibss_peer_info_cb,
1080 VOS_TRUE, 0xFF);
1081
1082 if (VOS_STATUS_SUCCESS == retStatus)
1083 {
1084 status = wait_for_completion_interruptible_timeout
1085 (&pAdapter->ibss_peer_info_comp,
1086 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1087
1088 /* status will be 0 if timed out */
1089 if (status <= 0)
1090 {
1091 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1092 __func__, status);
1093 retStatus = VOS_STATUS_E_FAILURE;
1094 return retStatus;
1095 }
1096 }
1097 else
1098 {
1099 hddLog(VOS_TRACE_LEVEL_WARN,
1100 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1101 }
1102
1103 return retStatus;
1104}
1105
1106/**---------------------------------------------------------------------------
1107
1108 \brief hdd_cfg80211_get_ibss_peer_info() -
1109
1110 Request function to get IBSS peer info from lower layers
1111
1112 \pAdapter -> Adapter context
1113 \staIdx -> Sta index for which the peer info is requested
1114
1115 \return - 0 for success non-zero for failure
1116 --------------------------------------------------------------------------*/
1117static VOS_STATUS
1118hdd_cfg80211_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx)
1119{
1120 long status;
1121 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1122 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1123
1124 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1125
1126 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1127 hdd_cfg80211_get_ibss_peer_info_cb,
1128 VOS_FALSE, staIdx);
1129
1130 if (VOS_STATUS_SUCCESS == retStatus)
1131 {
1132 status = wait_for_completion_interruptible_timeout
1133 (&pAdapter->ibss_peer_info_comp,
1134 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1135
1136 /* status = 0 on timeout */
1137 if (status <= 0)
1138 {
1139 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1140 __func__, status);
1141 retStatus = VOS_STATUS_E_FAILURE;
1142 return retStatus;
1143 }
1144 }
1145 else
1146 {
1147 hddLog(VOS_TRACE_LEVEL_WARN,
1148 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1149 }
1150
1151 return retStatus;
1152}
1153
1154/* Function header left blank Intentionally */
1155VOS_STATUS
1156hdd_parse_get_ibss_peer_info(tANI_U8 *pValue, v_MACADDR_t *pPeerMacAddr)
1157{
1158 tANI_U8 *inPtr = pValue;
1159 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1160
1161 /*no argument after the command*/
1162 if (NULL == inPtr)
1163 {
1164 return VOS_STATUS_E_FAILURE;;
1165 }
1166
1167 /*no space after the command*/
1168 else if (SPACE_ASCII_VALUE != *inPtr)
1169 {
1170 return VOS_STATUS_E_FAILURE;;
1171 }
1172
1173 /*removing empty spaces*/
1174 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
1175
1176 /*no argument followed by spaces*/
1177 if ('\0' == *inPtr)
1178 {
1179 return VOS_STATUS_E_FAILURE;;
1180 }
1181
1182 /*getting the first argument ie the peer mac address */
1183 if (inPtr[2] != ':' || inPtr[5] != ':' || inPtr[8] != ':' ||
1184 inPtr[11] != ':' || inPtr[14] != ':')
1185 {
1186 return VOS_STATUS_E_FAILURE;;
1187 }
1188 sscanf(inPtr, "%2x:%2x:%2x:%2x:%2x:%2x",
1189 (unsigned int *)&pPeerMacAddr->bytes[0],
1190 (unsigned int *)&pPeerMacAddr->bytes[1],
1191 (unsigned int *)&pPeerMacAddr->bytes[2],
1192 (unsigned int *)&pPeerMacAddr->bytes[3],
1193 (unsigned int *)&pPeerMacAddr->bytes[4],
1194 (unsigned int *)&pPeerMacAddr->bytes[5]);
1195
1196 /* The command buffer seems to be fine */
1197 return VOS_STATUS_SUCCESS;
1198}
1199
1200/* Function header left blank Intentionally */
1201static int hdd_parse_set_ibss_oui_data_command(tANI_U8 *command, tANI_U8 *ie,
1202 tANI_U32 limit)
1203{
1204 tANI_U8 len;
1205 tANI_U8 data;
1206
1207 /* skip white space */
1208 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1209 {
1210 command++;
1211 limit--;
1212 }
1213
1214 /* skip element id and element length */
1215 len = 2;
1216
1217 /* extract oui */
1218 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1219 (limit > 1))
1220 {
1221 /* Convert ASCII to decimal */
1222 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1223 ie[len++] = data;
1224 command += 2;
1225 limit -= 2;
1226 }
1227
1228 /* skip white space */
1229 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1230 {
1231 command++;
1232 limit--;
1233 }
1234
1235 /* extract data */
1236 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1237 (limit > 1))
1238 {
1239 /* Convert ASCII to decimal */
1240 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1241 ie[len++] = data;
1242 command += 2;
1243 limit -= 2;
1244 }
1245
1246 /* fill element id and element length */
1247 ie[0] = IE_EID_VENDOR;
1248 ie[1] = len - 2;
1249
1250 return len;
1251}
1252
1253static tANI_U32 hdd_find_ibss_wpa_ie_pos(tANI_U8 *addIePtr, tANI_U32 addIeLen)
1254{
1255 tANI_U32 ieLenPresent = 0;
1256 int left = addIeLen;
1257 v_U8_t *ptr = addIePtr;
1258 v_U8_t elem_id,elem_len;
1259
1260 while(left >= 2)
1261 {
1262 elem_id = ptr[0];
1263 elem_len = ptr[1];
1264 left -= 2;
1265 if(elem_len > left)
1266 {
1267 hddLog(LOGE,
1268 FL("****Invalid elem_len=%d left=%d*****"),
1269 elem_len,left);
1270 return 0;
1271 }
1272 if ((elem_id == IE_EID_VENDOR) &&
1273 (left >= WPA_OUI_TYPE_SIZE))
1274 {
1275 if (!memcmp(&ptr[2], WPA_OUI_TYPE,
1276 WPA_OUI_TYPE_SIZE))
1277 {
1278 ieLenPresent += elem_len + 2;
1279 return ieLenPresent;
1280 }
1281 }
1282 ieLenPresent += (elem_len + 2);
1283 left -= elem_len;
1284 ptr += (elem_len + 2);
1285 }
1286 return 0;
1287}
1288
1289#endif /* WLAN_FEATURE_RMC */
1290
Rajeev79dbe4c2013-10-05 11:03:42 +05301291#ifdef FEATURE_WLAN_BATCH_SCAN
1292
1293/**---------------------------------------------------------------------------
1294
1295 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
1296 input string
1297
1298 This function extracts assigned integer from string in below format:
1299 "STRING=10" : extracts integer 10 from this string
1300
1301 \param - pInPtr Pointer to input string
1302 \param - base Base for string to int conversion(10 for decimal 16 for hex)
1303 \param - pOutPtr Pointer to variable in which extracted integer needs to be
1304 assigned
1305 \param - pLastArg to tell whether it is last arguement in input string or
1306 not
1307
1308 \return - NULL for failure cases
1309 pointer to next arguement in input string for success cases
1310 --------------------------------------------------------------------------*/
1311static tANI_U8 *
1312hdd_extract_assigned_int_from_str
1313(
1314 tANI_U8 *pInPtr,
1315 tANI_U8 base,
1316 tANI_U32 *pOutPtr,
1317 tANI_U8 *pLastArg
1318)
1319{
1320 int tempInt;
1321 int v = 0;
1322 char buf[32];
1323 int val = 0;
1324 *pLastArg = FALSE;
1325
1326 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1327 if (NULL == pInPtr)
1328 {
1329 return NULL;
1330 }
1331
1332 pInPtr++;
1333
1334 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1335
1336 val = sscanf(pInPtr, "%32s ", buf);
1337 if (val < 0 && val > strlen(pInPtr))
1338 {
1339 return NULL;
1340 }
1341 pInPtr += val;
1342 v = kstrtos32(buf, base, &tempInt);
1343 if (v < 0)
1344 {
1345 return NULL;
1346 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -08001347 if (tempInt < 0)
1348 {
1349 tempInt = 0;
1350 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301351 *pOutPtr = tempInt;
1352
1353 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1354 if (NULL == pInPtr)
1355 {
1356 *pLastArg = TRUE;
1357 return NULL;
1358 }
1359 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1360
1361 return pInPtr;
1362}
1363
1364/**---------------------------------------------------------------------------
1365
1366 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
1367 input string
1368
1369 This function extracts assigned character from string in below format:
1370 "STRING=A" : extracts char 'A' from this string
1371
1372 \param - pInPtr Pointer to input string
1373 \param - pOutPtr Pointer to variable in which extracted char needs to be
1374 assigned
1375 \param - pLastArg to tell whether it is last arguement in input string or
1376 not
1377
1378 \return - NULL for failure cases
1379 pointer to next arguement in input string for success cases
1380 --------------------------------------------------------------------------*/
1381static tANI_U8 *
1382hdd_extract_assigned_char_from_str
1383(
1384 tANI_U8 *pInPtr,
1385 tANI_U8 *pOutPtr,
1386 tANI_U8 *pLastArg
1387)
1388{
1389 *pLastArg = FALSE;
1390
1391 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1392 if (NULL == pInPtr)
1393 {
1394 return NULL;
1395 }
1396
1397 pInPtr++;
1398
1399 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1400
1401 *pOutPtr = *pInPtr;
1402
1403 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1404 if (NULL == pInPtr)
1405 {
1406 *pLastArg = TRUE;
1407 return NULL;
1408 }
1409 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1410
1411 return pInPtr;
1412}
1413
1414
1415/**---------------------------------------------------------------------------
1416
1417 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
1418
1419 This function parses set batch scan command in below format:
1420 WLS_BATCHING_SET <space> followed by below arguements
1421 "SCANFREQ=XX" : Optional defaults to 30 sec
1422 "MSCAN=XX" : Required number of scans to attempt to batch
1423 "BESTN=XX" : Best Network (RSSI) defaults to 16
1424 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
1425 A. implies only 5 GHz , B. implies only 2.4GHz
1426 "RTT=X" : optional defaults to 0
1427 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
1428 error
1429
1430 For example input commands:
1431 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
1432 translated into set batch scan with following parameters:
1433 a) Frequence 60 seconds
1434 b) Batch 10 scans together
1435 c) Best RSSI to be 20
1436 d) 5GHz band only
1437 e) RTT is equal to 0
1438
1439 \param - pValue Pointer to input channel list
1440 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
1441
1442 \return - 0 for success non-zero for failure
1443
1444 --------------------------------------------------------------------------*/
1445static int
1446hdd_parse_set_batchscan_command
1447(
1448 tANI_U8 *pValue,
1449 tSirSetBatchScanReq *pHddSetBatchScanReq
1450)
1451{
1452 tANI_U8 *inPtr = pValue;
1453 tANI_U8 val = 0;
1454 tANI_U8 lastArg = 0;
Abhishek Singh00b71972016-01-07 10:51:04 +05301455 tANI_U32 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001456 tANI_U32 nMscan;
Abhishek Singh00b71972016-01-07 10:51:04 +05301457 tANI_U32 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
1458 tANI_U8 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1459 tANI_U32 nRtt = 0;
Rajeev Kumarc933d982013-11-18 20:04:20 -08001460 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +05301461
Rajeev79dbe4c2013-10-05 11:03:42 +05301462 /*go to space after WLS_BATCHING_SET command*/
1463 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1464 /*no argument after the command*/
1465 if (NULL == inPtr)
1466 {
1467 return -EINVAL;
1468 }
1469
1470 /*no space after the command*/
1471 else if (SPACE_ASCII_VALUE != *inPtr)
1472 {
1473 return -EINVAL;
1474 }
1475
1476 /*removing empty spaces*/
1477 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
1478
1479 /*no argument followed by spaces*/
1480 if ('\0' == *inPtr)
1481 {
1482 return -EINVAL;
1483 }
1484
1485 /*check and parse SCANFREQ*/
1486 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
1487 {
1488 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001489 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001490
Rajeev Kumarc933d982013-11-18 20:04:20 -08001491 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001492 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001493 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001494 }
1495
Rajeev79dbe4c2013-10-05 11:03:42 +05301496 if ( (NULL == inPtr) || (TRUE == lastArg))
1497 {
1498 return -EINVAL;
1499 }
1500 }
1501
1502 /*check and parse MSCAN*/
1503 if ((strncmp(inPtr, "MSCAN", 5) == 0))
1504 {
1505 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001506 &nMscan, &lastArg);
1507
1508 if (0 == nMscan)
1509 {
1510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1511 "invalid MSCAN=%d", nMscan);
1512 return -EINVAL;
1513 }
1514
Rajeev79dbe4c2013-10-05 11:03:42 +05301515 if (TRUE == lastArg)
1516 {
1517 goto done;
1518 }
1519 else if (NULL == inPtr)
1520 {
1521 return -EINVAL;
1522 }
1523 }
1524 else
1525 {
1526 return -EINVAL;
1527 }
1528
1529 /*check and parse BESTN*/
1530 if ((strncmp(inPtr, "BESTN", 5) == 0))
1531 {
1532 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001533 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001534
Rajeev Kumarc933d982013-11-18 20:04:20 -08001535 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001536 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001537 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001538 }
1539
Rajeev79dbe4c2013-10-05 11:03:42 +05301540 if (TRUE == lastArg)
1541 {
1542 goto done;
1543 }
1544 else if (NULL == inPtr)
1545 {
1546 return -EINVAL;
1547 }
1548 }
1549
1550 /*check and parse CHANNEL*/
1551 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
1552 {
1553 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -08001554
Rajeev79dbe4c2013-10-05 11:03:42 +05301555 if (('A' == val) || ('a' == val))
1556 {
c_hpothuebf89732014-02-25 13:00:24 +05301557 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301558 }
1559 else if (('B' == val) || ('b' == val))
1560 {
c_hpothuebf89732014-02-25 13:00:24 +05301561 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301562 }
1563 else
1564 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001565 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1566 }
1567
1568 if (TRUE == lastArg)
1569 {
1570 goto done;
1571 }
1572 else if (NULL == inPtr)
1573 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301574 return -EINVAL;
1575 }
1576 }
1577
1578 /*check and parse RTT*/
1579 if ((strncmp(inPtr, "RTT", 3) == 0))
1580 {
1581 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001582 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +05301583 if (TRUE == lastArg)
1584 {
1585 goto done;
1586 }
1587 if (NULL == inPtr)
1588 {
1589 return -EINVAL;
1590 }
1591 }
1592
1593
1594done:
1595
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001596 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1597 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1598 pHddSetBatchScanReq->bestNetwork = nBestN;
1599 pHddSetBatchScanReq->rfBand = ucRfBand;
1600 pHddSetBatchScanReq->rtt = nRtt;
1601
Rajeev79dbe4c2013-10-05 11:03:42 +05301602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1603 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1604 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1605 pHddSetBatchScanReq->scanFrequency,
1606 pHddSetBatchScanReq->numberOfScansToBatch,
1607 pHddSetBatchScanReq->bestNetwork,
1608 pHddSetBatchScanReq->rfBand,
1609 pHddSetBatchScanReq->rtt);
1610
1611 return 0;
1612}/*End of hdd_parse_set_batchscan_command*/
1613
1614/**---------------------------------------------------------------------------
1615
1616 \brief hdd_set_batch_scan_req_callback () - This function is called after
1617 receiving set batch scan response from FW and it saves set batch scan
1618 response data FW to HDD context and sets the completion event on
1619 which hdd_ioctl is waiting
1620
1621 \param - callbackContext Pointer to HDD adapter
1622 \param - pRsp Pointer to set batch scan response data received from FW
1623
1624 \return - nothing
1625
1626 --------------------------------------------------------------------------*/
1627static void hdd_set_batch_scan_req_callback
1628(
1629 void *callbackContext,
1630 tSirSetBatchScanRsp *pRsp
1631)
1632{
1633 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1634 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1635
1636 /*sanity check*/
1637 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1638 {
1639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1640 "%s: Invalid pAdapter magic", __func__);
1641 VOS_ASSERT(0);
1642 return;
1643 }
1644 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1645
1646 /*save set batch scan response*/
1647 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1648
1649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1650 "Received set batch scan rsp from FW with nScansToBatch=%d",
1651 pHddSetBatchScanRsp->nScansToBatch);
1652
1653 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1654 complete(&pAdapter->hdd_set_batch_scan_req_var);
1655
1656 return;
1657}/*End of hdd_set_batch_scan_req_callback*/
1658
1659
1660/**---------------------------------------------------------------------------
1661
1662 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1663 info in hdd batch scan response queue
1664
1665 \param - pAdapter Pointer to hdd adapter
1666 \param - pAPMetaInfo Pointer to access point meta info
1667 \param - scanId scan ID of batch scan response
1668 \param - isLastAp tells whether AP is last AP in batch scan response or not
1669
1670 \return - nothing
1671
1672 --------------------------------------------------------------------------*/
1673static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1674 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1675{
1676 tHddBatchScanRsp *pHead;
1677 tHddBatchScanRsp *pNode;
1678 tHddBatchScanRsp *pPrev;
1679 tHddBatchScanRsp *pTemp;
1680 tANI_U8 ssidLen;
1681
1682 /*head of hdd batch scan response queue*/
1683 pHead = pAdapter->pBatchScanRsp;
1684
1685 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1686 if (NULL == pNode)
1687 {
1688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1689 "%s: Could not allocate memory", __func__);
1690 VOS_ASSERT(0);
1691 return;
1692 }
1693
1694 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1695 sizeof(pNode->ApInfo.bssid));
1696 ssidLen = strlen(pApMetaInfo->ssid);
1697 if (SIR_MAX_SSID_SIZE < ssidLen)
1698 {
1699 /*invalid scan result*/
1700 vos_mem_free(pNode);
1701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1702 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1703 return;
1704 }
1705 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1706 /*null terminate ssid*/
1707 pNode->ApInfo.ssid[ssidLen] = '\0';
1708 pNode->ApInfo.ch = pApMetaInfo->ch;
1709 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1710 pNode->ApInfo.age = pApMetaInfo->timestamp;
1711 pNode->ApInfo.batchId = scanId;
1712 pNode->ApInfo.isLastAp = isLastAp;
1713
1714 pNode->pNext = NULL;
1715 if (NULL == pHead)
1716 {
1717 pAdapter->pBatchScanRsp = pNode;
1718 }
1719 else
1720 {
1721 pTemp = pHead;
1722 while (NULL != pTemp)
1723 {
1724 pPrev = pTemp;
1725 pTemp = pTemp->pNext;
1726 }
1727 pPrev->pNext = pNode;
1728 }
1729
1730 return;
1731}/*End of hdd_populate_batch_scan_rsp_queue*/
1732
1733/**---------------------------------------------------------------------------
1734
1735 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1736 receiving batch scan response indication from FW. It saves get batch scan
1737 response data in HDD batch scan response queue. This callback sets the
1738 completion event on which hdd_ioctl is waiting only after getting complete
1739 batch scan response data from FW
1740
1741 \param - callbackContext Pointer to HDD adapter
1742 \param - pRsp Pointer to get batch scan response data received from FW
1743
1744 \return - nothing
1745
1746 --------------------------------------------------------------------------*/
1747static void hdd_batch_scan_result_ind_callback
1748(
1749 void *callbackContext,
1750 void *pRsp
1751)
1752{
1753 v_BOOL_t isLastAp;
1754 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001755 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301756 tANI_U32 numberScanList;
1757 tANI_U32 nextScanListOffset;
1758 tANI_U32 nextApMetaInfoOffset;
1759 hdd_adapter_t* pAdapter;
1760 tpSirBatchScanList pScanList;
1761 tpSirBatchScanNetworkInfo pApMetaInfo;
1762 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1763 tSirSetBatchScanReq *pReq;
1764
1765 pAdapter = (hdd_adapter_t *)callbackContext;
1766 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001767 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301768 {
1769 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1770 "%s: Invalid pAdapter magic", __func__);
1771 VOS_ASSERT(0);
1772 return;
1773 }
1774
1775 /*initialize locals*/
1776 pReq = &pAdapter->hddSetBatchScanReq;
1777 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1778 isLastAp = FALSE;
1779 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001780 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301781 numberScanList = 0;
1782 nextScanListOffset = 0;
1783 nextApMetaInfoOffset = 0;
1784 pScanList = NULL;
1785 pApMetaInfo = NULL;
1786
1787 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1788 {
1789 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001790 "%s: pBatchScanRsp is %pK pReq %pK", __func__, pBatchScanRsp, pReq);
Rajeev79dbe4c2013-10-05 11:03:42 +05301791 isLastAp = TRUE;
1792 goto done;
1793 }
1794
1795 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1797 "Batch scan rsp: numberScalList %d", numberScanList);
1798
1799 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1800 {
1801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1802 "%s: numberScanList %d", __func__, numberScanList);
1803 isLastAp = TRUE;
1804 goto done;
1805 }
1806
1807 while (numberScanList)
1808 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001809 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301810 nextScanListOffset);
1811 if (NULL == pScanList)
1812 {
1813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001814 "%s: pScanList is %pK", __func__, pScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301815 isLastAp = TRUE;
1816 goto done;
1817 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001818 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001820 "Batch scan rsp: numApMetaInfo %d scanId %d",
1821 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301822
1823 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1824 {
1825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1826 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1827 isLastAp = TRUE;
1828 goto done;
1829 }
1830
Rajeev Kumarce651e42013-10-21 18:57:15 -07001831 /*Initialize next AP meta info offset for next scan list*/
1832 nextApMetaInfoOffset = 0;
1833
Rajeev79dbe4c2013-10-05 11:03:42 +05301834 while (numApMetaInfo)
1835 {
1836 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1837 nextApMetaInfoOffset);
1838 if (NULL == pApMetaInfo)
1839 {
1840 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001841 "%s: pApMetaInfo is %pK", __func__, pApMetaInfo);
Rajeev79dbe4c2013-10-05 11:03:42 +05301842 isLastAp = TRUE;
1843 goto done;
1844 }
1845 /*calculate AP age*/
1846 pApMetaInfo->timestamp =
1847 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1848
1849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001850 "%s: bssId "MAC_ADDRESS_STR
1851 " ch %d rssi %d timestamp %d", __func__,
1852 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1853 pApMetaInfo->ch, pApMetaInfo->rssi,
1854 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301855
1856 /*mark last AP in batch scan response*/
1857 if ((TRUE == pBatchScanRsp->isLastResult) &&
1858 (1 == numberScanList) && (1 == numApMetaInfo))
1859 {
1860 isLastAp = TRUE;
1861 }
1862
1863 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1864 /*store batch scan repsonse in hdd queue*/
1865 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1866 pScanList->scanId, isLastAp);
1867 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1868
1869 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1870 numApMetaInfo--;
1871 }
1872
Rajeev Kumarce651e42013-10-21 18:57:15 -07001873 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1874 + (sizeof(tSirBatchScanNetworkInfo)
1875 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301876 numberScanList--;
1877 }
1878
1879done:
1880
1881 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1882 requested from hdd_ioctl*/
1883 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1884 (TRUE == isLastAp))
1885 {
1886 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1887 complete(&pAdapter->hdd_get_batch_scan_req_var);
1888 }
1889
1890 return;
1891}/*End of hdd_batch_scan_result_ind_callback*/
1892
1893/**---------------------------------------------------------------------------
1894
1895 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1896 response as per batch scan FR request format by putting proper markers
1897
1898 \param - pDest pointer to destination buffer
1899 \param - cur_len current length
1900 \param - tot_len total remaining size which can be written to user space
1901 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1902 \param - pAdapter Pointer to HDD adapter
1903
1904 \return - ret no of characters written
1905
1906 --------------------------------------------------------------------------*/
1907static tANI_U32
1908hdd_format_batch_scan_rsp
1909(
1910 tANI_U8 *pDest,
1911 tANI_U32 cur_len,
1912 tANI_U32 tot_len,
1913 tHddBatchScanRsp *pApMetaInfo,
1914 hdd_adapter_t* pAdapter
1915)
1916{
1917 tANI_U32 ret = 0;
1918 tANI_U32 rem_len = 0;
1919 tANI_U8 temp_len = 0;
1920 tANI_U8 temp_total_len = 0;
1921 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1922 tANI_U8 *pTemp = temp;
1923
1924 /*Batch scan reponse needs to be returned to user space in
1925 following format:
1926 "scancount=X\n" where X is the number of scans in current batch
1927 batch
1928 "trunc\n" optional present if current scan truncated
1929 "bssid=XX:XX:XX:XX:XX:XX\n"
1930 "ssid=XXXX\n"
1931 "freq=X\n" frequency in Mhz
1932 "level=XX\n"
1933 "age=X\n" ms
1934 "dist=X\n" cm (-1 if not available)
1935 "errror=X\n" (-1if not available)
1936 "====\n" (end of ap marker)
1937 "####\n" (end of scan marker)
1938 "----\n" (end of results)*/
1939 /*send scan result in above format to user space based on
1940 available length*/
1941 /*The GET response may have more data than the driver can return in its
1942 buffer. In that case the buffer should be filled to the nearest complete
1943 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1944 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1945 The final buffer should end with "----\n"*/
1946
1947 /*sanity*/
1948 if (cur_len > tot_len)
1949 {
1950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1951 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1952 return 0;
1953 }
1954 else
1955 {
1956 rem_len = (tot_len - cur_len);
1957 }
1958
1959 /*end scan marker*/
1960 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1961 {
1962 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1963 pTemp += temp_len;
1964 temp_total_len += temp_len;
1965 }
1966
1967 /*bssid*/
1968 temp_len = snprintf(pTemp, sizeof(temp),
1969 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1970 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1971 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1972 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1973 pTemp += temp_len;
1974 temp_total_len += temp_len;
1975
1976 /*ssid*/
1977 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1978 pApMetaInfo->ApInfo.ssid);
1979 pTemp += temp_len;
1980 temp_total_len += temp_len;
1981
1982 /*freq*/
1983 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001984 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301985 pTemp += temp_len;
1986 temp_total_len += temp_len;
1987
1988 /*level*/
1989 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1990 pApMetaInfo->ApInfo.rssi);
1991 pTemp += temp_len;
1992 temp_total_len += temp_len;
1993
1994 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001995 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301996 pApMetaInfo->ApInfo.age);
1997 pTemp += temp_len;
1998 temp_total_len += temp_len;
1999
2000 /*dist*/
2001 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
2002 pTemp += temp_len;
2003 temp_total_len += temp_len;
2004
2005 /*error*/
2006 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
2007 pTemp += temp_len;
2008 temp_total_len += temp_len;
2009
2010 /*end AP marker*/
2011 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
2012 pTemp += temp_len;
2013 temp_total_len += temp_len;
2014
2015 /*last AP in batch scan response*/
2016 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
2017 {
2018 /*end scan marker*/
2019 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
2020 pTemp += temp_len;
2021 temp_total_len += temp_len;
2022
2023 /*end batch scan result marker*/
2024 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
2025 pTemp += temp_len;
2026 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002027
Rajeev79dbe4c2013-10-05 11:03:42 +05302028 }
2029
2030 if (temp_total_len < rem_len)
2031 {
2032 ret = temp_total_len + 1;
2033 strlcpy(pDest, temp, ret);
2034 pAdapter->isTruncated = FALSE;
2035 }
2036 else
2037 {
2038 pAdapter->isTruncated = TRUE;
2039 if (rem_len >= strlen("%%%%"))
2040 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08002041 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05302042 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08002043 else
Rajeev79dbe4c2013-10-05 11:03:42 +05302044 {
2045 ret = 0;
2046 }
2047 }
2048
2049 return ret;
2050
2051}/*End of hdd_format_batch_scan_rsp*/
2052
2053/**---------------------------------------------------------------------------
2054
2055 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
2056 buffer starting with head of hdd batch scan response queue
2057
2058 \param - pAdapter Pointer to HDD adapter
2059 \param - pDest Pointer to user data buffer
2060 \param - cur_len current offset in user buffer
2061 \param - rem_len remaining no of bytes in user buffer
2062
2063 \return - number of bytes written in user buffer
2064
2065 --------------------------------------------------------------------------*/
2066
2067tANI_U32 hdd_populate_user_batch_scan_rsp
2068(
2069 hdd_adapter_t* pAdapter,
2070 tANI_U8 *pDest,
2071 tANI_U32 cur_len,
2072 tANI_U32 rem_len
2073)
2074{
2075 tHddBatchScanRsp *pHead;
2076 tHddBatchScanRsp *pPrev;
2077 tANI_U32 len;
2078
Rajeev79dbe4c2013-10-05 11:03:42 +05302079 pAdapter->isTruncated = FALSE;
2080
2081 /*head of hdd batch scan response queue*/
2082 pHead = pAdapter->pBatchScanRsp;
2083 while (pHead)
2084 {
2085 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
2086 pAdapter);
2087 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07002088 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05302089 cur_len += len;
2090 if(TRUE == pAdapter->isTruncated)
2091 {
2092 /*result is truncated return rest of scan rsp in next req*/
2093 cur_len = rem_len;
2094 break;
2095 }
2096 pPrev = pHead;
2097 pHead = pHead->pNext;
2098 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08002099 if (TRUE == pPrev->ApInfo.isLastAp)
2100 {
2101 pAdapter->prev_batch_id = 0;
2102 }
2103 else
2104 {
2105 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
2106 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302107 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002108 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05302109 }
2110
2111 return cur_len;
2112}/*End of hdd_populate_user_batch_scan_rsp*/
2113
2114/**---------------------------------------------------------------------------
2115
2116 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
2117 scan response data from HDD queue to user space
2118 It does following in detail:
2119 a) if HDD has enough data in its queue then it 1st copies data to user
2120 space and then send get batch scan indication message to FW. In this
2121 case it does not wait on any event and batch scan response data will
2122 be populated in HDD response queue in MC thread context after receiving
2123 indication from FW
2124 b) else send get batch scan indication message to FW and wait on an event
2125 which will be set once HDD receives complete batch scan response from
2126 FW and then this function returns batch scan response to user space
2127
2128 \param - pAdapter Pointer to HDD adapter
2129 \param - pPrivData Pointer to priv_data
2130
2131 \return - 0 for success -EFAULT for failure
2132
2133 --------------------------------------------------------------------------*/
2134
2135int hdd_return_batch_scan_rsp_to_user
2136(
2137 hdd_adapter_t* pAdapter,
2138 hdd_priv_data_t *pPrivData,
2139 tANI_U8 *command
2140)
2141{
2142 tANI_U8 *pDest;
2143 tANI_U32 count = 0;
2144 tANI_U32 len = 0;
2145 tANI_U32 cur_len = 0;
2146 tANI_U32 rem_len = 0;
2147 eHalStatus halStatus;
2148 unsigned long rc;
2149 tSirTriggerBatchScanResultInd *pReq;
2150
2151 pReq = &pAdapter->hddTriggerBatchScanResultInd;
2152 pReq->param = 0;/*batch scan client*/
2153 pDest = (tANI_U8 *)(command + pPrivData->used_len);
2154 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
2155
2156 cur_len = pPrivData->used_len;
2157 if (pPrivData->total_len > pPrivData->used_len)
2158 {
2159 rem_len = pPrivData->total_len - pPrivData->used_len;
2160 }
2161 else
2162 {
2163 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2164 "%s: Invalid user data buffer total_len %d used_len %d",
2165 __func__, pPrivData->total_len, pPrivData->used_len);
2166 return -EFAULT;
2167 }
2168
2169 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2170 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2171 cur_len, rem_len);
2172 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2173
2174 /*enough scan result available in cache to return to user space or
2175 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08002176 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05302177 {
2178 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
2179 halStatus = sme_TriggerBatchScanResultInd(
2180 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2181 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
2182 pAdapter);
2183 if ( eHAL_STATUS_SUCCESS == halStatus )
2184 {
2185 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
2186 {
2187 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
2188 rc = wait_for_completion_timeout(
2189 &pAdapter->hdd_get_batch_scan_req_var,
2190 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
Abhishek Singh00b71972016-01-07 10:51:04 +05302191 if (0 >= rc)
Rajeev79dbe4c2013-10-05 11:03:42 +05302192 {
2193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Abhishek Singh00b71972016-01-07 10:51:04 +05302194 "%s: wait on hdd_get_batch_scan_req_var failed %ld",
2195 __func__, rc);
Rajeev79dbe4c2013-10-05 11:03:42 +05302196 return -EFAULT;
2197 }
2198 }
2199
2200 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07002201 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05302202 pDest += len;
2203 cur_len += len;
2204
2205 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2206 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2207 cur_len, rem_len);
2208 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2209
2210 count = 0;
2211 len = (len - pPrivData->used_len);
2212 pDest = (command + pPrivData->used_len);
2213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002214 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302215 while(count < len)
2216 {
2217 printk("%c", *(pDest + count));
2218 count++;
2219 }
2220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2221 "%s: copy %d data to user buffer", __func__, len);
2222 if (copy_to_user(pPrivData->buf, pDest, len))
2223 {
2224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2225 "%s: failed to copy data to user buffer", __func__);
2226 return -EFAULT;
2227 }
2228 }
2229 else
2230 {
2231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2232 "sme_GetBatchScanScan returned failure halStatus %d",
2233 halStatus);
2234 return -EINVAL;
2235 }
2236 }
2237 else
2238 {
Rajeev79dbe4c2013-10-05 11:03:42 +05302239 count = 0;
2240 len = (len - pPrivData->used_len);
2241 pDest = (command + pPrivData->used_len);
2242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002243 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302244 while(count < len)
2245 {
2246 printk("%c", *(pDest + count));
2247 count++;
2248 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08002249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2250 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05302251 if (copy_to_user(pPrivData->buf, pDest, len))
2252 {
2253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2254 "%s: failed to copy data to user buffer", __func__);
2255 return -EFAULT;
2256 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302257 }
2258
2259 return 0;
2260} /*End of hdd_return_batch_scan_rsp_to_user*/
2261
Rajeev Kumar8b373292014-01-08 20:36:55 -08002262/**---------------------------------------------------------------------------
2263
2264 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
2265 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
2266 WLS_BATCHING VERSION
2267 WLS_BATCHING SET
2268 WLS_BATCHING GET
2269 WLS_BATCHING STOP
2270
2271 \param - pAdapter Pointer to HDD adapter
2272 \param - pPrivdata Pointer to priv_data
2273 \param - command Pointer to command
2274
2275 \return - 0 for success -EFAULT for failure
2276
2277 --------------------------------------------------------------------------*/
2278
2279int hdd_handle_batch_scan_ioctl
2280(
2281 hdd_adapter_t *pAdapter,
2282 hdd_priv_data_t *pPrivdata,
2283 tANI_U8 *command
2284)
2285{
2286 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08002287 hdd_context_t *pHddCtx;
2288
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302289 ENTER();
2290
Yue Mae36e3552014-03-05 17:06:20 -08002291 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2292 ret = wlan_hdd_validate_context(pHddCtx);
2293 if (ret)
2294 {
Yue Mae36e3552014-03-05 17:06:20 -08002295 goto exit;
2296 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002297
2298 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
2299 {
2300 char extra[32];
2301 tANI_U8 len = 0;
2302 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
2303
2304 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2305 {
2306 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2307 "%s: Batch scan feature is not supported by FW", __func__);
2308 ret = -EINVAL;
2309 goto exit;
2310 }
2311
2312 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
2313 version);
2314 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2315 {
2316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2317 "%s: failed to copy data to user buffer", __func__);
2318 ret = -EFAULT;
2319 goto exit;
2320 }
2321 ret = HDD_BATCH_SCAN_VERSION;
2322 }
2323 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
2324 {
2325 int status;
2326 tANI_U8 *value = (command + 16);
2327 eHalStatus halStatus;
2328 unsigned long rc;
2329 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
2330 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
2331
2332 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2333 {
2334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2335 "%s: Batch scan feature is not supported by FW", __func__);
2336 ret = -EINVAL;
2337 goto exit;
2338 }
2339
2340 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
2341 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
2342 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
2343 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
2344 {
2345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302346 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08002347 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302348 hdd_device_modetoString(pAdapter->device_mode),
2349 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002350 ret = -EINVAL;
2351 goto exit;
2352 }
2353
2354 status = hdd_parse_set_batchscan_command(value, pReq);
2355 if (status)
2356 {
2357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2358 "Invalid WLS_BATCHING SET command");
2359 ret = -EINVAL;
2360 goto exit;
2361 }
2362
2363
2364 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
2365 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2366 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
2367 pAdapter);
2368
2369 if ( eHAL_STATUS_SUCCESS == halStatus )
2370 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302371 char extra[32];
2372 tANI_U8 len = 0;
2373 tANI_U8 mScan = 0;
2374
Rajeev Kumar8b373292014-01-08 20:36:55 -08002375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2376 "sme_SetBatchScanReq returned success halStatus %d",
2377 halStatus);
2378 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
2379 {
2380 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
2381 rc = wait_for_completion_timeout(
2382 &pAdapter->hdd_set_batch_scan_req_var,
2383 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
2384 if (0 == rc)
2385 {
2386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2387 "%s: Timeout waiting for set batch scan to complete",
2388 __func__);
2389 ret = -EINVAL;
2390 goto exit;
2391 }
2392 }
2393 if ( !pRsp->nScansToBatch )
2394 {
2395 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2396 "%s: Received set batch scan failure response from FW",
2397 __func__);
2398 ret = -EINVAL;
2399 goto exit;
2400 }
2401 /*As per the Batch Scan Framework API we should return the MIN of
2402 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302403 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002404
2405 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
2406
2407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2408 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302409 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
2410 len = scnprintf(extra, sizeof(extra), "%d", mScan);
2411 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2412 {
2413 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2414 "%s: failed to copy MSCAN value to user buffer", __func__);
2415 ret = -EFAULT;
2416 goto exit;
2417 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002418 }
2419 else
2420 {
2421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2422 "sme_SetBatchScanReq returned failure halStatus %d",
2423 halStatus);
2424 ret = -EINVAL;
2425 goto exit;
2426 }
2427 }
2428 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
2429 {
2430 eHalStatus halStatus;
2431 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
2432 pInd->param = 0;
2433
2434 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2435 {
2436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2437 "%s: Batch scan feature is not supported by FW", __func__);
2438 ret = -EINVAL;
2439 goto exit;
2440 }
2441
2442 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2443 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302444 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002445 "Batch scan is not yet enabled batch scan state %d",
2446 pAdapter->batchScanState);
2447 ret = -EINVAL;
2448 goto exit;
2449 }
2450
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002451 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2452 hdd_deinit_batch_scan(pAdapter);
2453 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2454
Rajeev Kumar8b373292014-01-08 20:36:55 -08002455 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
2456
2457 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
2458 pAdapter->sessionId);
2459 if ( eHAL_STATUS_SUCCESS == halStatus )
2460 {
2461 ret = 0;
2462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2463 "sme_StopBatchScanInd returned success halStatus %d",
2464 halStatus);
2465 }
2466 else
2467 {
2468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2469 "sme_StopBatchScanInd returned failure halStatus %d",
2470 halStatus);
2471 ret = -EINVAL;
2472 goto exit;
2473 }
2474 }
2475 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
2476 {
2477 tANI_U32 remain_len;
2478
2479 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2480 {
2481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2482 "%s: Batch scan feature is not supported by FW", __func__);
2483 ret = -EINVAL;
2484 goto exit;
2485 }
2486
2487 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2488 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002490 "Batch scan is not yet enabled could not return results"
2491 "Batch Scan state %d",
2492 pAdapter->batchScanState);
2493 ret = -EINVAL;
2494 goto exit;
2495 }
2496
2497 pPrivdata->used_len = 16;
2498 remain_len = pPrivdata->total_len - pPrivdata->used_len;
2499 if (remain_len < pPrivdata->total_len)
2500 {
2501 /*Clear previous batch scan response data if any*/
2502 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
2503 }
2504 else
2505 {
2506 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2507 "Invalid total length from user space can't fetch batch"
2508 " scan response total_len %d used_len %d remain len %d",
2509 pPrivdata->total_len, pPrivdata->used_len, remain_len);
2510 ret = -EINVAL;
2511 goto exit;
2512 }
2513 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
2514 }
2515
2516exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302517 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08002518 return ret;
2519}
2520
2521
Rajeev79dbe4c2013-10-05 11:03:42 +05302522#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
2523
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302524#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
2525/**
2526 * hdd_assign_handoff_src_reassoc - Set handoff source as REASSOC
2527 * to Handoff request
2528 * @handoffInfo: Pointer to Handoff request
2529 * @src: enum of handoff_src
2530 * Return: None
2531 */
2532#ifndef QCA_WIFI_ISOC
2533static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2534 *handoffInfo, handoff_src src)
2535{
2536 handoffInfo->src = src;
2537}
2538#else
2539static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2540 *handoffInfo, handoff_src src)
2541{
2542}
2543#endif
2544
2545/**
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302546 * hdd_reassoc() - perform a user space-directed reassoc
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302547 *
2548 * @pAdapter: Adapter upon which the command was received
2549 * @bssid: BSSID with which to reassociate
2550 * @channel: channel upon which to reassociate
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302551 * @src: The source for the trigger of this action
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302552 *
2553 * Return: 0 for success non-zero for failure
2554 */
2555#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302556int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302557 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302558{
2559 hdd_station_ctx_t *pHddStaCtx;
2560 tCsrHandoffRequest handoffInfo;
2561 hdd_context_t *pHddCtx = NULL;
2562 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2563
2564 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2565
2566 /* if not associated, no need to proceed with reassoc */
2567 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2568 hddLog(LOG1, FL("Not associated"));
2569 return -EINVAL;
2570 }
2571
2572 /* if the target bssid is same as currently associated AP,
2573 then no need to proceed with reassoc */
2574 if (!memcmp(bssid, pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr))) {
2575 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
2576 return -EINVAL;
2577 }
2578
2579 /* Check channel number is a valid channel number */
2580 if (VOS_STATUS_SUCCESS !=
2581 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
2582 hddLog(LOGE, FL("Invalid Channel %d"), channel);
2583 return -EINVAL;
2584 }
2585
2586 /* Proceed with reassoc */
2587 handoffInfo.channel = channel;
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302588 hdd_assign_handoff_src_reassoc(&handoffInfo, src);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302589 memcpy(handoffInfo.bssid, bssid, sizeof(tSirMacAddr));
2590 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
2591 return 0;
2592}
2593#else
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302594int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302595 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302596{
2597 return -EPERM;
2598}
2599#endif
2600
2601/**
2602 * hdd_parse_reassoc_v1() - parse version 1 of the REASSOC command
2603 * This function parses the v1 REASSOC command with the format
2604 * REASSOC xx:xx:xx:xx:xx:xx CH where "xx:xx:xx:xx:xx:xx" is the
2605 * Hex-ASCII representation of the BSSID and CH is the ASCII
2606 * representation of the channel. For example
2607 * REASSOC 00:0a:0b:11:22:33 48
2608 *
2609 * @pAdapter: Adapter upon which the command was received
2610 * @command: ASCII text command that was received
2611 *
2612 * Return: 0 for success non-zero for failure
2613 */
2614static int
2615hdd_parse_reassoc_v1(hdd_adapter_t *pAdapter, const char *command)
2616{
2617 tANI_U8 channel = 0;
2618 tSirMacAddr bssid;
2619 int ret;
2620
2621 ret = hdd_parse_reassoc_command_v1_data(command, bssid, &channel);
2622 if (ret)
2623 hddLog(LOGE, FL("Failed to parse reassoc command data"));
2624 else
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302625 ret = hdd_reassoc(pAdapter, bssid, channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302626
2627 return ret;
2628}
2629
2630/**
2631 * hdd_parse_reassoc_v2() - parse version 2 of the REASSOC command
2632 * This function parses the v2 REASSOC command with the format
2633 * REASSOC <android_wifi_reassoc_params>
2634 *
2635 * @pAdapter: Adapter upon which the command was received
2636 * @command: command that was received, ASCII command followed
2637 * by binary data
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302638 * @total_len: Total length of the command received
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302639 *
2640 * Return: 0 for success non-zero for failure
2641 */
2642static int
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302643hdd_parse_reassoc_v2(hdd_adapter_t *pAdapter, const char *command,
2644 int total_len)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302645{
2646 struct android_wifi_reassoc_params params;
2647 tSirMacAddr bssid;
2648 int ret;
2649
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302650 if (total_len < sizeof(params) + 8) {
2651 hddLog(LOGE, FL("Invalid command length"));
2652 return -EINVAL;
2653 }
2654
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302655 /* The params are located after "REASSOC " */
2656 memcpy(&params, command + 8, sizeof(params));
2657
2658 if (!mac_pton(params.bssid, (u8 *)&bssid)) {
2659 hddLog(LOGE, FL("MAC address parsing failed"));
2660 ret = -EINVAL;
2661 } else {
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302662 ret = hdd_reassoc(pAdapter, bssid, params.channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302663 }
2664 return ret;
2665}
2666
2667/**
2668 * hdd_parse_reassoc() - parse the REASSOC command
2669 * There are two different versions of the REASSOC command.Version 1
2670 * of the command contains a parameter list that is ASCII characters
2671 * whereas version 2 contains a combination of ASCII and binary
2672 * payload. Determine if a version 1 or a version 2 command is being
2673 * parsed by examining the parameters, and then dispatch the parser
2674 * that is appropriate for the command.
2675 *
2676 * @pAdapter: Adapter upon which the command was received
2677 * @command: command that was received
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302678 * @total_len: Total length of the command received
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302679 *
2680 * Return: 0 for success non-zero for failure
2681 */
2682static int
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302683hdd_parse_reassoc(hdd_adapter_t *pAdapter, const char *command, int total_len)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302684{
2685 int ret;
2686
2687 /*
2688 * both versions start with "REASSOC"
2689 * v1 has a bssid and channel # as an ASCII string
2690 * REASSOC xx:xx:xx:xx:xx:xx CH
2691 * v2 has a C struct
2692 * REASSOC <binary c struct>
2693 *
2694 * The first field in the v2 struct is also the bssid in ASCII.
2695 * But in the case of a v2 message the BSSID is NUL-terminated.
2696 * Hence we can peek at that offset to see if this is V1 or V2
2697 * REASSOC xx:xx:xx:xx:xx:xx*
2698 * 1111111111222222
2699 * 01234567890123456789012345
2700 */
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302701
2702 if (total_len < 26) {
2703 hddLog(LOGE, FL("Invalid command (total_len=%d)"), total_len);
2704 return -EINVAL;
2705 }
2706
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302707 if (command[25])
2708 ret = hdd_parse_reassoc_v1(pAdapter, command);
2709 else
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302710 ret = hdd_parse_reassoc_v2(pAdapter, command, total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302711
2712 return ret;
2713}
2714#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE FEATURE_WLAN_LFR */
2715
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302716struct bcn_miss_rate_priv {
2717 int bcn_miss_rate;
2718};
2719
2720/**
2721 * get_bcn_miss_rate_cb() callback invoked on receiving beacon miss
2722 * rate from firmware
2723 * @status: Status of get beacon miss rate operation
2724 * @bcnMissRate: Beacon miss rate
2725 * @context: Context passed while registering callback
2726 *
2727 * This function is invoked by WDA layer on receiving
2728 * WDI_GET_BCN_MISS_RATE_RSP
2729 *
2730 * Return: None
2731 */
2732static void get_bcn_miss_rate_cb(VOS_STATUS status, int bcnMissRate,
2733 void *context)
c_hpothu92367912014-05-01 15:18:17 +05302734{
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302735 struct hdd_request *request;
2736 struct bcn_miss_rate_priv *priv;
c_hpothu39eb1e32014-06-26 16:31:50 +05302737
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302738 request = hdd_request_get(context);
2739 if (!request) {
2740 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
2741 return;
2742 }
c_hpothu92367912014-05-01 15:18:17 +05302743
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302744 priv = hdd_request_priv(request);
c_hpothu92367912014-05-01 15:18:17 +05302745
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302746 if (VOS_STATUS_SUCCESS == status)
2747 priv->bcn_miss_rate = bcnMissRate;
2748 else
2749 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
c_hpothu92367912014-05-01 15:18:17 +05302750
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302751 hdd_request_complete(request);
2752 hdd_request_put(request);
Hanumanth Reddy Pothulad0d3c172018-05-02 18:53:05 +05302753
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302754 return;
c_hpothu92367912014-05-01 15:18:17 +05302755}
2756
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302757struct fw_stats_priv {
2758 tSirFwStatsResult *fw_stats;
2759};
2760
2761/**
2762 * hdd_fw_stats_cb() callback invoked on receiving firmware stats
2763 * from firmware
2764 * @status: Status of get firmware stats operation
2765 * @fwStatsResult: firmware stats
2766 * @context: Context passed while registering callback
2767 *
2768 * This function is invoked by WDA layer on receiving
2769 * WDI_GET_FW_STATS_RSP
2770 *
2771 * Return: None
2772 */
2773static void hdd_fw_stats_cb(VOS_STATUS status,
2774 tSirFwStatsResult *fwStatsResult, void *context)
Satyanarayana Dash72806012014-12-02 14:30:08 +05302775{
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302776 struct hdd_request *request;
2777 struct fw_stats_priv *priv;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302778
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302779 hddLog(VOS_TRACE_LEVEL_INFO, FL("with status = %d"),status);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302780
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302781 request = hdd_request_get(context);
2782 if (!request) {
2783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
2784 return;
2785 }
2786 priv = hdd_request_priv(request);
2787
2788 if (VOS_STATUS_SUCCESS == status)
2789 *priv->fw_stats = *fwStatsResult;
2790 else
2791 priv->fw_stats = NULL;
2792
2793 hdd_request_complete(request);
2794 hdd_request_put(request);
2795 return;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302796}
2797
jge35567202017-06-21 16:39:38 +08002798/*
2799 *hdd_parse_setmaxtxpower_command() - HDD Parse MAXTXPOWER command
2800 *@pValue Pointer to MAXTXPOWER command
2801 *@pTxPower Pointer to tx power
2802 *
2803 *This function parses the MAXTXPOWER command passed in the format
2804 * MAXTXPOWER<space>X(Tx power in dbm)
2805 * For example input commands:
2806 * 1) MAXTXPOWER -8 -> This is translated into set max TX power to -8 dbm
2807 * 2) MAXTXPOWER -23 -> This is translated into set max TX power to -23 dbm
2808 *
2809 *return - 0 for success non-zero for failure
2810 */
2811static int hdd_parse_setmaxtxpower_command(unsigned char *pValue, int *pTxPower)
2812{
2813 unsigned char *inPtr = pValue;
2814 int tempInt;
2815 int v = 0;
2816 *pTxPower = 0;
2817
2818 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
2819 /* no argument after the command */
2820 if (NULL == inPtr)
2821 return -EINVAL;
2822 /* no space after the command */
2823 else if (SPACE_ASCII_VALUE != *inPtr)
2824 return -EINVAL;
2825
2826 /* removing empty spaces */
2827 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
2828
2829 /* no argument followed by spaces */
2830 if ('\0' == *inPtr)
2831 return 0;
2832
2833 v = kstrtos32(inPtr, 10, &tempInt);
2834
2835 /* Range checking for passed parameter */
2836 if ((tempInt < HDD_MIN_TX_POWER) || (tempInt > HDD_MAX_TX_POWER))
2837 return -EINVAL;
2838
2839 *pTxPower = tempInt;
2840
2841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2842 "SETMAXTXPOWER: %d", *pTxPower);
2843
2844 return 0;
2845}
2846
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302847static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2848{
2849 int ret = 0;
2850
2851 if (!pCfg || !command || !extra || !len)
2852 {
2853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2854 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2855 ret = -EINVAL;
2856 return ret;
2857 }
2858
2859 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2860 {
2861 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2862 (int)pCfg->nActiveMaxChnTime);
2863 return ret;
2864 }
2865 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2866 {
2867 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2868 (int)pCfg->nActiveMinChnTime);
2869 return ret;
2870 }
2871 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2872 {
2873 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2874 (int)pCfg->nPassiveMaxChnTime);
2875 return ret;
2876 }
2877 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2878 {
2879 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2880 (int)pCfg->nPassiveMinChnTime);
2881 return ret;
2882 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302883 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2884 {
2885 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2886 (int)pCfg->nActiveMaxChnTime);
2887 return ret;
2888 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302889 else
2890 {
2891 ret = -EINVAL;
2892 }
2893
2894 return ret;
2895}
2896
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05302897/**
2898 * hdd_btc_get_dwell_time() - Get BTC dwell time parameters
2899 * @pCfg: Pointer to HDD context
2900 * @command: ASCII text command that is received
2901 * @extra: Pointer to copy data sent to user
2902 * @n: size of 'extra' buffer
2903 * @len: length copied to 'extra' buffer
2904 *
2905 * Driver commands:
2906 * wpa_cli DRIVER BTCGETDWELLTIME ESCO MAX
2907 * wpa_cli DRIVER BTCGETDWELLTIME ESCO MIN
2908 * wpa_cli DRIVER BTCGETDWELLTIME SCO MAX
2909 * wpa_cli DRIVER BTCGETDWELLTIME SCO MIN
2910 *
2911 * Return: 0 for success non-zero for failure
2912 */
2913
2914static int hdd_btc_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command,
2915 char *extra, tANI_U8 n, tANI_U8 *len)
2916{
2917 int ret = 0;
2918
2919 if (!pCfg || !command || !extra || !len)
2920 {
2921 hddLog(LOGE, FL("Argument passsed for BTCGETDWELLTIME is incorrect"));
2922 ret = -EINVAL;
2923 return ret;
2924 }
2925
2926 if (strncmp(command, "BTCGETDWELLTIME ESCO MAX", 24) == 0)
2927 {
2928 *len = scnprintf(extra, n, "BTCGETDWELLTIME ESCO MAX %u\n",
2929 (int)pCfg->max_chntime_btc_esco);
2930 return ret;
2931 }
2932 else if (strncmp(command, "BTCGETDWELLTIME ESCO MIN", 24) == 0)
2933 {
2934 *len = scnprintf(extra, n, "BTCGETDWELLTIME ESCO MIN %u\n",
2935 (int)pCfg->min_chntime_btc_esco);
2936 return ret;
2937 }
2938 else if (strncmp(command, "BTCGETDWELLTIME SCO MAX", 23) == 0)
2939 {
2940 *len = scnprintf(extra, n, "BTCGETDWELLTIME SCO MAX %u\n",
2941 (int)pCfg->max_chntime_btc_sco);
2942 return ret;
2943 }
2944 else if (strncmp(command, "BTCGETDWELLTIME SCO MIN", 23) == 0)
2945 {
2946 *len = scnprintf(extra, n, "BTCGETDWELLTIME SCO MIN %u\n",
2947 (int)pCfg->min_chntime_btc_sco);
2948 return ret;
2949 }
2950 else
2951 {
2952 ret = -EINVAL;
2953 }
2954
2955 return ret;
2956}
2957
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302958int hdd_drv_cmd_validate(tANI_U8 *command, int len)
2959{
2960 if (command[len] != ' ')
2961 return -EINVAL;
2962
2963 return 0;
2964}
2965
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05302966#ifdef WLAN_AP_STA_CONCURRENCY
2967
2968/**
2969 * hdd_conc_get_dwell_time() - Get concurrency dwell time parameters
2970 * @pCfg: Pointer to HDD context
2971 * @command: ASCII text command that is received
2972 * @extra: Pointer to copy data sent to user
2973 * @n: size of 'extra' buffer
2974 * @len: length copied to 'extra' buffer
2975 *
2976 * Driver commands:
2977 * wpa_cli DRIVER CONCGETDWELLTIME ACTIVE MAX
2978 * wpa_cli DRIVER CONCGETDWELLTIME ACTIVE MIN
2979 * wpa_cli DRIVER CONCGETDWELLTIME PASSIVE MAX
2980 * wpa_cli DRIVER CONCGETDWELLTIME PASSIVE MIN
2981 *
2982 * Return: 0 for success non-zero for failure
2983 */
2984
2985static int hdd_conc_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command,
2986 char *extra, tANI_U8 n, tANI_U8 *len)
2987{
2988 int ret = 0;
2989
2990 if (!pCfg || !command || !extra || !len)
2991 {
2992 hddLog(LOGE, FL("Argument passsed for CONCGETDWELLTIME is incorrect"));
2993 ret = -EINVAL;
2994 return ret;
2995 }
2996
2997 if (strncmp(command, "CONCGETDWELLTIME ACTIVE MAX", 27) == 0)
2998 {
2999 *len = scnprintf(extra, n, "CONCGETDWELLTIME ACTIVE MAX %u\n",
3000 (int)pCfg->nActiveMaxChnTimeConc);
3001 return ret;
3002 }
3003 else if (strncmp(command, "CONCGETDWELLTIME ACTIVE MIN", 27) == 0)
3004 {
3005 *len = scnprintf(extra, n, "CONCGETDWELLTIME ACTIVE MIN %u\n",
3006 (int)pCfg->nActiveMinChnTimeConc);
3007 return ret;
3008 }
3009 else if (strncmp(command, "CONCGETDWELLTIME PASSIVE MAX", 28) == 0)
3010 {
3011 *len = scnprintf(extra, n, "CONCGETDWELLTIME PASSIVE MAX %u\n",
3012 (int)pCfg->nPassiveMaxChnTimeConc);
3013 return ret;
3014 }
3015 else if (strncmp(command, "CONCGETDWELLTIME PASSIVE MIN", 28) == 0)
3016 {
3017 *len = scnprintf(extra, n, "CONCGETDWELLTIME PASSIVE MIN %u\n",
3018 (int)pCfg->nPassiveMinChnTimeConc);
3019 return ret;
3020 }
3021 else
3022 {
3023 ret = -EINVAL;
3024 }
3025
3026 return ret;
3027}
3028
3029/**
3030 * hdd_conc_set_dwell_time() - Set concurrency dwell time parameters
3031 * @pAdapter: Adapter upon which the command was received
3032 * @command: ASCII text command that is received
3033 *
3034 * Driver commands:
3035 * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MAX <value>
3036 * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MIN <value>
3037 * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MAX <value
3038 * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MIN <value>
3039 *
3040 * Return: 0 for success non-zero for failure
3041 */
3042
3043static int hdd_conc_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3044{
3045 tHalHandle hHal;
3046 hdd_config_t *pCfg;
3047 tANI_U8 *value = command;
3048 int val = 0, ret = 0, temp = 0;
3049 tSmeConfigParams smeConfig;
3050
3051 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3052 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
3053 {
3054 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME is incorrect"));
3055 ret = -EINVAL;
3056 return ret;
3057 }
3058
3059 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3060 sme_GetConfigParam(hHal, &smeConfig);
3061
3062 if (strncmp(command, "CONCSETDWELLTIME ACTIVE MAX", 27) == 0 )
3063 {
3064 if (hdd_drv_cmd_validate(command, 27)) {
3065 hddLog(LOGE, FL("Invalid driver command"));
3066 return -EINVAL;
3067 }
3068
3069 value = value + 28;
3070 temp = kstrtou32(value, 10, &val);
3071 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MIN ||
3072 val > CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MAX)
3073 {
3074 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME ACTIVE MAX is incorrect"));
3075 ret = -EFAULT;
3076 return ret;
3077 }
3078 pCfg->nActiveMaxChnTimeConc = val;
3079 smeConfig.csrConfig.nActiveMaxChnTimeConc = val;
3080 sme_UpdateConfig(hHal, &smeConfig);
3081 }
3082 else if (strncmp(command, "CONCSETDWELLTIME ACTIVE MIN", 27) == 0)
3083 {
3084 if (hdd_drv_cmd_validate(command, 27)) {
3085 hddLog(LOGE, FL("Invalid driver command"));
3086 return -EINVAL;
3087 }
3088
3089 value = value + 28;
3090 temp = kstrtou32(value, 10, &val);
3091 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MIN ||
3092 val > CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MAX)
3093 {
3094 hddLog(LOGE, FL("Argument passsed for CONCSETDWELLTIME ACTIVE MIN is incorrect"));
3095 ret = -EFAULT;
3096 return ret;
3097 }
3098 pCfg->nActiveMinChnTimeConc = val;
3099 smeConfig.csrConfig.nActiveMinChnTimeConc = val;
3100 sme_UpdateConfig(hHal, &smeConfig);
3101 }
3102 else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MAX", 28) == 0)
3103 {
3104 if (hdd_drv_cmd_validate(command, 28)) {
3105 hddLog(LOGE, FL("Invalid driver command"));
3106 return -EINVAL;
3107 }
3108
3109 value = value + 29;
3110 temp = kstrtou32(value, 10, &val);
3111 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MIN ||
3112 val > CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MAX)
3113 {
3114 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME PASSIVE MAX is incorrect"));
3115 ret = -EFAULT;
3116 return ret;
3117 }
3118 pCfg->nPassiveMaxChnTimeConc = val;
3119 smeConfig.csrConfig.nPassiveMaxChnTimeConc = val;
3120 sme_UpdateConfig(hHal, &smeConfig);
3121 }
3122 else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MIN", 28) == 0)
3123 {
3124 if (hdd_drv_cmd_validate(command, 28)) {
3125 hddLog(LOGE, FL("Invalid driver command"));
3126 return -EINVAL;
3127 }
3128
3129 value = value + 29;
3130 temp = kstrtou32(value, 10, &val);
3131 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MIN ||
3132 val > CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MAX )
3133 {
3134 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME PASSIVE MIN is incorrect"));
3135 ret = -EFAULT;
3136 return ret;
3137 }
3138 pCfg->nPassiveMinChnTimeConc = val;
3139 smeConfig.csrConfig.nPassiveMinChnTimeConc = val;
3140 sme_UpdateConfig(hHal, &smeConfig);
3141 }
3142 else
3143 {
3144 ret = -EINVAL;
3145 }
3146
3147 return ret;
3148}
3149
3150#endif
3151
3152/**
3153 * hdd_btc_set_dwell_time() - Set BTC dwell time parameters
3154 * @pAdapter: Adapter upon which the command was received
3155 * @command: ASCII text command that is received
3156 *
3157 * Driver commands:
3158 * wpa_cli DRIVER BTCSETDWELLTIME ESCO MAX <value>
3159 * wpa_cli DRIVER BTCSETDWELLTIME ESCO MIN <value>
3160 * wpa_cli DRIVER BTCSETDWELLTIME SCO MAX <value>
3161 * wpa_cli DRIVER BTCSETDWELLTIME SCO MIN <value>
3162 *
3163 * Return: 0 for success non-zero for failure
3164 */
3165
3166static int hdd_btc_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3167{
3168 tHalHandle hHal;
3169 hdd_config_t *pCfg;
3170 tANI_U8 *value = command;
3171 int val = 0, ret = 0, temp = 0;
3172 tSmeConfigParams smeConfig;
3173
3174 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3175 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
3176 {
3177 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME is incorrect"));
3178 ret = -EINVAL;
3179 return ret;
3180 }
3181
3182 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3183 sme_GetConfigParam(hHal, &smeConfig);
3184
3185 if (strncmp(command, "BTCSETDWELLTIME ESCO MAX", 24) == 0)
3186 {
3187 if (hdd_drv_cmd_validate(command, 24)) {
3188 hddLog(LOGE, FL("Invalid driver command"));
3189 return -EINVAL;
3190 }
3191
3192 value = value + 25;
3193 temp = kstrtou32(value, 10, &val);
3194 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MIN ||
3195 val > CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MAX)
3196 {
3197 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME ESCO MAX is incorrect"));
3198 ret = -EFAULT;
3199 return ret;
3200 }
3201 pCfg->max_chntime_btc_esco = val;
3202 smeConfig.csrConfig.max_chntime_btc_esco = val;
3203 sme_UpdateConfig(hHal, &smeConfig);
3204 }
3205 else if (strncmp(command, "BTCSETDWELLTIME ESCO MIN", 24) == 0)
3206 {
3207 if (hdd_drv_cmd_validate(command, 24)) {
3208 hddLog(LOGE, FL("Invalid driver command"));
3209 return -EINVAL;
3210 }
3211
3212 value = value + 25;
3213 temp = kstrtou32(value, 10, &val);
3214 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MIN ||
3215 val > CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MAX)
3216 {
3217 hddLog(LOGE, FL("Argument passsed for BTCSETDWELLTIME ESCO MIN is incorrect"));
3218 ret = -EFAULT;
3219 return ret;
3220 }
3221 pCfg->min_chntime_btc_esco = val;
3222 smeConfig.csrConfig.min_chntime_btc_esco = val;
3223 sme_UpdateConfig(hHal, &smeConfig);
3224 }
3225 else if (strncmp(command, "BTCSETDWELLTIME SCO MAX", 23) == 0)
3226 {
3227 if (hdd_drv_cmd_validate(command, 23)) {
3228 hddLog(LOGE, FL("Invalid driver command"));
3229 return -EINVAL;
3230 }
3231
3232 value = value + 24;
3233 temp = kstrtou32(value, 10, &val);
3234 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MIN ||
3235 val > CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MAX)
3236 {
3237 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME SCO MAX is incorrect"));
3238 ret = -EFAULT;
3239 return ret;
3240 }
3241 pCfg->max_chntime_btc_sco = val;
3242 smeConfig.csrConfig.max_chntime_btc_sco = val;
3243 sme_UpdateConfig(hHal, &smeConfig);
3244 }
3245 else if (strncmp(command, "BTCSETDWELLTIME SCO MIN", 23) == 0)
3246 {
3247 if (hdd_drv_cmd_validate(command, 23)) {
3248 hddLog(LOGE, FL("Invalid driver command"));
3249 return -EINVAL;
3250 }
3251
3252 value = value + 24;
3253 temp = kstrtou32(value, 10, &val);
3254 if (temp != 0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MIN ||
3255 val > CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MAX)
3256 {
3257 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME SCO MIN is incorrect"));
3258 ret = -EFAULT;
3259 return ret;
3260 }
3261 pCfg->min_chntime_btc_sco = val;
3262 smeConfig.csrConfig.min_chntime_btc_sco = val;
3263 sme_UpdateConfig(hHal, &smeConfig);
3264 }
3265 else
3266 {
3267 ret = -EINVAL;
3268 }
3269
3270 return ret;
3271}
3272
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303273static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3274{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303275 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303276 hdd_config_t *pCfg;
3277 tANI_U8 *value = command;
3278 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303279 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303280
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303281 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3282 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303283 {
3284 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3285 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3286 ret = -EINVAL;
3287 return ret;
3288 }
3289
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303290 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3291 sme_GetConfigParam(hHal, &smeConfig);
3292
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303293 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
3294 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303295 if (hdd_drv_cmd_validate(command, 23))
3296 return -EINVAL;
3297
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303298 value = value + 24;
3299 temp = kstrtou32(value, 10, &val);
3300 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3301 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3302 {
3303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3304 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
3305 ret = -EFAULT;
3306 return ret;
3307 }
3308 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303309 smeConfig.csrConfig.nActiveMaxChnTime = val;
3310 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303311 }
3312 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
3313 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303314 if (hdd_drv_cmd_validate(command, 23))
3315 return -EINVAL;
3316
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303317 value = value + 24;
3318 temp = kstrtou32(value, 10, &val);
3319 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
3320 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
3321 {
3322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3323 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
3324 ret = -EFAULT;
3325 return ret;
3326 }
3327 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303328 smeConfig.csrConfig.nActiveMinChnTime = val;
3329 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303330 }
3331 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
3332 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303333 if (hdd_drv_cmd_validate(command, 24))
3334 return -EINVAL;
3335
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303336 value = value + 25;
3337 temp = kstrtou32(value, 10, &val);
3338 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
3339 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
3340 {
3341 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3342 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
3343 ret = -EFAULT;
3344 return ret;
3345 }
3346 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303347 smeConfig.csrConfig.nPassiveMaxChnTime = val;
3348 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303349 }
3350 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
3351 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303352 if (hdd_drv_cmd_validate(command, 24))
3353 return -EINVAL;
3354
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303355 value = value + 25;
3356 temp = kstrtou32(value, 10, &val);
3357 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
3358 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
3359 {
3360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3361 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
3362 ret = -EFAULT;
3363 return ret;
3364 }
3365 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303366 smeConfig.csrConfig.nPassiveMinChnTime = val;
3367 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303368 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05303369 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3370 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303371 if (hdd_drv_cmd_validate(command, 12))
3372 return -EINVAL;
3373
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05303374 value = value + 13;
3375 temp = kstrtou32(value, 10, &val);
3376 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3377 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3378 {
3379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3380 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3381 ret = -EFAULT;
3382 return ret;
3383 }
3384 pCfg->nActiveMaxChnTime = val;
3385 smeConfig.csrConfig.nActiveMaxChnTime = val;
3386 sme_UpdateConfig(hHal, &smeConfig);
3387 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303388 else
3389 {
3390 ret = -EINVAL;
3391 }
3392
3393 return ret;
3394}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303395static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
3396 tANI_U8 cmd_len)
3397{
3398 tANI_U8 *value;
3399 tANI_U8 fcc_constraint;
3400
3401 eHalStatus status;
3402 int ret = 0;
3403 value = cmd + cmd_len + 1;
3404
3405 ret = kstrtou8(value, 10, &fcc_constraint);
3406 if ((ret < 0) || (fcc_constraint > 1)) {
3407 /*
3408 * If the input value is greater than max value of datatype,
3409 * then also it is a failure
3410 */
3411 hddLog(VOS_TRACE_LEVEL_ERROR,
3412 "%s: value out of range", __func__);
3413 return -EINVAL;
3414 }
3415
Agrawal Ashish842eea82016-02-04 17:56:16 +05303416 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint,
3417 pHddCtx->scan_info.mScanPending);
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303418 if (status != eHAL_STATUS_SUCCESS)
3419 ret = -EPERM;
3420
3421 return ret;
3422}
3423
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05303424/**---------------------------------------------------------------------------
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303425
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05303426 \brief hdd_enable_disable_ca_event() - When Host sends IOCTL (enabled),
3427 FW will send *ONE* CA ind to Host(even though it is duplicate).
3428 When Host send IOCTL (disable), FW doesn't perform any action.
3429 Whenever any change in CA *and* WLAN is in SAP/P2P-GO mode, FW
3430 sends CA ind to host. (regard less of IOCTL status)
3431 \param - pHddCtx - HDD context
3432 \param - command - command received from framework
3433 \param - cmd_len - len of the command
3434
3435 \return - 0 on success, appropriate error values on failure.
3436
3437 --------------------------------------------------------------------------*/
3438int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, tANI_U8* command, tANI_U8 cmd_len)
3439{
3440 tANI_U8 set_value;
3441 int ret = 0;
3442 eHalStatus status;
3443
3444 ret = wlan_hdd_validate_context(pHddCtx);
3445 if (0 != ret)
3446 {
3447 ret = -EINVAL;
3448 goto exit;
3449 }
3450
3451 if (pHddCtx->cfg_ini->gOptimizeCAevent == 0)
3452 {
3453 hddLog(VOS_TRACE_LEVEL_ERROR, "Enable gOptimizeCAevent"
3454 " ini param to control channel avooidance indication");
3455 ret = 0;
3456 goto exit;
3457 }
3458
3459 set_value = command[cmd_len + 1] - '0';
3460 status = sme_enableDisableChanAvoidIndEvent(pHddCtx->hHal, set_value);
3461 if (status != eHAL_STATUS_SUCCESS)
3462 {
3463 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to send"
3464 " enableDisableChanAoidance command to SME\n", __func__);
3465 ret = -EINVAL;
3466 }
3467
3468exit:
3469 return ret;
3470}
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303471
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303472/**
3473 * wlan_hdd_fastreassoc_handoff_request() - Post Handoff request to SME
3474 * @pHddCtx: Pointer to the HDD context
3475 * @channel: channel to reassociate
3476 * @targetApBssid: Target AP/BSSID to reassociate
3477 *
3478 * Return: None
3479 */
3480#if defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) && !defined(QCA_WIFI_ISOC)
3481static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3482 uint8_t channel, tSirMacAddr targetApBssid)
3483{
3484 tCsrHandoffRequest handoffInfo;
3485 handoffInfo.channel = channel;
3486 handoffInfo.src = FASTREASSOC;
3487 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3488 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3489}
3490#else
3491static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3492 uint8_t channel, tSirMacAddr targetApBssid)
3493{
3494}
3495#endif
3496
3497/**
3498 * csr_fastroam_neighbor_ap_event() - Function to trigger scan/roam
3499 * @pAdapter: Pointer to HDD adapter
3500 * @channel: Channel to scan/roam
3501 * @targetApBssid: BSSID to roam
3502 *
3503 * Return: None
3504 */
3505#ifdef QCA_WIFI_ISOC
3506static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3507 uint8_t channel, tSirMacAddr targetApBssid)
3508{
3509 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3510 &targetApBssid[0], eSME_ROAM_TRIGGER_SCAN, channel);
3511}
3512#else
3513static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3514 uint8_t channel, tSirMacAddr targetApBssid)
3515{
3516}
3517#endif
3518
3519/**
3520 * wlan_hdd_handle_fastreassoc() - Handle fastreassoc command
3521 * @pAdapter: pointer to hdd adapter
3522 * @command: pointer to the command received
3523 *
3524 * Return: VOS_STATUS enum
3525 */
3526static VOS_STATUS wlan_hdd_handle_fastreassoc(hdd_adapter_t *pAdapter,
3527 uint8_t *command)
3528{
3529 tANI_U8 *value = command;
3530 tANI_U8 channel = 0;
3531 tSirMacAddr targetApBssid;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303532 hdd_station_ctx_t *pHddStaCtx = NULL;
3533 hdd_context_t *pHddCtx = NULL;
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303534 int ret;
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303535 tCsrRoamModifyProfileFields mod_profile_fields;
3536 uint32_t roam_id = 0;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303537 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3538 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3539
3540 /* if not associated, no need to proceed with reassoc */
3541 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
3542 hddLog(LOG1, FL("Not associated!"));
3543 return eHAL_STATUS_FAILURE;
3544 }
3545
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303546 ret = hdd_parse_reassoc_command_v1_data(value, targetApBssid, &channel);
3547 if (ret) {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303548 hddLog(LOGE, FL("Failed to parse reassoc command data"));
3549 return eHAL_STATUS_FAILURE;
3550 }
3551
3552 /* if the target bssid is same as currently associated AP,
3553 then no need to proceed with reassoc */
3554 if (vos_mem_compare(targetApBssid,
3555 pHddStaCtx->conn_info.bssId,
3556 sizeof(tSirMacAddr))) {
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303557 sme_GetModifyProfileFields(pHddCtx->hHal, pAdapter->sessionId,
3558 &mod_profile_fields);
3559 sme_RoamReassoc(pHddCtx->hHal, pAdapter->sessionId, NULL,
3560 mod_profile_fields, &roam_id, 1);
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303561 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303562 return eHAL_STATUS_SUCCESS;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303563 }
3564
3565 /* Check channel number is a valid channel number */
3566 if (VOS_STATUS_SUCCESS !=
3567 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
3568 hddLog(LOGE, FL("Invalid Channel [%d]"), channel);
3569 return eHAL_STATUS_FAILURE;
3570 }
3571
3572 /* Proceed with reassoc */
3573 wlan_hdd_fastreassoc_handoff_request(pHddCtx, channel, targetApBssid);
3574
3575 /* Proceed with scan/roam */
3576 csr_fastroam_neighbor_ap_event(pAdapter, channel, targetApBssid);
3577
3578 return eHAL_STATUS_SUCCESS;
3579}
3580
3581/**
3582 * hdd_assign_reassoc_handoff - Set handoff source as REASSOC
3583 * @handoffInfo: Pointer to the csr Handoff Request.
3584 *
3585 * Return: None
3586 */
3587#ifndef QCA_WIFI_ISOC
3588static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3589{
3590 handoffInfo->src = REASSOC;
3591}
3592#else
3593static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3594{
3595}
3596#endif
3597
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303598/**
3599 * wlan_hdd_free_cache_channels() - Free the cache channels list
3600 * @hdd_ctx: Pointer to HDD context
3601 *
3602 * Return: None
3603 */
3604
3605static void wlan_hdd_free_cache_channels(hdd_context_t *hdd_ctx)
3606{
Ashish Kumar Dhanotiya19803832018-05-24 19:05:48 +05303607 if(!hdd_ctx || !hdd_ctx->original_channels)
3608 return;
3609
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303610 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303611 hdd_ctx->original_channels->num_channels = 0;
3612 vos_mem_free(hdd_ctx->original_channels->channel_info);
3613 hdd_ctx->original_channels->channel_info = NULL;
3614 vos_mem_free(hdd_ctx->original_channels);
3615 hdd_ctx->original_channels = NULL;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303616 mutex_unlock(&hdd_ctx->cache_channel_lock);
3617}
3618
3619/**
3620 * hdd_alloc_chan_cache() - Allocate the memory to cache the channel
3621 * info for the channels received in command SET_DISABLE_CHANNEL_LIST
3622 * @hdd_ctx: Pointer to HDD context
3623 * @num_chan: Number of channels for which memory needs to
3624 * be allocated
3625 *
3626 * Return: 0 on success and error code on failure
3627 */
3628
3629int hdd_alloc_chan_cache(hdd_context_t *hdd_ctx, int num_chan)
3630{
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303631 hdd_ctx->original_channels =
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303632 vos_mem_malloc(sizeof(struct hdd_cache_channels));
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303633 if (!hdd_ctx->original_channels) {
3634 hddLog(VOS_TRACE_LEVEL_ERROR,
3635 "In %s, VOS_MALLOC_ERR", __func__);
3636 return -EINVAL;
3637 }
3638 hdd_ctx->original_channels->num_channels = num_chan;
3639 hdd_ctx->original_channels->channel_info =
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303640 vos_mem_malloc(num_chan *
3641 sizeof(struct hdd_cache_channel_info));
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303642 if (!hdd_ctx->original_channels->channel_info) {
3643 hddLog(VOS_TRACE_LEVEL_ERROR,
3644 "In %s, VOS_MALLOC_ERR", __func__);
3645 hdd_ctx->original_channels->num_channels = 0;
3646 vos_mem_free(hdd_ctx->original_channels);
3647 hdd_ctx->original_channels = NULL;
3648 return -ENOMEM;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303649 }
3650 return 0;
3651
3652}
3653
3654
3655int hdd_parse_disable_chan_cmd(hdd_adapter_t *adapter, tANI_U8 *ptr)
3656{
3657 v_PVOID_t pvosGCtx = vos_get_global_context(VOS_MODULE_ID_HDD, NULL);
3658 hdd_context_t *hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, pvosGCtx);
3659 tANI_U8 *param;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303660 int j, tempInt, ret = 0, i, num_channels;
3661 int parsed_channels[MAX_CHANNEL];
3662 bool is_command_repeated = false;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303663
3664 if (NULL == pvosGCtx) {
3665 hddLog(VOS_TRACE_LEVEL_FATAL,
3666 "VOS Global Context is NULL");
3667 return -EINVAL;
3668 }
3669
3670 if (NULL == hdd_ctx) {
3671 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
3672 return -EINVAL;
3673 }
3674
3675 param = strchr(ptr, ' ');
3676 /*no argument after the command*/
3677 if (NULL == param)
3678 return -EINVAL;
3679
3680 /*no space after the command*/
3681 else if (SPACE_ASCII_VALUE != *param)
3682 return -EINVAL;
3683
3684 param++;
3685
3686 /*removing empty spaces*/
3687 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3688 param++;
3689
3690 /*no argument followed by spaces*/
3691 if ('\0' == *param)
3692 return -EINVAL;
3693
3694 /*getting the first argument ie the number of channels*/
3695 if (sscanf(param, "%d ", &tempInt) != 1) {
3696 hddLog(VOS_TRACE_LEVEL_ERROR,
3697 "%s: Cannot get number of channels from input",
3698 __func__);
3699 return -EINVAL;
3700 }
3701
3702 if (tempInt < 0 || tempInt > MAX_CHANNEL) {
3703 hddLog(VOS_TRACE_LEVEL_ERROR,
3704 "%s: Invalid Number of channel received", __func__);
3705 return -EINVAL;
3706 }
3707
3708 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3709 "%s: Number of channel to disable are: %d",
3710 __func__, tempInt);
3711
3712 if (!tempInt) {
3713 if (!wlan_hdd_restore_channels(hdd_ctx)) {
3714 /*
3715 * Free the cache channels only when the command is
3716 * received with num channels as 0
3717 */
3718 wlan_hdd_free_cache_channels(hdd_ctx);
3719 }
3720 return 0;
3721 }
3722
3723 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303724 if (!hdd_ctx->original_channels) {
3725 if (hdd_alloc_chan_cache(hdd_ctx, tempInt)) {
3726 ret = -ENOMEM;
3727 goto mem_alloc_failed;
3728 }
3729 } else if (hdd_ctx->original_channels->num_channels != tempInt) {
3730 hddLog(VOS_TRACE_LEVEL_ERROR,
3731 "%s, Invalid No of channel provided in the list",
3732 __func__);
3733 ret = -EINVAL;
3734 is_command_repeated = true;
3735 goto parse_failed;
3736 } else {
3737 is_command_repeated = true;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303738 }
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303739
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303740 num_channels = tempInt;
3741
3742 for (j = 0; j < num_channels; j++) {
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303743 /*
3744 * param pointing to the beginning of first space
3745 * after number of channels
3746 */
3747 param = strpbrk(param, " ");
3748 /*no channel list after the number of channels argument*/
3749 if (NULL == param) {
3750 hddLog(VOS_TRACE_LEVEL_ERROR,
3751 "%s, Invalid No of channel provided in the list",
3752 __func__);
3753 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303754 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303755 }
3756
3757 param++;
3758
3759 /*removing empty space*/
3760 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3761 param++;
3762
3763 if ('\0' == *param) {
3764 hddLog(VOS_TRACE_LEVEL_ERROR,
3765 "%s, No channel is provided in the list",
3766 __func__);
3767 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303768 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303769
3770 }
3771
3772 if (sscanf(param, "%d ", &tempInt) != 1) {
3773 hddLog(VOS_TRACE_LEVEL_ERROR,
3774 "%s: Cannot read channel number",
3775 __func__);
3776 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303777 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303778
3779 }
3780
3781 if (!IS_CHANNEL_VALID(tempInt)) {
3782 hddLog(VOS_TRACE_LEVEL_ERROR,
3783 "%s: Invalid channel number received",
3784 __func__);
3785 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303786 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303787
3788 }
3789
3790 hddLog(VOS_TRACE_LEVEL_INFO, "%s: channel[%d] = %d", __func__,
3791 j, tempInt);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303792
3793 parsed_channels[j] = tempInt;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303794 }
3795
3796 /*extra arguments check*/
3797 param = strchr(param, ' ');
3798 if (NULL != param) {
3799 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3800 param++;
3801
3802 if ('\0' != *param) {
3803 hddLog(VOS_TRACE_LEVEL_ERROR,
3804 "%s: Invalid argument received", __func__);
3805 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303806 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303807 }
3808 }
3809
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303810 /*
3811 * If command is received first time, cache the channels to
3812 * be disabled else compare the channels received in the
3813 * command with the cached channels, if channel list matches
3814 * return success otherewise return failure.
3815 */
3816 if (!is_command_repeated)
3817 for (j = 0; j < num_channels; j++)
3818 hdd_ctx->original_channels->
3819 channel_info[j].channel_num =
3820 parsed_channels[j];
3821 else {
3822 for (i = 0; i < num_channels; i++) {
3823 for (j = 0; j < num_channels; j++)
3824 if (hdd_ctx->original_channels->
3825 channel_info[i].channel_num ==
3826 parsed_channels[j])
3827 break;
3828 if (j == num_channels) {
3829 ret = -EINVAL;
3830 goto parse_failed;
3831 }
3832 }
3833 ret = 0;
3834 }
3835
3836mem_alloc_failed:
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303837 mutex_unlock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya1cf97dd2019-03-11 16:59:25 +05303838 /* Disable the channels received in command SET_DISABLE_CHANNEL_LIST*/
3839 if (!is_command_repeated) {
3840 wlan_hdd_disable_channels(hdd_ctx);
3841 hdd_check_and_disconnect_sta_on_invalid_channel(hdd_ctx);
3842 }
3843
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303844 EXIT();
3845
3846 return ret;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303847
3848parse_failed:
3849 mutex_unlock(&hdd_ctx->cache_channel_lock);
3850 if (!is_command_repeated)
3851 wlan_hdd_free_cache_channels(hdd_ctx);
3852 EXIT();
3853 return ret;
3854
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303855}
3856
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303857int hdd_get_disable_ch_list(hdd_context_t *hdd_ctx, tANI_U8 *buf,
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303858 uint32_t buf_len)
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303859{
3860 struct hdd_cache_channel_info *ch_list;
3861 unsigned char i, num_ch;
3862 int len = 0;
3863
3864 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303865 if (hdd_ctx->original_channels &&
3866 hdd_ctx->original_channels->num_channels &&
3867 hdd_ctx->original_channels->channel_info) {
3868 num_ch = hdd_ctx->original_channels->num_channels;
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303869
3870 len = scnprintf(buf, buf_len, "%s %hhu",
3871 "GET_DISABLE_CHANNEL_LIST", num_ch);
3872
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303873 ch_list = hdd_ctx->original_channels->channel_info;
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303874
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303875 for (i = 0; (i < num_ch) && (len < buf_len-1); i++) {
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303876 len += scnprintf(buf + len, buf_len - len,
3877 " %d", ch_list[i].channel_num);
3878 }
3879 }
3880 mutex_unlock(&hdd_ctx->cache_channel_lock);
3881
3882 return len;
3883}
3884
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003885static int hdd_driver_command(hdd_adapter_t *pAdapter,
3886 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07003887{
Jeff Johnson295189b2012-06-20 16:38:30 -07003888 hdd_priv_data_t priv_data;
3889 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303890 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3891 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003892 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303893 int status;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303894#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3895 struct cfg80211_mgmt_tx_params params;
3896#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303897
3898 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003899 /*
3900 * Note that valid pointers are provided by caller
3901 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003902
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003903 /* copy to local struct to avoid numerous changes to legacy code */
3904 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07003905
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003906 if (priv_data.total_len <= 0 ||
3907 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07003908 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003909 hddLog(VOS_TRACE_LEVEL_WARN,
3910 "%s:invalid priv_data.total_len(%d)!!!", __func__,
3911 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003912 ret = -EINVAL;
3913 goto exit;
3914 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05303915 status = wlan_hdd_validate_context(pHddCtx);
3916 if (0 != status)
3917 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303918 ret = -EINVAL;
3919 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303920 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003921 /* Allocate +1 for '\0' */
3922 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07003923 if (!command)
3924 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003925 hddLog(VOS_TRACE_LEVEL_ERROR,
3926 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003927 ret = -ENOMEM;
3928 goto exit;
3929 }
3930
3931 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
3932 {
3933 ret = -EFAULT;
3934 goto exit;
3935 }
3936
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003937 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003938 command[priv_data.total_len] = '\0';
3939
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003940 /* at one time the following block of code was conditional. braces
3941 * have been retained to avoid re-indenting the legacy code
3942 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003943 {
3944 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
3945
3946 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003947 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07003948
3949 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
3950 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303951 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3952 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
3953 pAdapter->sessionId, (unsigned)
3954 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
3955 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
3956 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
3957 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07003958 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
3959 sizeof(tSirMacAddr)))
3960 {
3961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003962 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003963 ret = -EFAULT;
3964 }
3965 }
Amar Singhal0974e402013-02-12 14:27:46 -08003966 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07003967 {
Amar Singhal0974e402013-02-12 14:27:46 -08003968 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003969
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303970 ret = hdd_drv_cmd_validate(command, 7);
3971 if (ret)
3972 goto exit;
3973
Jeff Johnson295189b2012-06-20 16:38:30 -07003974 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003975
3976 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07003977 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07003978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08003979 "%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 +05303980 if(VOS_FTM_MODE != hdd_get_conparam())
3981 {
3982 /* Change band request received */
3983 ret = hdd_setBand_helper(pAdapter->dev, ptr);
3984 if(ret < 0)
3985 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3986 "%s: failed to set band ret=%d", __func__, ret);
3987 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003988 }
Kiet Lamf040f472013-11-20 21:15:23 +05303989 else if(strncmp(command, "SETWMMPS", 8) == 0)
3990 {
3991 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303992
3993 ret = hdd_drv_cmd_validate(command, 8);
3994 if (ret)
3995 goto exit;
3996
Kiet Lamf040f472013-11-20 21:15:23 +05303997 ret = hdd_wmmps_helper(pAdapter, ptr);
3998 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05303999
4000 else if(strncmp(command, "TDLSSCAN", 8) == 0)
4001 {
4002 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304003
4004 ret = hdd_drv_cmd_validate(command, 8);
4005 if (ret)
4006 goto exit;
4007
Agarwal Ashishef54a182014-12-16 15:07:31 +05304008 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
4009 }
4010
Jeff Johnson32d95a32012-09-10 13:15:23 -07004011 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
4012 {
4013 char *country_code;
4014
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304015 ret = hdd_drv_cmd_validate(command, 7);
4016 if (ret)
4017 goto exit;
4018
Jeff Johnson32d95a32012-09-10 13:15:23 -07004019 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07004020
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004021 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07004022 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07004023#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05304024 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07004025#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004026 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
4027 (void *)(tSmeChangeCountryCallback)
4028 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05304029 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004030 if (eHAL_STATUS_SUCCESS == ret)
4031 {
4032 ret = wait_for_completion_interruptible_timeout(
4033 &pAdapter->change_country_code,
4034 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
4035 if (0 >= ret)
4036 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004037 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304038 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004039 }
4040 }
4041 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07004042 {
4043 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004044 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004045 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07004046 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004047
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004048 }
4049 /*
4050 command should be a string having format
4051 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
4052 */
Amar Singhal0974e402013-02-12 14:27:46 -08004053 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004054 {
Amar Singhal0974e402013-02-12 14:27:46 -08004055 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004056
4057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004058 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004059
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08004060 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07004061 }
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +05304062
4063 else if (strncmp(command, "VOWIFIMODE", 10) == 0)
4064 {
4065 tANI_U8 *ptr;
4066
4067 ret = hdd_drv_cmd_validate(command, 10);
4068 if (ret)
4069 goto exit;
4070
4071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4072 "Received Command for VOWIFI mode in %s", __func__);
4073
4074 ptr = (tANI_U8*)command + 11;
4075 hdd_set_vowifi_mode(pHddCtx, *ptr - '0');
4076 }
4077
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004078 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
4079 {
4080 int suspend = 0;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304081 tANI_U8 *ptr;
4082
4083 ret = hdd_drv_cmd_validate(command, 14);
4084 if (ret)
4085 goto exit;
4086
4087 ptr = (tANI_U8*)command + 15;
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004088
4089 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304090 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4091 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
4092 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004093 hdd_set_wlan_suspend_mode(suspend);
4094 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004095#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
4096 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
4097 {
4098 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004099 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004100 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
4101 eHalStatus status = eHAL_STATUS_SUCCESS;
4102
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304103 ret = hdd_drv_cmd_validate(command, 14);
4104 if (ret)
4105 goto exit;
4106
Srinivas Girigowdade697412013-02-14 16:31:48 -08004107 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
4108 value = value + 15;
4109
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004110 /* Convert the value from ascii to integer */
4111 ret = kstrtos8(value, 10, &rssi);
4112 if (ret < 0)
4113 {
4114 /* If the input value is greater than max value of datatype, then also
4115 kstrtou8 fails */
4116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4117 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07004118 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004119 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
4120 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
4121 ret = -EINVAL;
4122 goto exit;
4123 }
4124
Srinivas Girigowdade697412013-02-14 16:31:48 -08004125 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004126
Srinivas Girigowdade697412013-02-14 16:31:48 -08004127 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
4128 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
4129 {
4130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4131 "Neighbor lookup threshold value %d is out of range"
4132 " (Min: %d Max: %d)", lookUpThreshold,
4133 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
4134 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
4135 ret = -EINVAL;
4136 goto exit;
4137 }
4138
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304139 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4140 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
4141 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004142 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4143 "%s: Received Command to Set Roam trigger"
4144 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
4145
4146 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
4147 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
4148 if (eHAL_STATUS_SUCCESS != status)
4149 {
4150 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4151 "%s: Failed to set roam trigger, try again", __func__);
4152 ret = -EPERM;
4153 goto exit;
4154 }
4155
4156 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05304157 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004158 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
4159 }
4160 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
4161 {
4162 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
4163 int rssi = (-1) * lookUpThreshold;
4164 char extra[32];
4165 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304166 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4167 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
4168 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004169 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05304170 len = VOS_MIN(priv_data.total_len, len + 1);
4171 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004172 {
4173 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4174 "%s: failed to copy data to user buffer", __func__);
4175 ret = -EFAULT;
4176 goto exit;
4177 }
4178 }
4179 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
4180 {
4181 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004182 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004183 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004184
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304185 ret = hdd_drv_cmd_validate(command, 17);
4186 if (ret)
4187 goto exit;
4188
Srinivas Girigowdade697412013-02-14 16:31:48 -08004189 /* input refresh period is in terms of seconds */
4190 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
4191 value = value + 18;
4192 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004193 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004194 if (ret < 0)
4195 {
4196 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004197 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08004198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004199 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08004200 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07004201 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
4202 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004203 ret = -EINVAL;
4204 goto exit;
4205 }
4206
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004207 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
4208 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004209 {
4210 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004211 "Roam scan period value %d is out of range"
4212 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07004213 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
4214 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004215 ret = -EINVAL;
4216 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304217 }
4218 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4219 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
4220 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004221 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004222
4223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4224 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004225 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004226
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004227 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
4228 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004229 }
4230 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
4231 {
4232 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
4233 char extra[32];
4234 tANI_U8 len = 0;
4235
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304236 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4237 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
4238 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004239 len = scnprintf(extra, sizeof(extra), "%s %d",
4240 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004241 /* Returned value is in units of seconds */
Ratnam Rachuria72ba112015-07-17 13:27:03 +05304242 len = VOS_MIN(priv_data.total_len, len + 1);
4243 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4245 "%s: failed to copy data to user buffer", __func__);
4246 ret = -EFAULT;
4247 goto exit;
4248 }
4249 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004250 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
4251 {
4252 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004253 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004254 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004255
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304256 ret = hdd_drv_cmd_validate(command, 24);
4257 if (ret)
4258 goto exit;
4259
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004260 /* input refresh period is in terms of seconds */
4261 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
4262 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004263
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004264 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004265 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004266 if (ret < 0)
4267 {
4268 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004269 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004270 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004271 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004272 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004273 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
4274 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
4275 ret = -EINVAL;
4276 goto exit;
4277 }
4278
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004279 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
4280 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
4281 {
4282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4283 "Neighbor scan results refresh period value %d is out of range"
4284 " (Min: %d Max: %d)", roamScanRefreshPeriod,
4285 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
4286 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
4287 ret = -EINVAL;
4288 goto exit;
4289 }
4290 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
4291
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4293 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004294 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004295
4296 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
4297 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
4298 }
4299 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
4300 {
4301 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
4302 char extra[32];
4303 tANI_U8 len = 0;
4304
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004305 len = scnprintf(extra, sizeof(extra), "%s %d",
4306 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004307 /* Returned value is in units of seconds */
Ratnam Rachuri2c9d6702015-07-17 13:25:16 +05304308 len = VOS_MIN(priv_data.total_len, len + 1);
4309 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4311 "%s: failed to copy data to user buffer", __func__);
4312 ret = -EFAULT;
4313 goto exit;
4314 }
4315 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004316#ifdef FEATURE_WLAN_LFR
4317 /* SETROAMMODE */
4318 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
4319 {
4320 tANI_U8 *value = command;
4321 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
4322
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05304323 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
4324 hddLog(LOGE,
4325 FL("Roaming is always disabled in STA + MON concurrency"));
4326 ret = -EINVAL;
4327 goto exit;
4328 }
4329
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304330 ret = hdd_drv_cmd_validate(command, SIZE_OF_SETROAMMODE);
4331 if (ret)
4332 goto exit;
4333
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004334 /* Move pointer to ahead of SETROAMMODE<delimiter> */
4335 value = value + SIZE_OF_SETROAMMODE + 1;
4336
4337 /* Convert the value from ascii to integer */
4338 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
4339 if (ret < 0)
4340 {
4341 /* If the input value is greater than max value of datatype, then also
4342 kstrtou8 fails */
4343 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4344 "%s: kstrtou8 failed range [%d - %d]", __func__,
4345 CFG_LFR_FEATURE_ENABLED_MIN,
4346 CFG_LFR_FEATURE_ENABLED_MAX);
4347 ret = -EINVAL;
4348 goto exit;
4349 }
4350 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
4351 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
4352 {
4353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4354 "Roam Mode value %d is out of range"
4355 " (Min: %d Max: %d)", roamMode,
4356 CFG_LFR_FEATURE_ENABLED_MIN,
4357 CFG_LFR_FEATURE_ENABLED_MAX);
4358 ret = -EINVAL;
4359 goto exit;
4360 }
4361
4362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4363 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
4364 /*
4365 * Note that
4366 * SETROAMMODE 0 is to enable LFR while
4367 * SETROAMMODE 1 is to disable LFR, but
4368 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
4369 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
4370 */
4371 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
4372 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
4373 else
4374 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
4375
4376 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
4377 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
4378 }
4379 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304380 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004381 {
4382 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4383 char extra[32];
4384 tANI_U8 len = 0;
4385
4386 /*
4387 * roamMode value shall be inverted because the sementics is different.
4388 */
4389 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
4390 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
4391 else
4392 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
4393
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004394 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Ratnam Rachuri28693eb2015-07-17 13:23:42 +05304395 len = VOS_MIN(priv_data.total_len, len + 1);
4396 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4398 "%s: failed to copy data to user buffer", __func__);
4399 ret = -EFAULT;
4400 goto exit;
4401 }
4402 }
4403#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08004404#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004405#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004406 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
4407 {
4408 tANI_U8 *value = command;
4409 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
4410
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304411 ret = hdd_drv_cmd_validate(command, 12);
4412 if (ret)
4413 goto exit;
4414
Srinivas Girigowdade697412013-02-14 16:31:48 -08004415 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
4416 value = value + 13;
4417 /* Convert the value from ascii to integer */
4418 ret = kstrtou8(value, 10, &roamRssiDiff);
4419 if (ret < 0)
4420 {
4421 /* If the input value is greater than max value of datatype, then also
4422 kstrtou8 fails */
4423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4424 "%s: kstrtou8 failed range [%d - %d]", __func__,
4425 CFG_ROAM_RSSI_DIFF_MIN,
4426 CFG_ROAM_RSSI_DIFF_MAX);
4427 ret = -EINVAL;
4428 goto exit;
4429 }
4430
4431 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
4432 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
4433 {
4434 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4435 "Roam rssi diff value %d is out of range"
4436 " (Min: %d Max: %d)", roamRssiDiff,
4437 CFG_ROAM_RSSI_DIFF_MIN,
4438 CFG_ROAM_RSSI_DIFF_MAX);
4439 ret = -EINVAL;
4440 goto exit;
4441 }
4442
4443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4444 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
4445
4446 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
4447 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
4448 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304449 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004450 {
4451 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
4452 char extra[32];
4453 tANI_U8 len = 0;
4454
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304455 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4456 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
4457 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004458 len = scnprintf(extra, sizeof(extra), "%s %d",
4459 command, roamRssiDiff);
Ratnam Rachuri22a3b402015-07-17 13:21:49 +05304460 len = VOS_MIN(priv_data.total_len, len + 1);
4461 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4463 "%s: failed to copy data to user buffer", __func__);
4464 ret = -EFAULT;
4465 goto exit;
4466 }
4467 }
4468#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004469#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004470 else if (strncmp(command, "GETBAND", 7) == 0)
4471 {
4472 int band = -1;
4473 char extra[32];
4474 tANI_U8 len = 0;
4475 hdd_getBand_helper(pHddCtx, &band);
4476
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304477 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4478 TRACE_CODE_HDD_GETBAND_IOCTL,
4479 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004480 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Ratnam Rachuri52139592015-07-17 13:17:29 +05304481 len = VOS_MIN(priv_data.total_len, len + 1);
4482 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4484 "%s: failed to copy data to user buffer", __func__);
4485 ret = -EFAULT;
4486 goto exit;
4487 }
4488 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004489 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
4490 {
4491 tANI_U8 *value = command;
4492 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4493 tANI_U8 numChannels = 0;
4494 eHalStatus status = eHAL_STATUS_SUCCESS;
4495
4496 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4497 if (eHAL_STATUS_SUCCESS != status)
4498 {
4499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4500 "%s: Failed to parse channel list information", __func__);
4501 ret = -EINVAL;
4502 goto exit;
4503 }
4504
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304505 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4506 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
4507 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004508 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4509 {
4510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4511 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4512 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4513 ret = -EINVAL;
4514 goto exit;
4515 }
4516 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
4517 numChannels);
4518 if (eHAL_STATUS_SUCCESS != status)
4519 {
4520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4521 "%s: Failed to update channel list information", __func__);
4522 ret = -EINVAL;
4523 goto exit;
4524 }
4525 }
4526 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
4527 {
4528 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4529 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07004530 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004531 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07004532 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004533
4534 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
4535 ChannelList, &numChannels ))
4536 {
4537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4538 "%s: failed to get roam scan channel list", __func__);
4539 ret = -EFAULT;
4540 goto exit;
4541 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304542 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4543 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
4544 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004545 /* output channel list is of the format
4546 [Number of roam scan channels][Channel1][Channel2]... */
4547 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004548 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Sushant Kaushika08ca192015-09-16 15:52:04 +05304549 for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004550 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004551 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
4552 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004553 }
4554
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05304555 len = VOS_MIN(priv_data.total_len, len + 1);
4556 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004557 {
4558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4559 "%s: failed to copy data to user buffer", __func__);
4560 ret = -EFAULT;
4561 goto exit;
4562 }
4563 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004564 else if (strncmp(command, "GETCCXMODE", 10) == 0)
4565 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004566 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004567 char extra[32];
4568 tANI_U8 len = 0;
4569
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004570 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004571 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004572 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004573 hdd_is_okc_mode_enabled(pHddCtx) &&
4574 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4575 {
4576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004577 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004578 " hence this operation is not permitted!", __func__);
4579 ret = -EPERM;
4580 goto exit;
4581 }
4582
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004583 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004584 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05304585 len = VOS_MIN(priv_data.total_len, len + 1);
4586 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004587 {
4588 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4589 "%s: failed to copy data to user buffer", __func__);
4590 ret = -EFAULT;
4591 goto exit;
4592 }
4593 }
4594 else if (strncmp(command, "GETOKCMODE", 10) == 0)
4595 {
4596 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
4597 char extra[32];
4598 tANI_U8 len = 0;
4599
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004600 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004601 then this operation is not permitted (return FAILURE) */
4602 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004603 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004604 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4605 {
4606 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004607 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004608 " hence this operation is not permitted!", __func__);
4609 ret = -EPERM;
4610 goto exit;
4611 }
4612
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004613 len = scnprintf(extra, sizeof(extra), "%s %d",
4614 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05304615 len = VOS_MIN(priv_data.total_len, len + 1);
4616 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004617 {
4618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4619 "%s: failed to copy data to user buffer", __func__);
4620 ret = -EFAULT;
4621 goto exit;
4622 }
4623 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004624 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004625 {
4626 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4627 char extra[32];
4628 tANI_U8 len = 0;
4629
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004630 len = scnprintf(extra, sizeof(extra), "%s %d",
4631 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05304632 len = VOS_MIN(priv_data.total_len, len + 1);
4633 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004634 {
4635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4636 "%s: failed to copy data to user buffer", __func__);
4637 ret = -EFAULT;
4638 goto exit;
4639 }
4640 }
4641 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
4642 {
4643 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4644 char extra[32];
4645 tANI_U8 len = 0;
4646
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004647 len = scnprintf(extra, sizeof(extra), "%s %d",
4648 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05304649 len = VOS_MIN(priv_data.total_len, len + 1);
4650 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004651 {
4652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4653 "%s: failed to copy data to user buffer", __func__);
4654 ret = -EFAULT;
4655 goto exit;
4656 }
4657 }
4658 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
4659 {
4660 tANI_U8 *value = command;
4661 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
4662
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304663 ret = hdd_drv_cmd_validate(command, 25);
4664 if (ret)
4665 goto exit;
4666
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004667 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
4668 value = value + 26;
4669 /* Convert the value from ascii to integer */
4670 ret = kstrtou8(value, 10, &minTime);
4671 if (ret < 0)
4672 {
4673 /* If the input value is greater than max value of datatype, then also
4674 kstrtou8 fails */
4675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4676 "%s: kstrtou8 failed range [%d - %d]", __func__,
4677 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
4678 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
4679 ret = -EINVAL;
4680 goto exit;
4681 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004682 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
4683 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
4684 {
4685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4686 "scan min channel time value %d is out of range"
4687 " (Min: %d Max: %d)", minTime,
4688 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
4689 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
4690 ret = -EINVAL;
4691 goto exit;
4692 }
4693
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304694 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4695 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
4696 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004697 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4698 "%s: Received Command to change channel min time = %d", __func__, minTime);
4699
4700 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
4701 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
4702 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004703 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
4704 {
4705 tANI_U8 *value = command;
4706 tANI_U8 channel = 0;
4707 tANI_U8 dwellTime = 0;
4708 tANI_U8 bufLen = 0;
4709 tANI_U8 *buf = NULL;
4710 tSirMacAddr targetApBssid;
4711 eHalStatus status = eHAL_STATUS_SUCCESS;
4712 struct ieee80211_channel chan;
4713 tANI_U8 finalLen = 0;
4714 tANI_U8 *finalBuf = NULL;
4715 tANI_U8 temp = 0;
4716 u64 cookie;
4717 hdd_station_ctx_t *pHddStaCtx = NULL;
4718 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4719
4720 /* if not associated, no need to send action frame */
4721 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4722 {
4723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
4724 ret = -EINVAL;
4725 goto exit;
4726 }
4727
4728 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
4729 &dwellTime, &buf, &bufLen);
4730 if (eHAL_STATUS_SUCCESS != status)
4731 {
4732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4733 "%s: Failed to parse send action frame data", __func__);
4734 ret = -EINVAL;
4735 goto exit;
4736 }
4737
4738 /* if the target bssid is different from currently associated AP,
4739 then no need to send action frame */
4740 if (VOS_TRUE != vos_mem_compare(targetApBssid,
4741 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
4742 {
4743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
4744 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004745 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004746 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004747 goto exit;
4748 }
4749
4750 /* if the channel number is different from operating channel then
4751 no need to send action frame */
4752 if (channel != pHddStaCtx->conn_info.operationChannel)
4753 {
4754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4755 "%s: channel(%d) is different from operating channel(%d)",
4756 __func__, channel, pHddStaCtx->conn_info.operationChannel);
4757 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004758 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004759 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004760 goto exit;
4761 }
4762 chan.center_freq = sme_ChnToFreq(channel);
4763
4764 finalLen = bufLen + 24;
4765 finalBuf = vos_mem_malloc(finalLen);
4766 if (NULL == finalBuf)
4767 {
4768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
4769 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07004770 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004771 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004772 goto exit;
4773 }
4774 vos_mem_zero(finalBuf, finalLen);
4775
4776 /* Fill subtype */
4777 temp = SIR_MAC_MGMT_ACTION << 4;
4778 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
4779
4780 /* Fill type */
4781 temp = SIR_MAC_MGMT_FRAME;
4782 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
4783
4784 /* Fill destination address (bssid of the AP) */
4785 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
4786
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004787 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004788 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
4789
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004790 /* Fill BSSID (AP mac address) */
4791 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004792
4793 /* Fill received buffer from 24th address */
4794 vos_mem_copy(finalBuf + 24, buf, bufLen);
4795
Jeff Johnson11c33152013-04-16 17:52:40 -07004796 /* done with the parsed buffer */
4797 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004798 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004799
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304800#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
4801 params.chan = &chan;
4802 params.offchan = 0;
4803 params.wait = dwellTime;
4804 params.buf = finalBuf;
4805 params.len = finalLen;
4806 params.no_cck = 1;
4807 params.dont_wait_for_ack = 1;
4808 ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
4809#else
DARAM SUDHA39eede62014-02-12 11:16:40 +05304810 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07004811#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4812 &(pAdapter->wdev),
4813#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004814 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07004815#endif
4816 &chan, 0,
4817#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4818 NL80211_CHAN_HT20, 1,
4819#endif
4820 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004821 1, &cookie );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304822#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004823 vos_mem_free(finalBuf);
4824 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004825 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
4826 {
4827 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
4828 char extra[32];
4829 tANI_U8 len = 0;
4830
4831 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004832 len = scnprintf(extra, sizeof(extra), "%s %d",
4833 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304834 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4835 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
4836 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05304837 len = VOS_MIN(priv_data.total_len, len + 1);
4838 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004839 {
4840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4841 "%s: failed to copy data to user buffer", __func__);
4842 ret = -EFAULT;
4843 goto exit;
4844 }
4845 }
4846 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
4847 {
4848 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004849 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004850
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304851 ret = hdd_drv_cmd_validate(command, 18);
4852 if (ret)
4853 goto exit;
4854
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004855 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
4856 value = value + 19;
4857 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004858 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004859 if (ret < 0)
4860 {
4861 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004862 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004864 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004865 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4866 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4867 ret = -EINVAL;
4868 goto exit;
4869 }
4870
4871 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
4872 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
4873 {
4874 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4875 "lfr mode value %d is out of range"
4876 " (Min: %d Max: %d)", maxTime,
4877 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4878 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4879 ret = -EINVAL;
4880 goto exit;
4881 }
4882
4883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4884 "%s: Received Command to change channel max time = %d", __func__, maxTime);
4885
4886 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
4887 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
4888 }
4889 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
4890 {
4891 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
4892 char extra[32];
4893 tANI_U8 len = 0;
4894
4895 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004896 len = scnprintf(extra, sizeof(extra), "%s %d",
4897 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05304898 len = VOS_MIN(priv_data.total_len, len + 1);
4899 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004900 {
4901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4902 "%s: failed to copy data to user buffer", __func__);
4903 ret = -EFAULT;
4904 goto exit;
4905 }
4906 }
4907 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
4908 {
4909 tANI_U8 *value = command;
4910 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
4911
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304912 ret = hdd_drv_cmd_validate(command, 15);
4913 if (ret)
4914 goto exit;
4915
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004916 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
4917 value = value + 16;
4918 /* Convert the value from ascii to integer */
4919 ret = kstrtou16(value, 10, &val);
4920 if (ret < 0)
4921 {
4922 /* If the input value is greater than max value of datatype, then also
4923 kstrtou16 fails */
4924 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4925 "%s: kstrtou16 failed range [%d - %d]", __func__,
4926 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4927 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4928 ret = -EINVAL;
4929 goto exit;
4930 }
4931
4932 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
4933 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
4934 {
4935 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4936 "scan home time value %d is out of range"
4937 " (Min: %d Max: %d)", val,
4938 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4939 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4940 ret = -EINVAL;
4941 goto exit;
4942 }
4943
4944 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4945 "%s: Received Command to change scan home time = %d", __func__, val);
4946
4947 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
4948 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
4949 }
4950 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
4951 {
4952 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
4953 char extra[32];
4954 tANI_U8 len = 0;
4955
4956 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004957 len = scnprintf(extra, sizeof(extra), "%s %d",
4958 "GETSCANHOMETIME", val);
Ratheesh S P728d7c62015-07-16 15:38:58 +05304959 len = VOS_MIN(priv_data.total_len, len + 1);
4960 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004961 {
4962 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4963 "%s: failed to copy data to user buffer", __func__);
4964 ret = -EFAULT;
4965 goto exit;
4966 }
4967 }
4968 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
4969 {
4970 tANI_U8 *value = command;
4971 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
4972
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304973 ret = hdd_drv_cmd_validate(command, 16);
4974 if (ret)
4975 goto exit;
4976
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004977 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
4978 value = value + 17;
4979 /* Convert the value from ascii to integer */
4980 ret = kstrtou8(value, 10, &val);
4981 if (ret < 0)
4982 {
4983 /* If the input value is greater than max value of datatype, then also
4984 kstrtou8 fails */
4985 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4986 "%s: kstrtou8 failed range [%d - %d]", __func__,
4987 CFG_ROAM_INTRA_BAND_MIN,
4988 CFG_ROAM_INTRA_BAND_MAX);
4989 ret = -EINVAL;
4990 goto exit;
4991 }
4992
4993 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
4994 (val > CFG_ROAM_INTRA_BAND_MAX))
4995 {
4996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4997 "intra band mode value %d is out of range"
4998 " (Min: %d Max: %d)", val,
4999 CFG_ROAM_INTRA_BAND_MIN,
5000 CFG_ROAM_INTRA_BAND_MAX);
5001 ret = -EINVAL;
5002 goto exit;
5003 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005004 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5005 "%s: Received Command to change intra band = %d", __func__, val);
5006
5007 pHddCtx->cfg_ini->nRoamIntraBand = val;
5008 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
5009 }
5010 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
5011 {
5012 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
5013 char extra[32];
5014 tANI_U8 len = 0;
5015
5016 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005017 len = scnprintf(extra, sizeof(extra), "%s %d",
5018 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +05305019 len = VOS_MIN(priv_data.total_len, len + 1);
5020 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005021 {
5022 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5023 "%s: failed to copy data to user buffer", __func__);
5024 ret = -EFAULT;
5025 goto exit;
5026 }
5027 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005028 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
5029 {
5030 tANI_U8 *value = command;
5031 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
5032
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305033 ret = hdd_drv_cmd_validate(command, 14);
5034 if (ret)
5035 goto exit;
5036
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005037 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
5038 value = value + 15;
5039 /* Convert the value from ascii to integer */
5040 ret = kstrtou8(value, 10, &nProbes);
5041 if (ret < 0)
5042 {
5043 /* If the input value is greater than max value of datatype, then also
5044 kstrtou8 fails */
5045 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5046 "%s: kstrtou8 failed range [%d - %d]", __func__,
5047 CFG_ROAM_SCAN_N_PROBES_MIN,
5048 CFG_ROAM_SCAN_N_PROBES_MAX);
5049 ret = -EINVAL;
5050 goto exit;
5051 }
5052
5053 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
5054 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
5055 {
5056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5057 "NProbes value %d is out of range"
5058 " (Min: %d Max: %d)", nProbes,
5059 CFG_ROAM_SCAN_N_PROBES_MIN,
5060 CFG_ROAM_SCAN_N_PROBES_MAX);
5061 ret = -EINVAL;
5062 goto exit;
5063 }
5064
5065 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5066 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
5067
5068 pHddCtx->cfg_ini->nProbes = nProbes;
5069 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
5070 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305071 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005072 {
5073 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
5074 char extra[32];
5075 tANI_U8 len = 0;
5076
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005077 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri6da525d2015-08-07 13:55:54 +05305078 len = VOS_MIN(priv_data.total_len, len + 1);
5079 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005080 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5081 "%s: failed to copy data to user buffer", __func__);
5082 ret = -EFAULT;
5083 goto exit;
5084 }
5085 }
5086 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
5087 {
5088 tANI_U8 *value = command;
5089 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
5090
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305091 ret = hdd_drv_cmd_validate(command, 19);
5092 if (ret)
5093 goto exit;
5094
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005095 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
5096 /* input value is in units of msec */
5097 value = value + 20;
5098 /* Convert the value from ascii to integer */
5099 ret = kstrtou16(value, 10, &homeAwayTime);
5100 if (ret < 0)
5101 {
5102 /* If the input value is greater than max value of datatype, then also
5103 kstrtou8 fails */
5104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5105 "%s: kstrtou8 failed range [%d - %d]", __func__,
5106 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
5107 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
5108 ret = -EINVAL;
5109 goto exit;
5110 }
5111
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005112 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
5113 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
5114 {
5115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5116 "homeAwayTime value %d is out of range"
5117 " (Min: %d Max: %d)", homeAwayTime,
5118 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
5119 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
5120 ret = -EINVAL;
5121 goto exit;
5122 }
5123
5124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5125 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07005126 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
5127 {
5128 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
5129 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
5130 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005131 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305132 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005133 {
5134 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
5135 char extra[32];
5136 tANI_U8 len = 0;
5137
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005138 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri51a5ad12015-08-07 14:06:37 +05305139 len = VOS_MIN(priv_data.total_len, len + 1);
5140 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5142 "%s: failed to copy data to user buffer", __func__);
5143 ret = -EFAULT;
5144 goto exit;
5145 }
5146 }
5147 else if (strncmp(command, "REASSOC", 7) == 0)
5148 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305149 ret = hdd_drv_cmd_validate(command, 7);
5150 if (ret)
5151 goto exit;
5152
5153 ret = hdd_parse_reassoc(pAdapter, command, priv_data.total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05305154 if (!ret)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005155 goto exit;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005156 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005157 else if (strncmp(command, "SETWESMODE", 10) == 0)
5158 {
5159 tANI_U8 *value = command;
5160 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
5161
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305162 ret = hdd_drv_cmd_validate(command, 10);
5163 if (ret)
5164 goto exit;
5165
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005166 /* Move pointer to ahead of SETWESMODE<delimiter> */
5167 value = value + 11;
5168 /* Convert the value from ascii to integer */
5169 ret = kstrtou8(value, 10, &wesMode);
5170 if (ret < 0)
5171 {
5172 /* If the input value is greater than max value of datatype, then also
5173 kstrtou8 fails */
5174 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5175 "%s: kstrtou8 failed range [%d - %d]", __func__,
5176 CFG_ENABLE_WES_MODE_NAME_MIN,
5177 CFG_ENABLE_WES_MODE_NAME_MAX);
5178 ret = -EINVAL;
5179 goto exit;
5180 }
5181
5182 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
5183 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
5184 {
5185 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5186 "WES Mode value %d is out of range"
5187 " (Min: %d Max: %d)", wesMode,
5188 CFG_ENABLE_WES_MODE_NAME_MIN,
5189 CFG_ENABLE_WES_MODE_NAME_MAX);
5190 ret = -EINVAL;
5191 goto exit;
5192 }
5193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5194 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
5195
5196 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
5197 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
5198 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305199 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005200 {
5201 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
5202 char extra[32];
5203 tANI_U8 len = 0;
5204
Arif Hussain826d9412013-11-12 16:44:54 -08005205 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05305206 len = VOS_MIN(priv_data.total_len, len + 1);
5207 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5209 "%s: failed to copy data to user buffer", __func__);
5210 ret = -EFAULT;
5211 goto exit;
5212 }
5213 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005214#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005215#ifdef FEATURE_WLAN_LFR
5216 else if (strncmp(command, "SETFASTROAM", 11) == 0)
5217 {
5218 tANI_U8 *value = command;
5219 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
5220
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05305221 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
5222 hddLog(LOGE,
5223 FL("Roaming is always disabled in STA + MON concurrency"));
5224 ret = -EINVAL;
5225 goto exit;
5226 }
5227
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305228 ret = hdd_drv_cmd_validate(command, 11);
5229 if (ret)
5230 goto exit;
5231
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005232 /* Move pointer to ahead of SETFASTROAM<delimiter> */
5233 value = value + 12;
5234 /* Convert the value from ascii to integer */
5235 ret = kstrtou8(value, 10, &lfrMode);
5236 if (ret < 0)
5237 {
5238 /* If the input value is greater than max value of datatype, then also
5239 kstrtou8 fails */
5240 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5241 "%s: kstrtou8 failed range [%d - %d]", __func__,
5242 CFG_LFR_FEATURE_ENABLED_MIN,
5243 CFG_LFR_FEATURE_ENABLED_MAX);
5244 ret = -EINVAL;
5245 goto exit;
5246 }
5247
5248 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
5249 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
5250 {
5251 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5252 "lfr mode value %d is out of range"
5253 " (Min: %d Max: %d)", lfrMode,
5254 CFG_LFR_FEATURE_ENABLED_MIN,
5255 CFG_LFR_FEATURE_ENABLED_MAX);
5256 ret = -EINVAL;
5257 goto exit;
5258 }
5259
5260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5261 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
5262
5263 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
5264 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
5265 }
5266#endif
5267#ifdef WLAN_FEATURE_VOWIFI_11R
5268 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
5269 {
5270 tANI_U8 *value = command;
5271 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
5272
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305273 ret = hdd_drv_cmd_validate(command, 17);
5274 if (ret)
5275 goto exit;
5276
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005277 /* Move pointer to ahead of SETFASTROAM<delimiter> */
5278 value = value + 18;
5279 /* Convert the value from ascii to integer */
5280 ret = kstrtou8(value, 10, &ft);
5281 if (ret < 0)
5282 {
5283 /* If the input value is greater than max value of datatype, then also
5284 kstrtou8 fails */
5285 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5286 "%s: kstrtou8 failed range [%d - %d]", __func__,
5287 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
5288 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
5289 ret = -EINVAL;
5290 goto exit;
5291 }
5292
5293 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
5294 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
5295 {
5296 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5297 "ft mode value %d is out of range"
5298 " (Min: %d Max: %d)", ft,
5299 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
5300 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
5301 ret = -EINVAL;
5302 goto exit;
5303 }
5304
5305 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5306 "%s: Received Command to change ft mode = %d", __func__, ft);
5307
5308 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
5309 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
5310 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305311 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
5312 {
5313 tANI_U8 *value = command;
5314 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305315
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305316 ret = hdd_drv_cmd_validate(command, 14);
5317 if (ret)
5318 goto exit;
5319
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305320 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
5321 value = value + 15;
5322 /* Convert the value from ascii to integer */
5323 ret = kstrtou8(value, 10, &dfsScanMode);
5324 if (ret < 0)
5325 {
5326 /* If the input value is greater than max value of
5327 datatype, then also kstrtou8 fails
5328 */
5329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5330 "%s: kstrtou8 failed range [%d - %d]", __func__,
5331 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
5332 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
5333 ret = -EINVAL;
5334 goto exit;
5335 }
5336
5337 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
5338 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
5339 {
5340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5341 "dfsScanMode value %d is out of range"
5342 " (Min: %d Max: %d)", dfsScanMode,
5343 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
5344 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
5345 ret = -EINVAL;
5346 goto exit;
5347 }
5348 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5349 "%s: Received Command to Set DFS Scan Mode = %d",
5350 __func__, dfsScanMode);
5351
5352 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
5353 }
5354 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
5355 {
5356 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
5357 char extra[32];
5358 tANI_U8 len = 0;
5359
5360 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05305361 len = VOS_MIN(priv_data.total_len, len + 1);
5362 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305363 {
5364 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5365 "%s: failed to copy data to user buffer", __func__);
5366 ret = -EFAULT;
5367 goto exit;
5368 }
5369 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305370 else if (strncmp(command, "FASTREASSOC", 11) == 0)
5371 {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05305372 ret = wlan_hdd_handle_fastreassoc(pAdapter, command);
5373 if (!ret)
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305374 goto exit;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305375 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005376#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005377#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005378 else if (strncmp(command, "SETCCXMODE", 10) == 0)
5379 {
5380 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005381 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005382
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305383 ret = hdd_drv_cmd_validate(command, 10);
5384 if (ret)
5385 goto exit;
5386
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005387 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005388 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005389 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005390 hdd_is_okc_mode_enabled(pHddCtx) &&
5391 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
5392 {
5393 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005394 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005395 " hence this operation is not permitted!", __func__);
5396 ret = -EPERM;
5397 goto exit;
5398 }
5399
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005400 /* Move pointer to ahead of SETCCXMODE<delimiter> */
5401 value = value + 11;
5402 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005403 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005404 if (ret < 0)
5405 {
5406 /* If the input value is greater than max value of datatype, then also
5407 kstrtou8 fails */
5408 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5409 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005410 CFG_ESE_FEATURE_ENABLED_MIN,
5411 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005412 ret = -EINVAL;
5413 goto exit;
5414 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005415 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
5416 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005417 {
5418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005419 "Ese mode value %d is out of range"
5420 " (Min: %d Max: %d)", eseMode,
5421 CFG_ESE_FEATURE_ENABLED_MIN,
5422 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005423 ret = -EINVAL;
5424 goto exit;
5425 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005427 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005428
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005429 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
5430 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005431 }
5432#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005433 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
5434 {
5435 tANI_U8 *value = command;
5436 tANI_BOOLEAN roamScanControl = 0;
5437
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305438 ret = hdd_drv_cmd_validate(command, 18);
5439 if (ret)
5440 goto exit;
5441
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005442 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
5443 value = value + 19;
5444 /* Convert the value from ascii to integer */
5445 ret = kstrtou8(value, 10, &roamScanControl);
5446 if (ret < 0)
5447 {
5448 /* If the input value is greater than max value of datatype, then also
5449 kstrtou8 fails */
5450 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5451 "%s: kstrtou8 failed ", __func__);
5452 ret = -EINVAL;
5453 goto exit;
5454 }
5455
5456 if (0 != roamScanControl)
5457 {
5458 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5459 "roam scan control invalid value = %d",
5460 roamScanControl);
5461 ret = -EINVAL;
5462 goto exit;
5463 }
5464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5465 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
5466
5467 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
5468 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005469#ifdef FEATURE_WLAN_OKC
5470 else if (strncmp(command, "SETOKCMODE", 10) == 0)
5471 {
5472 tANI_U8 *value = command;
5473 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
5474
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305475 ret = hdd_drv_cmd_validate(command, 10);
5476 if (ret)
5477 goto exit;
5478
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005479 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005480 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005481 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005482 hdd_is_okc_mode_enabled(pHddCtx) &&
5483 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
5484 {
5485 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005486 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005487 " hence this operation is not permitted!", __func__);
5488 ret = -EPERM;
5489 goto exit;
5490 }
5491
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005492 /* Move pointer to ahead of SETOKCMODE<delimiter> */
5493 value = value + 11;
5494 /* Convert the value from ascii to integer */
5495 ret = kstrtou8(value, 10, &okcMode);
5496 if (ret < 0)
5497 {
5498 /* If the input value is greater than max value of datatype, then also
5499 kstrtou8 fails */
5500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5501 "%s: kstrtou8 failed range [%d - %d]", __func__,
5502 CFG_OKC_FEATURE_ENABLED_MIN,
5503 CFG_OKC_FEATURE_ENABLED_MAX);
5504 ret = -EINVAL;
5505 goto exit;
5506 }
5507
5508 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
5509 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
5510 {
5511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5512 "Okc mode value %d is out of range"
5513 " (Min: %d Max: %d)", okcMode,
5514 CFG_OKC_FEATURE_ENABLED_MIN,
5515 CFG_OKC_FEATURE_ENABLED_MAX);
5516 ret = -EINVAL;
5517 goto exit;
5518 }
5519
5520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5521 "%s: Received Command to change okc mode = %d", __func__, okcMode);
5522
5523 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
5524 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005525#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305526 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005527 {
5528 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
5529 char extra[32];
5530 tANI_U8 len = 0;
5531
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005532 len = scnprintf(extra, sizeof(extra), "%s %d",
5533 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05305534 len = VOS_MIN(priv_data.total_len, len + 1);
5535 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5537 "%s: failed to copy data to user buffer", __func__);
5538 ret = -EFAULT;
5539 goto exit;
5540 }
5541 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05305542#ifdef WLAN_FEATURE_PACKET_FILTERING
5543 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
5544 {
5545 tANI_U8 filterType = 0;
5546 tANI_U8 *value = command;
5547
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305548 ret = hdd_drv_cmd_validate(command, 21);
5549 if (ret)
5550 goto exit;
5551
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05305552 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
5553 value = value + 22;
5554
5555 /* Convert the value from ascii to integer */
5556 ret = kstrtou8(value, 10, &filterType);
5557 if (ret < 0)
5558 {
5559 /* If the input value is greater than max value of datatype,
5560 * then also kstrtou8 fails
5561 */
5562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5563 "%s: kstrtou8 failed range ", __func__);
5564 ret = -EINVAL;
5565 goto exit;
5566 }
5567
5568 if (filterType != 0 && filterType != 1)
5569 {
5570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5571 "%s: Accepted Values are 0 and 1 ", __func__);
5572 ret = -EINVAL;
5573 goto exit;
5574 }
5575 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
5576 pAdapter->sessionId);
5577 }
5578#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305579 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
5580 {
Kiet Lamad161252014-07-22 11:23:32 -07005581 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05305582 int ret;
5583
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305584 ret = hdd_drv_cmd_validate(command, 10);
5585 if (ret)
5586 goto exit;
5587
Kiet Lamad161252014-07-22 11:23:32 -07005588 dhcpPhase = command + 11;
5589 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305590 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05305591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07005592 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05305593
5594 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07005595
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05305596 ret = wlan_hdd_scan_abort(pAdapter);
5597 if (ret < 0)
5598 {
5599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5600 FL("failed to abort existing scan %d"), ret);
5601 }
5602
Kiet Lamad161252014-07-22 11:23:32 -07005603 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
5604 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305605 }
Kiet Lamad161252014-07-22 11:23:32 -07005606 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305607 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05305608 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07005609 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05305610
5611 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07005612
5613 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
5614 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305615 }
5616 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005617 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
5618 {
Abhishek Singh58749d62016-02-03 15:27:20 +05305619 hddLog(LOG1,
5620 FL("making default scan to ACTIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05305621 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005622 }
5623 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
5624 {
Abhishek Singh58749d62016-02-03 15:27:20 +05305625 hddLog(LOG1,
5626 FL("making default scan to PASSIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05305627 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005628 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305629 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
5630 {
5631 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5632 char extra[32];
5633 tANI_U8 len = 0;
5634
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05305635 memset(extra, 0, sizeof(extra));
5636 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05305637 len = VOS_MIN(priv_data.total_len, len + 1);
5638 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305639 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5640 "%s: failed to copy data to user buffer", __func__);
5641 ret = -EFAULT;
5642 goto exit;
5643 }
5644 ret = len;
5645 }
5646 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
5647 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05305648 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305649 }
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05305650 else if (strncmp(command, "BTCGETDWELLTIME", 15) == 0)
5651 {
5652 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5653 char extra[32];
5654 tANI_U8 len = 0;
5655
5656 if (hdd_drv_cmd_validate(command, 15)) {
5657 hddLog(LOGE, FL("Invalid driver command"));
5658 return -EINVAL;
5659 }
5660
5661 memset(extra, 0, sizeof(extra));
5662 ret = hdd_btc_get_dwell_time(pCfg, command, extra,
5663 sizeof(extra), &len);
5664 len = VOS_MIN(priv_data.total_len, len + 1);
5665 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
5666 hddLog(LOGE, FL("Failed to copy data to user buffer"));
5667 ret = -EFAULT;
5668 goto exit;
5669 }
5670 ret = len;
5671 }
5672 else if (strncmp(command, "BTCSETDWELLTIME", 15) == 0)
5673 {
5674 if (hdd_drv_cmd_validate(command, 15)) {
5675 hddLog(LOGE, FL("Invalid driver command"));
5676 return -EINVAL;
5677 }
5678 ret = hdd_btc_set_dwell_time(pAdapter, command);
5679 }
5680#ifdef WLAN_AP_STA_CONCURRENCY
5681 else if (strncmp(command, "CONCGETDWELLTIME", 16) == 0)
5682 {
5683 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5684 char extra[32];
5685 tANI_U8 len = 0;
5686
5687 if (hdd_drv_cmd_validate(command, 16)) {
5688 hddLog(LOGE, FL("Invalid driver command"));
5689 return -EINVAL;
5690 }
5691
5692 memset(extra, 0, sizeof(extra));
5693 ret = hdd_conc_get_dwell_time(pCfg, command, extra,
5694 sizeof(extra), &len);
5695 len = VOS_MIN(priv_data.total_len, len + 1);
5696 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
5697 hddLog(LOGE, FL("Failed to copy data to user buffer"));
5698 ret = -EFAULT;
5699 goto exit;
5700 }
5701 ret = len;
5702 }
5703 else if (strncmp(command, "CONCSETDWELLTIME", 16) == 0)
5704 {
5705 if (hdd_drv_cmd_validate(command, 16)) {
5706 hddLog(LOGE, FL("Invalid driver command"));
5707 return -EINVAL;
5708 }
5709 ret = hdd_conc_set_dwell_time(pAdapter, command);
5710 }
5711#endif
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005712 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
5713 {
5714 tANI_U8 filterType = 0;
5715 tANI_U8 *value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305716
5717 ret = hdd_drv_cmd_validate(command, 8);
5718 if (ret)
5719 goto exit;
5720
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005721 value = command + 9;
5722
5723 /* Convert the value from ascii to integer */
5724 ret = kstrtou8(value, 10, &filterType);
5725 if (ret < 0)
5726 {
5727 /* If the input value is greater than max value of datatype,
5728 * then also kstrtou8 fails
5729 */
5730 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5731 "%s: kstrtou8 failed range ", __func__);
5732 ret = -EINVAL;
5733 goto exit;
5734 }
5735 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
5736 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
5737 {
5738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5739 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
5740 " 2-Sink ", __func__);
5741 ret = -EINVAL;
5742 goto exit;
5743 }
5744 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
5745 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05305746 pScanInfo = &pHddCtx->scan_info;
5747 if (filterType && pScanInfo != NULL &&
5748 pHddCtx->scan_info.mScanPending)
5749 {
5750 /*Miracast Session started. Abort Scan */
5751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5752 "%s, Aborting Scan For Miracast",__func__);
5753 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
5754 eCSR_SCAN_ABORT_DEFAULT);
5755 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005756 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05305757 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005758 }
Leo Chang614d2072013-08-22 14:59:44 -07005759 else if (strncmp(command, "SETMCRATE", 9) == 0)
5760 {
Leo Chang614d2072013-08-22 14:59:44 -07005761 tANI_U8 *value = command;
5762 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07005763 tSirRateUpdateInd *rateUpdate;
5764 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07005765
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305766 ret = hdd_drv_cmd_validate(command, 9);
5767 if (ret)
5768 goto exit;
5769
Leo Chang614d2072013-08-22 14:59:44 -07005770 /* Only valid for SAP mode */
5771 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
5772 {
5773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5774 "%s: SAP mode is not running", __func__);
5775 ret = -EFAULT;
5776 goto exit;
5777 }
5778
5779 /* Move pointer to ahead of SETMCRATE<delimiter> */
5780 /* input value is in units of hundred kbps */
5781 value = value + 10;
5782 /* Convert the value from ascii to integer, decimal base */
5783 ret = kstrtouint(value, 10, &targetRate);
5784
Leo Chang1f98cbd2013-10-17 15:03:52 -07005785 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
5786 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07005787 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07005788 hddLog(VOS_TRACE_LEVEL_ERROR,
5789 "%s: SETMCRATE indication alloc fail", __func__);
5790 ret = -EFAULT;
5791 goto exit;
5792 }
5793 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
5794
5795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5796 "MC Target rate %d", targetRate);
5797 /* Ignore unicast */
5798 rateUpdate->ucastDataRate = -1;
5799 rateUpdate->mcastDataRate24GHz = targetRate;
5800 rateUpdate->mcastDataRate5GHz = targetRate;
5801 rateUpdate->mcastDataRate24GHzTxFlag = 0;
5802 rateUpdate->mcastDataRate5GHzTxFlag = 0;
5803 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
5804 if (eHAL_STATUS_SUCCESS != status)
5805 {
5806 hddLog(VOS_TRACE_LEVEL_ERROR,
5807 "%s: SET_MC_RATE failed", __func__);
5808 vos_mem_free(rateUpdate);
5809 ret = -EFAULT;
5810 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07005811 }
5812 }
jge35567202017-06-21 16:39:38 +08005813 else if (strncmp(command, "MAXTXPOWER", 10) == 0)
5814 {
5815 int status;
5816 int txPower;
5817 eHalStatus smeStatus;
5818 tANI_U8 *value = command;
5819 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5820 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5821
5822 status = hdd_parse_setmaxtxpower_command(value, &txPower);
5823 if (status)
5824 {
5825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5826 "Invalid MAXTXPOWER command ");
5827 ret = -EINVAL;
5828 goto exit;
5829 }
5830
5831 hddLog(VOS_TRACE_LEVEL_INFO, "max tx power %d selfMac: "
5832 MAC_ADDRESS_STR " bssId: " MAC_ADDRESS_STR " ",
5833 txPower, MAC_ADDR_ARRAY(selfMac),
5834 MAC_ADDR_ARRAY(bssid));
5835 smeStatus = sme_SetMaxTxPower((tHalHandle)(pHddCtx->hHal),
5836 bssid, selfMac, txPower) ;
5837 if( smeStatus != eHAL_STATUS_SUCCESS )
5838 {
5839 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:Set max tx power failed",
5840 __func__);
5841 ret = -EINVAL;
5842 goto exit;
5843 }
5844
5845 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Set max tx power success",
5846 __func__);
5847 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305848#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08005849 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05305850 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08005851 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05305852 }
5853#endif
Abhishek Singh00b71972016-01-07 10:51:04 +05305854#ifdef WLAN_FEATURE_RMC
5855 else if ((strncasecmp(command, "SETIBSSBEACONOUIDATA", 20) == 0) &&
5856 (WLAN_HDD_IBSS == pAdapter->device_mode))
5857 {
5858 int i = 0;
5859 tANI_U8 *ibss_ie;
5860 tANI_U32 command_len;
5861 tANI_U8 *value = command;
5862 tHalHandle hHal = pHddCtx->hHal;
5863 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5864 tANI_U32 ibss_ie_length;
5865 tANI_U32 len, present;
5866 tANI_U8 *addIE;
5867 tANI_U8 *addIEData;
5868
5869 hddLog(LOG1,
5870 FL(" received command %s"),((char *) value));
5871 /* validate argument of command */
5872 if (strlen(value) <= 21)
5873 {
5874 hddLog(LOGE,
5875 FL("No arguements in command length %zu"), strlen(value));
5876 ret = -EFAULT;
5877 goto exit;
5878 }
5879
5880 /* moving to arguments of commands */
5881 value = value + 21;
5882 command_len = strlen(value);
5883
5884 /* oui_data can't be less than 3 bytes */
5885 if (command_len <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH))
5886 {
5887 hddLog(LOGE,
5888 FL("Invalid SETIBSSBEACONOUIDATA command length %d"),
5889 command_len);
5890 ret = -EFAULT;
5891 goto exit;
5892 }
5893 ibss_ie = vos_mem_malloc(command_len);
5894 if (!ibss_ie) {
5895 hddLog(LOGE,
5896 FL("Could not allocate memory for command length %d"),
5897 command_len);
5898 ret = -ENOMEM;
5899 goto exit;
5900 }
5901 vos_mem_zero(ibss_ie, command_len);
5902
5903 ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie,
5904 command_len);
5905 if (ibss_ie_length < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
5906 hddLog(LOGE, FL("Could not parse command %s return length %d"),
5907 value, ibss_ie_length);
5908 ret = -EFAULT;
5909 vos_mem_free(ibss_ie);
5910 goto exit;
5911 }
5912
5913 hddLog(LOG1, FL("ibss_ie length %d ibss_ie:"), ibss_ie_length);
5914 while (i < ibss_ie_length)
5915 hddLog(LOG1, FL("0x%x"), ibss_ie[i++]);
5916
5917 /* Populate Vendor IE in Beacon */
5918 if ((ccmCfgGetInt(hHal,
5919 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
5920 &present)) != eHAL_STATUS_SUCCESS)
5921 {
5922 hddLog(LOGE,
5923 FL("unable to ftch WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
5924 ret = -EFAULT;
5925 vos_mem_free(ibss_ie);
5926 goto exit;
5927 }
5928
5929 addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5930 if (!addIE) {
5931 hddLog(LOGE,
5932 FL("Could not allocate memory for command length %d"),
5933 command_len);
5934 vos_mem_free(ibss_ie);
5935 ret = -ENOMEM;
5936 goto exit;
5937 }
5938 vos_mem_zero(addIE, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5939
5940 if (present)
5941 {
5942 if ((wlan_cfgGetStrLen(pMac,
5943 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &len)) != eSIR_SUCCESS)
5944 {
5945 hddLog(LOGE,
5946 FL("unable to fetch WNI_CFG_PROBE_RSP_BCN_ADDNIE_LEN"));
5947 ret = -EFAULT;
5948 vos_mem_free(ibss_ie);
5949 vos_mem_free(addIE);
5950 goto exit;
5951 }
5952
5953 if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
5954 ((len + ibss_ie_length) <=
5955 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN))
5956 {
5957 if ((ccmCfgGetStr(hHal,
5958 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, &len))
5959 != eHAL_STATUS_SUCCESS)
5960 {
5961 hddLog(LOGE,
5962 FL("unable to fetch WNI_PROBE_RSP_BCN_ADDNIE_DATA"));
5963 ret = -EFAULT;
5964 vos_mem_free(ibss_ie);
5965 vos_mem_free(addIE);
5966 goto exit;
5967 }
5968 else
5969 {
5970 /* Curruntly only WPA IE is added before Vendor IE
5971 * so we can blindly place the Vendor IE after WPA
5972 * IE. If no WPA IE found replace all with Vendor IE.
5973 */
5974 len = hdd_find_ibss_wpa_ie_pos(addIE, len);
5975 }
5976 }
5977 else
5978 {
5979 hddLog(LOGE,
5980 FL("IE len exceed limit len %d,ibss_ie_length %d "),
5981 len, ibss_ie_length);
5982 ret = -EFAULT;
5983 vos_mem_free(addIE);
5984 vos_mem_free(ibss_ie);
5985 goto exit;
5986 }
5987 }
5988 else {
5989 len = 0;
5990 }
5991
5992 vos_mem_copy (addIE + len , ibss_ie, ibss_ie_length);
5993 len += ibss_ie_length;
5994
5995 if (ccmCfgSetStr(hHal,
5996 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, len, NULL,
5997 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
5998 {
5999 hddLog(LOGE,
6000 FL("unable to set WNI_CFG_PRBE_RSP_BCN_ADDNIE_DATA"));
6001 ret = -EFAULT;
6002 vos_mem_free(ibss_ie);
6003 vos_mem_free(addIE);
6004 goto exit;
6005 }
6006 vos_mem_free(addIE);
6007 if (ccmCfgSetInt(hHal,
6008 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6009 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
6010 {
6011 hddLog(LOGE,
6012 FL("unble to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
6013 ret = -EFAULT;
6014 vos_mem_free(ibss_ie);
6015 goto exit;
6016 }
6017
6018 /* Populate Vendor IE in probe resp */
6019 if ((ccmCfgGetInt(hHal,
6020 WNI_CFG_PROBE_RSP_ADDNIE_FLAG,
6021 &present)) != eHAL_STATUS_SUCCESS)
6022 {
6023 hddLog(LOGE,
6024 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
6025 ret = -EFAULT;
6026 vos_mem_free(ibss_ie);
6027 goto exit;
6028 }
6029
6030 addIEData = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
6031 if (!addIEData) {
6032 hddLog(LOGE,
6033 FL("Could not allocate memory for command length %d"),
6034 command_len);
6035 vos_mem_free(ibss_ie);
6036 ret = -ENOMEM;
6037 goto exit;
6038 }
6039 vos_mem_zero(addIEData, WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
6040
6041 if (present) {
6042 if (eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
6043 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &len)) {
6044 hddLog(LOGE,
6045 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6046 ret = -EFAULT;
6047 vos_mem_free(ibss_ie);
6048 vos_mem_free(addIEData);
6049 goto exit;
6050 }
6051 if (len < WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && len &&
6052 (ibss_ie_length + len) <=
6053 WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN) {
6054
6055 if ((ccmCfgGetStr(hHal,
6056 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, addIEData, &len))
6057 != eHAL_STATUS_SUCCESS) {
6058 hddLog(LOGE,
6059 FL("unable fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6060 ret = -EFAULT;
6061 vos_mem_free(ibss_ie);
6062 vos_mem_free(addIEData);
6063 goto exit;
6064 }
6065 else {
6066 /* Curruntly only WPA IE is added before Vendor IE
6067 * so we can blindly place the Vendor IE after WPA
6068 * IE. If no WPA IE found replace all with Vendor IE.
6069 */
6070 len = hdd_find_ibss_wpa_ie_pos(addIEData, len);
6071 }
6072 }
6073 else
6074 {
6075 hddLog(LOGE,
6076 FL("IE len exceed limit len %d,ibss_ie_length %d "),
6077 len, ibss_ie_length);
6078 ret = -EFAULT;
6079 vos_mem_free(addIEData);
6080 vos_mem_free(ibss_ie);
6081 goto exit;
6082 }
6083 } /* probe rsp ADD IE present */
6084 else {
6085 /* probe rsp add IE is not present */
6086 len = 0;
6087 }
6088
6089 vos_mem_copy(addIEData +len , ibss_ie, ibss_ie_length);
6090 len += ibss_ie_length;
6091
6092 vos_mem_free(ibss_ie);
6093
6094 if (ccmCfgSetStr(hHal,
6095 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6096 (tANI_U8*)(addIEData),
6097 len, NULL,
6098 eANI_BOOLEAN_FALSE)
6099 == eHAL_STATUS_FAILURE) {
6100 hddLog(LOGE,
6101 FL("unable to copy to WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6102 ret = -EFAULT;
6103 vos_mem_free(addIEData);
6104 goto exit;
6105 }
6106 vos_mem_free(addIEData);
6107 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6108 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6109 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6110 {
6111 hddLog(LOGE,
6112 FL("unable to copy WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
6113 ret = -EFAULT;
6114 goto exit;
6115 }
6116 }
6117 else if (strncasecmp(command, "SETRMCENABLE", 12) == 0)
6118 {
6119 tANI_U8 *value = command;
6120 tANI_U8 ucRmcEnable = 0;
6121 int status;
6122
6123 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6124 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6125 {
6126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6127 "Received SETRMCENABLE command in invalid mode %d "
6128 "SETRMCENABLE command is only allowed in IBSS or SOFTAP mode",
6129 pAdapter->device_mode);
6130 ret = -EINVAL;
6131 goto exit;
6132 }
6133
6134 status = hdd_parse_setrmcenable_command(value, &ucRmcEnable);
6135 if (status)
6136 {
6137 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6138 "Invalid SETRMCENABLE command ");
6139 ret = -EINVAL;
6140 goto exit;
6141 }
6142
6143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6144 "%s: ucRmcEnable %d ", __func__, ucRmcEnable);
6145
6146 if (TRUE == ucRmcEnable)
6147 {
6148 status = sme_EnableRMC( (tHalHandle)(pHddCtx->hHal),
6149 pAdapter->sessionId );
6150 }
6151 else if(FALSE == ucRmcEnable)
6152 {
6153 status = sme_DisableRMC( (tHalHandle)(pHddCtx->hHal),
6154 pAdapter->sessionId );
6155 }
6156 else
6157 {
6158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6159 "Invalid SETRMCENABLE command %d", ucRmcEnable);
6160 ret = -EINVAL;
6161 goto exit;
6162 }
6163
6164 if (VOS_STATUS_SUCCESS != status)
6165 {
6166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6167 "%s: SETRMC %d failed status %d", __func__, ucRmcEnable,
6168 status);
6169 ret = -EINVAL;
6170 goto exit;
6171 }
6172 }
6173 else if (strncasecmp(command, "SETRMCACTIONPERIOD", 18) == 0)
6174 {
6175 tANI_U8 *value = command;
6176 tANI_U32 uActionPeriod = 0;
6177 int status;
6178
6179 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6180 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6181 {
6182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6183 "Received SETRMC command in invalid mode %d "
6184 "SETRMC command is only allowed in IBSS or SOFTAP mode",
6185 pAdapter->device_mode);
6186 ret = -EINVAL;
6187 goto exit;
6188 }
6189
6190 status = hdd_parse_setrmcactionperiod_command(value, &uActionPeriod);
6191 if (status)
6192 {
6193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6194 "Invalid SETRMCACTIONPERIOD command ");
6195 ret = -EINVAL;
6196 goto exit;
6197 }
6198
6199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6200 "%s: uActionPeriod %d ", __func__, uActionPeriod);
6201
6202 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
6203 uActionPeriod, NULL, eANI_BOOLEAN_FALSE))
6204 {
6205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6206 "%s: Could not set SETRMCACTIONPERIOD %d", __func__, uActionPeriod);
6207 ret = -EINVAL;
6208 goto exit;
6209 }
6210
6211 }
6212 else if (strncasecmp(command, "GETIBSSPEERINFOALL", 18) == 0)
6213 {
6214 /* Peer Info All Command */
6215 int status = eHAL_STATUS_SUCCESS;
6216 hdd_station_ctx_t *pHddStaCtx = NULL;
6217 char *extra = NULL;
6218 int idx = 0, length = 0;
6219 v_MACADDR_t *macAddr;
6220 v_U32_t txRateMbps = 0, numOfBytestoPrint = 0;
6221
6222 if (WLAN_HDD_IBSS == pAdapter->device_mode)
6223 {
6224 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6225 }
6226 else
6227 {
6228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6229 "%s: pAdapter is not valid for this device mode",
6230 __func__);
6231 ret = -EINVAL;
6232 goto exit;
6233 }
6234
6235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6236 "%s: Received GETIBSSPEERINFOALL Command", __func__);
6237
6238
6239 /* Handle the command */
6240 status = hdd_cfg80211_get_ibss_peer_info_all(pAdapter);
6241 if (VOS_STATUS_SUCCESS == status)
6242 {
6243 /* The variable extra needed to be allocated on the heap since
6244 * amount of memory required to copy the data for 32 devices
6245 * exceeds the size of 1024 bytes of default stack size. On
6246 * 64 bit devices, the default max stack size of 2048 bytes
6247 */
6248 extra = kmalloc(WLAN_MAX_BUF_SIZE, GFP_KERNEL);
6249
6250 if (NULL == extra)
6251 {
6252 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6253 "%s:kmalloc failed", __func__);
6254 ret = -EINVAL;
6255 goto exit;
6256 }
6257
6258 /* Copy number of stations */
6259 length = scnprintf( extra, WLAN_MAX_BUF_SIZE, "%d ",
6260 pHddStaCtx->ibss_peer_info.numIBSSPeers);
6261 numOfBytestoPrint = length;
6262 for (idx = 0; idx < pHddStaCtx->ibss_peer_info.numIBSSPeers; idx++)
6263 {
6264 macAddr =
6265 hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
6266 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
6267 if (NULL != macAddr)
6268 {
6269 txRateMbps =
6270 ((pHddStaCtx->ibss_peer_info.ibssPeerList[idx].txRate)*500*1000)/1000000;
6271
6272 length += scnprintf( (extra + length), WLAN_MAX_BUF_SIZE - length,
6273 "%02x:%02x:%02x:%02x:%02x:%02x %d %d ",
6274 macAddr->bytes[0], macAddr->bytes[1], macAddr->bytes[2],
6275 macAddr->bytes[3], macAddr->bytes[4], macAddr->bytes[5],
6276 (int)txRateMbps,
6277 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[idx].rssi);
6278 }
6279 else
6280 {
6281 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6282 "%s: MAC ADDR is NULL for staIdx: %d", __func__,
6283 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
6284 }
6285
6286 /*
6287 * VOS_TRACE() macro has limitation of 512 bytes for the print
6288 * buffer. Hence printing the data in two chunks. The first chunk
6289 * will have the data for 16 devices and the second chunk will
6290 * have the rest.
6291 */
6292 if (idx < NUM_OF_STA_DATA_TO_PRINT)
6293 {
6294 numOfBytestoPrint = length;
6295 }
6296 }
6297
6298 /*
6299 * Copy the data back into buffer, if the data to copy is
6300 * morethan 512 bytes than we will split the data and do
6301 * it in two shots
6302 */
6303 if (copy_to_user(priv_data.buf, extra, numOfBytestoPrint))
6304 {
6305 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6306 "%s: Copy into user data buffer failed ", __func__);
6307 ret = -EFAULT;
6308 kfree(extra);
6309 goto exit;
6310 }
6311 priv_data.buf[numOfBytestoPrint] = '\0';
6312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6313 "%s", priv_data.buf);
6314
6315 if (length > numOfBytestoPrint)
6316 {
6317 if (copy_to_user(priv_data.buf + numOfBytestoPrint,
6318 extra + numOfBytestoPrint,
6319 length - numOfBytestoPrint + 1))
6320 {
6321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6322 "%s: Copy into user data buffer failed ", __func__);
6323 ret = -EFAULT;
6324 kfree(extra);
6325 goto exit;
6326 }
6327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6328 "%s", &priv_data.buf[numOfBytestoPrint]);
6329 }
6330
6331 /* Free temporary buffer */
6332 kfree(extra);
6333 }
6334
6335 else
6336 {
6337 /* Command failed, log error */
6338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6339 "%s: GETIBSSPEERINFOALL command failed with status code %d",
6340 __func__, status);
6341 ret = -EINVAL;
6342 goto exit;
6343 }
6344 ret = 0;
6345 }
6346 else if(strncasecmp(command, "GETIBSSPEERINFO", 15) == 0)
6347 {
6348 /* Peer Info <Peer Addr> command */
6349 tANI_U8 *value = command;
6350 VOS_STATUS status;
6351 hdd_station_ctx_t *pHddStaCtx = NULL;
6352 char extra[128] = { 0 };
6353 v_U32_t length = 0;
6354 v_U8_t staIdx = 0;
6355 v_U32_t txRateMbps = 0;
6356 v_MACADDR_t peerMacAddr;
6357
6358 if (WLAN_HDD_IBSS == pAdapter->device_mode)
6359 {
6360 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6361 }
6362 else
6363 {
6364 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6365 "%s: pAdapter is not valid for this device mode",
6366 __func__);
6367 ret = -EINVAL;
6368 goto exit;
6369 }
6370
6371 /* if there are no peers, no need to continue with the command */
6372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6373 "%s: Received GETIBSSPEERINFO Command", __func__);
6374
6375 if (eConnectionState_IbssConnected != pHddStaCtx->conn_info.connState)
6376 {
6377 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6378 "%s:No IBSS Peers coalesced", __func__);
6379 ret = -EINVAL;
6380 goto exit;
6381 }
6382
6383 /* Parse the incoming command buffer */
6384 status = hdd_parse_get_ibss_peer_info(value, &peerMacAddr);
6385 if (VOS_STATUS_SUCCESS != status)
6386 {
6387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6388 "%s: Invalid GETIBSSPEERINFO command", __func__);
6389 ret = -EINVAL;
6390 goto exit;
6391 }
6392
6393 /* Get station index for the peer mac address */
6394 hdd_Ibss_GetStaId(pHddStaCtx, &peerMacAddr, &staIdx);
6395
6396 if (staIdx > HDD_MAX_NUM_IBSS_STA)
6397 {
6398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6399 "%s: Invalid StaIdx %d returned", __func__, staIdx);
6400 ret = -EINVAL;
6401 goto exit;
6402 }
6403
6404 /* Handle the command */
6405 status = hdd_cfg80211_get_ibss_peer_info(pAdapter, staIdx);
6406 if (VOS_STATUS_SUCCESS == status)
6407 {
6408 v_U32_t txRate = pHddStaCtx->ibss_peer_info.ibssPeerList[0].txRate;
6409 txRateMbps = (txRate * 500 * 1000)/1000000;
6410
6411 length = scnprintf( extra, sizeof(extra), "%d %d", (int)txRateMbps,
6412 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[0].rssi);
6413
6414 /* Copy the data back into buffer */
6415 if (copy_to_user(priv_data.buf, &extra, length+ 1))
6416 {
6417 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6418 "%s: copy data to user buffer failed GETIBSSPEERINFO command",
6419 __func__);
6420 ret = -EFAULT;
6421 goto exit;
6422 }
6423 }
6424 else
6425 {
6426 /* Command failed, log error */
6427 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6428 "%s: GETIBSSPEERINFO command failed with status code %d",
6429 __func__, status);
6430 ret = -EINVAL;
6431 goto exit;
6432 }
6433
6434 /* Success ! */
6435 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6436 "%s", priv_data.buf);
6437 ret = 0;
6438 }
6439 else if (strncasecmp(command, "SETRMCTXRATE", 12) == 0)
6440 {
6441 tANI_U8 *value = command;
6442 tANI_U32 uRate = 0;
6443 tTxrateinfoflags txFlags = 0;
6444 tSirRateUpdateInd *rateUpdateParams;
6445 int status;
6446
6447 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6448 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6449 {
6450 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6451 "Received SETRMCTXRATE command in invalid mode %d "
6452 "SETRMC command is only allowed in IBSS or SOFTAP mode",
6453 pAdapter->device_mode);
6454 ret = -EINVAL;
6455 goto exit;
6456 }
6457
6458 status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags);
6459 if (status)
6460 {
6461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6462 "Invalid SETRMCTXRATE command ");
6463 ret = -EINVAL;
6464 goto exit;
6465 }
6466
6467 rateUpdateParams = vos_mem_malloc(sizeof(tSirRateUpdateInd));
6468 if (NULL == rateUpdateParams)
6469 {
6470 ret = -EINVAL;
6471 goto exit;
6472 }
6473
6474 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6475 "%s: uRate %d ", __func__, uRate);
6476
6477 vos_mem_zero(rateUpdateParams, sizeof(tSirRateUpdateInd ));
6478
6479 /* -1 implies ignore this param */
6480 rateUpdateParams->ucastDataRate = -1;
6481
6482 /*
6483 * Fill the user specifieed RMC rate param
6484 * and the derived tx flags.
6485 */
6486 rateUpdateParams->rmcDataRate = uRate;
6487 rateUpdateParams->rmcDataRateTxFlag = txFlags;
6488
6489 status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), rateUpdateParams);
6490 }
6491 else if (strncasecmp(command, "SETIBSSTXFAILEVENT", 18) == 0 )
6492 {
6493 char *value;
6494 tANI_U8 tx_fail_count = 0;
6495 tANI_U16 pid = 0;
6496
6497 value = command;
6498
6499 ret = hdd_ParseIBSSTXFailEventParams(value, &tx_fail_count, &pid);
6500
6501 if (0 != ret)
6502 {
6503 hddLog(VOS_TRACE_LEVEL_INFO,
6504 "%s: Failed to parse SETIBSSTXFAILEVENT arguments",
6505 __func__);
6506 goto exit;
6507 }
6508
6509 hddLog(VOS_TRACE_LEVEL_INFO, "%s: tx_fail_cnt=%hhu, pid=%hu",
6510 __func__, tx_fail_count, pid);
6511
6512 if (0 == tx_fail_count)
6513 {
6514 // Disable TX Fail Indication
6515 if (eHAL_STATUS_SUCCESS ==
6516 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
6517 tx_fail_count,
6518 NULL))
6519 {
6520 cesium_pid = 0;
6521 }
6522 else
6523 {
6524 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6525 "%s: failed to disable TX Fail Event ", __func__);
6526 ret = -EINVAL;
6527 }
6528 }
6529 else
6530 {
6531 if (eHAL_STATUS_SUCCESS ==
6532 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
6533 tx_fail_count,
6534 (void*)hdd_tx_fail_ind_callback))
6535 {
6536 cesium_pid = pid;
6537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6538 "%s: Registered Cesium pid %u", __func__,
6539 cesium_pid);
6540 }
6541 else
6542 {
6543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6544 "%s: Failed to enable TX Fail Monitoring", __func__);
6545 ret = -EINVAL;
6546 }
6547 }
6548 }
6549
6550#endif /* WLAN_FEATURE_RMC */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006551#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006552 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
6553 {
6554 tANI_U8 *value = command;
6555 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
6556 tANI_U8 numChannels = 0;
6557 eHalStatus status = eHAL_STATUS_SUCCESS;
6558
6559 status = hdd_parse_channellist(value, ChannelList, &numChannels);
6560 if (eHAL_STATUS_SUCCESS != status)
6561 {
6562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6563 "%s: Failed to parse channel list information", __func__);
6564 ret = -EINVAL;
6565 goto exit;
6566 }
6567
6568 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
6569 {
6570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6571 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
6572 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
6573 ret = -EINVAL;
6574 goto exit;
6575 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006576 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006577 ChannelList,
6578 numChannels);
6579 if (eHAL_STATUS_SUCCESS != status)
6580 {
6581 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6582 "%s: Failed to update channel list information", __func__);
6583 ret = -EINVAL;
6584 goto exit;
6585 }
6586 }
6587 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
6588 {
6589 tANI_U8 *value = command;
6590 char extra[128] = {0};
6591 int len = 0;
6592 tANI_U8 tid = 0;
6593 hdd_station_ctx_t *pHddStaCtx = NULL;
6594 tAniTrafStrmMetrics tsmMetrics;
6595 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6596
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306597 ret = hdd_drv_cmd_validate(command, 11);
6598 if (ret)
6599 goto exit;
6600
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006601 /* if not associated, return error */
6602 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6603 {
6604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
6605 ret = -EINVAL;
6606 goto exit;
6607 }
6608
6609 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
6610 value = value + 12;
6611 /* Convert the value from ascii to integer */
6612 ret = kstrtou8(value, 10, &tid);
6613 if (ret < 0)
6614 {
6615 /* If the input value is greater than max value of datatype, then also
6616 kstrtou8 fails */
6617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6618 "%s: kstrtou8 failed range [%d - %d]", __func__,
6619 TID_MIN_VALUE,
6620 TID_MAX_VALUE);
6621 ret = -EINVAL;
6622 goto exit;
6623 }
6624
6625 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
6626 {
6627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6628 "tid value %d is out of range"
6629 " (Min: %d Max: %d)", tid,
6630 TID_MIN_VALUE,
6631 TID_MAX_VALUE);
6632 ret = -EINVAL;
6633 goto exit;
6634 }
6635
6636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6637 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
6638
6639 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
6640 {
6641 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6642 "%s: failed to get tsm stats", __func__);
6643 ret = -EFAULT;
6644 goto exit;
6645 }
6646
6647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6648 "UplinkPktQueueDly(%d)\n"
6649 "UplinkPktQueueDlyHist[0](%d)\n"
6650 "UplinkPktQueueDlyHist[1](%d)\n"
6651 "UplinkPktQueueDlyHist[2](%d)\n"
6652 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05306653 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006654 "UplinkPktLoss(%d)\n"
6655 "UplinkPktCount(%d)\n"
6656 "RoamingCount(%d)\n"
6657 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
6658 tsmMetrics.UplinkPktQueueDlyHist[0],
6659 tsmMetrics.UplinkPktQueueDlyHist[1],
6660 tsmMetrics.UplinkPktQueueDlyHist[2],
6661 tsmMetrics.UplinkPktQueueDlyHist[3],
6662 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
6663 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
6664
6665 /* Output TSM stats is of the format
6666 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
6667 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006668 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006669 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
6670 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
6671 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
6672 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
6673 tsmMetrics.RoamingDly);
6674
Ratnam Rachurid53009c2015-08-07 13:59:00 +05306675 len = VOS_MIN(priv_data.total_len, len + 1);
6676 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006677 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6678 "%s: failed to copy data to user buffer", __func__);
6679 ret = -EFAULT;
6680 goto exit;
6681 }
6682 }
6683 else if (strncmp(command, "SETCCKMIE", 9) == 0)
6684 {
6685 tANI_U8 *value = command;
6686 tANI_U8 *cckmIe = NULL;
6687 tANI_U8 cckmIeLen = 0;
6688 eHalStatus status = eHAL_STATUS_SUCCESS;
6689
6690 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
6691 if (eHAL_STATUS_SUCCESS != status)
6692 {
6693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6694 "%s: Failed to parse cckm ie data", __func__);
6695 ret = -EINVAL;
6696 goto exit;
6697 }
6698
6699 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
6700 {
6701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6702 "%s: CCKM Ie input length is more than max[%d]", __func__,
6703 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006704 vos_mem_free(cckmIe);
6705 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006706 ret = -EINVAL;
6707 goto exit;
6708 }
6709 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006710 vos_mem_free(cckmIe);
6711 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006712 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006713 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
6714 {
6715 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006716 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006717 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07006718
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006719 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006720 if (eHAL_STATUS_SUCCESS != status)
6721 {
6722 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006723 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006724 ret = -EINVAL;
6725 goto exit;
6726 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07006727 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6728 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
6729 hdd_indicateEseBcnReportNoResults (pAdapter,
6730 eseBcnReq.bcnReq[0].measurementToken,
6731 0x02, //BIT(1) set for measurement done
6732 0); // no BSS
6733 goto exit;
6734 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006735
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006736 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
6737 if (eHAL_STATUS_SUCCESS != status)
6738 {
6739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6740 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
6741 ret = -EINVAL;
6742 goto exit;
6743 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006744 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006745#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05306746 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
6747 {
6748 eHalStatus status;
6749 char buf[32], len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306750 void *cookie;
6751 struct hdd_request *request;
6752 struct bcn_miss_rate_priv *priv;
6753 static const struct hdd_request_params params = {
6754 .priv_size = sizeof(*priv),
6755 .timeout_ms = WLAN_WAIT_TIME_STATS,
6756 };
c_hpothu92367912014-05-01 15:18:17 +05306757
6758 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6759
6760 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6761 {
6762 hddLog(VOS_TRACE_LEVEL_WARN,
6763 FL("GETBCNMISSRATE: STA is not in connected state"));
6764 ret = -1;
6765 goto exit;
6766 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306767 request = hdd_request_alloc(&params);
6768 if (!request) {
6769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6770 ret = -ENOMEM;
6771 goto exit;
6772 }
6773 cookie = hdd_request_cookie(request);
6774 priv = hdd_request_priv(request);
6775 priv->bcn_miss_rate = -1;
c_hpothu92367912014-05-01 15:18:17 +05306776
6777 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
6778 pAdapter->sessionId,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306779 (void *)get_bcn_miss_rate_cb,
6780 cookie);
c_hpothu92367912014-05-01 15:18:17 +05306781 if( eHAL_STATUS_SUCCESS != status)
6782 {
6783 hddLog(VOS_TRACE_LEVEL_INFO,
6784 FL("GETBCNMISSRATE: fail to post WDA cmd"));
6785 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306786 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306787 }
6788
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306789 ret = hdd_request_wait_for_response(request);
6790 if(ret)
c_hpothu92367912014-05-01 15:18:17 +05306791 {
6792 hddLog(VOS_TRACE_LEVEL_ERROR,
6793 FL("failed to wait on bcnMissRateComp %d"), ret);
6794
c_hpothu92367912014-05-01 15:18:17 +05306795 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306796 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306797 }
6798
6799 hddLog(VOS_TRACE_LEVEL_INFO,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306800 FL("GETBCNMISSRATE: bcnMissRate: %d"), priv->bcn_miss_rate);
c_hpothu92367912014-05-01 15:18:17 +05306801
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306802 if (priv->bcn_miss_rate == -1) {
6803 ret = -EFAULT;
6804 goto free_bcn_miss_rate_req;
6805 }
6806
6807 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d",
6808 priv->bcn_miss_rate);
c_hpothu92367912014-05-01 15:18:17 +05306809 if (copy_to_user(priv_data.buf, &buf, len + 1))
6810 {
6811 hddLog(VOS_TRACE_LEVEL_ERROR,
6812 "%s: failed to copy data to user buffer", __func__);
6813 ret = -EFAULT;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306814 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306815 }
6816 ret = len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306817
6818free_bcn_miss_rate_req:
6819 hdd_request_put(request);
c_hpothu92367912014-05-01 15:18:17 +05306820 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306821#ifdef FEATURE_WLAN_TDLS
6822 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
6823 tANI_U8 *value = command;
6824 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306825
6826 ret = hdd_drv_cmd_validate(command, 26);
6827 if (ret)
6828 goto exit;
6829
Atul Mittal87ec2422014-09-24 13:12:50 +05306830 /* Move pointer to ahead of TDLSOFFCH*/
6831 value += 26;
c_manjeebbc40212015-12-08 13:52:59 +05306832 if (!(sscanf(value, "%d", &set_value))) {
6833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6834 FL("No input identified"));
6835 ret = -EINVAL;
6836 goto exit;
6837 }
6838
Atul Mittal87ec2422014-09-24 13:12:50 +05306839 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6840 "%s: Tdls offchannel offset:%d",
6841 __func__, set_value);
6842 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
6843 if (ret < 0)
6844 {
6845 ret = -EINVAL;
6846 goto exit;
6847 }
6848
6849 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
6850 tANI_U8 *value = command;
6851 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306852
6853 ret = hdd_drv_cmd_validate(command, 18);
6854 if (ret)
6855 goto exit;
6856
Atul Mittal87ec2422014-09-24 13:12:50 +05306857 /* Move pointer to ahead of tdlsoffchnmode*/
6858 value += 18;
c_manjee82323892015-12-08 12:40:34 +05306859 ret = sscanf(value, "%d", &set_value);
6860 if (ret != 1) {
6861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6862 FL("No input identified"));
6863 ret = -EINVAL;
6864 goto exit;
6865 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6867 "%s: Tdls offchannel mode:%d",
6868 __func__, set_value);
6869 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
6870 if (ret < 0)
6871 {
6872 ret = -EINVAL;
6873 goto exit;
6874 }
6875 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
6876 tANI_U8 *value = command;
6877 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306878
6879 ret = hdd_drv_cmd_validate(command, 14);
6880 if (ret)
6881 goto exit;
6882
Atul Mittal87ec2422014-09-24 13:12:50 +05306883 /* Move pointer to ahead of TDLSOFFCH*/
6884 value += 14;
c_manjeef6ccaf52015-12-08 11:52:11 +05306885 ret = sscanf(value, "%d", &set_value);
6886 if (ret != 1) {
6887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6888 "Wrong value is given for hdd_set_tdls_offchannel");
6889 ret = -EINVAL;
6890 goto exit;
6891 }
6892
Atul Mittal87ec2422014-09-24 13:12:50 +05306893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6894 "%s: Tdls offchannel num: %d",
6895 __func__, set_value);
6896 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
6897 if (ret < 0)
6898 {
6899 ret = -EINVAL;
6900 goto exit;
6901 }
6902 }
6903#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05306904 else if (strncmp(command, "GETFWSTATS", 10) == 0)
6905 {
6906 eHalStatus status;
6907 char *buf = NULL;
6908 char len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306909 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp),
6910 *fw_stats_result;
Satyanarayana Dash72806012014-12-02 14:30:08 +05306911 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306912 int stats;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306913 void *cookie;
6914 struct hdd_request *request;
6915 struct fw_stats_priv *priv;
6916 static const struct hdd_request_params params = {
6917 .priv_size = sizeof(*priv),
6918 .timeout_ms = WLAN_WAIT_TIME_STATS,
6919 };
Satyanarayana Dash72806012014-12-02 14:30:08 +05306920
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306921 ret = hdd_drv_cmd_validate(command, 10);
6922 if (ret)
6923 goto exit;
6924
6925 stats = *(ptr + 11) - '0';
Satyanarayana Dash72806012014-12-02 14:30:08 +05306926 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
6927 if (!IS_FEATURE_FW_STATS_ENABLE)
6928 {
6929 hddLog(VOS_TRACE_LEVEL_INFO,
6930 FL("Get Firmware stats feature not supported"));
6931 ret = -EINVAL;
6932 goto exit;
6933 }
6934
6935 if (FW_STATS_MAX <= stats || 0 >= stats)
6936 {
6937 hddLog(VOS_TRACE_LEVEL_INFO,
6938 FL(" stats %d not supported"),stats);
6939 ret = -EINVAL;
6940 goto exit;
6941 }
6942
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306943 request = hdd_request_alloc(&params);
6944 if (!request) {
6945 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6946 ret = -ENOMEM;
6947 goto exit;
6948 }
6949 cookie = hdd_request_cookie(request);
6950
Satyanarayana Dash72806012014-12-02 14:30:08 +05306951 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306952 cookie, hdd_fw_stats_cb);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306953 if (eHAL_STATUS_SUCCESS != status)
6954 {
6955 hddLog(VOS_TRACE_LEVEL_ERROR,
6956 FL(" fail to post WDA cmd status = %d"), status);
6957 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306958 hdd_request_put(request);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306959 goto exit;
6960 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306961 ret = hdd_request_wait_for_response(request);
6962 if (ret)
Satyanarayana Dash72806012014-12-02 14:30:08 +05306963 {
6964 hddLog(VOS_TRACE_LEVEL_ERROR,
6965 FL("failed to wait on GwtFwstats"));
Satyanarayana Dash72806012014-12-02 14:30:08 +05306966 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306967 hdd_request_put(request);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306968 goto exit;
6969 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306970
6971 priv = hdd_request_priv(request);
6972 fw_stats_result = priv->fw_stats;
6973 fwStatsRsp->type = 0;
6974 if (NULL != fw_stats_result)
6975 {
6976 switch (fw_stats_result->type )
6977 {
6978 case FW_UBSP_STATS:
6979 {
6980 tSirUbspFwStats *stats =
6981 &fwStatsRsp->fwStatsData.ubspStats;
6982 memcpy(fwStatsRsp, fw_stats_result,
6983 sizeof(tSirFwStatsResult));
6984 hddLog(VOS_TRACE_LEVEL_INFO,
6985 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
6986 stats->ubsp_enter_cnt,
6987 stats->ubsp_jump_ddr_cnt);
6988 }
6989 break;
6990
6991 default:
6992 {
6993 hddLog(VOS_TRACE_LEVEL_ERROR,
6994 FL("No handling for stats type %d"),
6995 fw_stats_result->type);
6996 }
6997 }
6998 }
6999 hdd_request_put(request);
7000
Satyanarayana Dash72806012014-12-02 14:30:08 +05307001 if (fwStatsRsp->type)
7002 {
7003 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
7004 if (!buf)
7005 {
7006 hddLog(VOS_TRACE_LEVEL_ERROR,
7007 FL(" failed to allocate memory"));
7008 ret = -ENOMEM;
7009 goto exit;
7010 }
7011 switch( fwStatsRsp->type )
7012 {
7013 case FW_UBSP_STATS:
7014 {
7015 len = snprintf(buf, FW_STATE_RSP_LEN,
7016 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05307017 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
7018 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05307019 }
7020 break;
7021 default:
7022 {
7023 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
7024 ret = -EFAULT;
7025 kfree(buf);
7026 goto exit;
7027 }
7028 }
7029 if (copy_to_user(priv_data.buf, buf, len + 1))
7030 {
7031 hddLog(VOS_TRACE_LEVEL_ERROR,
7032 FL(" failed to copy data to user buffer"));
7033 ret = -EFAULT;
7034 kfree(buf);
7035 goto exit;
7036 }
7037 ret = len;
7038 kfree(buf);
7039 }
7040 else
7041 {
7042 hddLog(VOS_TRACE_LEVEL_ERROR,
7043 FL("failed to fetch the stats"));
7044 ret = -EFAULT;
7045 goto exit;
7046 }
Satyanarayana Dash72806012014-12-02 14:30:08 +05307047 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05307048 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
7049 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05307050 ret = hdd_drv_cmd_validate(command, 15);
7051 if (ret)
7052 goto exit;
7053
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05307054 /*
7055 * this command wld be called by user-space when it detects WLAN
7056 * ON after airplane mode is set. When APM is set, WLAN turns off.
7057 * But it can be turned back on. Otherwise; when APM is turned back
7058 * off, WLAN wld turn back on. So at that point the command is
7059 * expected to come down. 0 means disable, 1 means enable. The
7060 * constraint is removed when parameter 1 is set or different
7061 * country code is set
7062 */
7063 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
7064 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05307065 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
7066 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05307067 ret = hdd_drv_cmd_validate(command, 16);
7068 if (ret)
7069 goto exit;
7070
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05307071 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
7072 }
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05307073 /*
7074 * command should be a string having format
7075 * SET_DISABLE_CHANNEL_LIST <num of channels>
7076 * <channels separated by spaces>
7077 */
7078 else if (strncmp(command, "SET_DISABLE_CHANNEL_LIST", 24) == 0) {
7079 tANI_U8 *ptr = command;
7080 ret = hdd_drv_cmd_validate(command, 24);
7081 if (ret)
7082 goto exit;
7083
7084 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7085 " Received Command to disable Channels %s",
7086 __func__);
7087 ret = hdd_parse_disable_chan_cmd(pAdapter, ptr);
7088 if (ret)
7089 goto exit;
7090 }
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307091 else if (strncmp(command, "GET_DISABLE_CHANNEL_LIST", 24) == 0) {
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307092 char extra[512] = {0};
7093 int max_len, copied_length;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05307094
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307096 " Received Command to get disable Channels list %s",
7097 __func__);
7098
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307099 max_len = VOS_MIN(priv_data.total_len, sizeof(extra));
7100 copied_length = hdd_get_disable_ch_list(pHddCtx, extra, max_len);
7101 if (copied_length == 0) {
7102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307103 FL("disable channel list are not yet programed"));
7104 ret = -EINVAL;
7105 goto exit;
7106 }
7107
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307108 if (copy_to_user(priv_data.buf, &extra, copied_length + 1)) {
7109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7110 "%s: failed to copy data to user buffer", __func__);
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307111 ret = -EFAULT;
7112 goto exit;
7113 }
7114
7115 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7116 FL("data:%s"), extra);
7117 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07007118 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307119 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7120 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
7121 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05307122 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
7123 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07007124 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007125 }
7126exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307127 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007128 if (command)
7129 {
7130 kfree(command);
7131 }
7132 return ret;
7133}
7134
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007135#ifdef CONFIG_COMPAT
7136static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7137{
7138 struct {
7139 compat_uptr_t buf;
7140 int used_len;
7141 int total_len;
7142 } compat_priv_data;
7143 hdd_priv_data_t priv_data;
7144 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007145
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007146 /*
7147 * Note that pAdapter and ifr have already been verified by caller,
7148 * and HDD context has also been validated
7149 */
7150 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
7151 sizeof(compat_priv_data))) {
7152 ret = -EFAULT;
7153 goto exit;
7154 }
7155 priv_data.buf = compat_ptr(compat_priv_data.buf);
7156 priv_data.used_len = compat_priv_data.used_len;
7157 priv_data.total_len = compat_priv_data.total_len;
7158 ret = hdd_driver_command(pAdapter, &priv_data);
7159 exit:
7160 return ret;
7161}
7162#else /* CONFIG_COMPAT */
7163static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7164{
7165 /* will never be invoked */
7166 return 0;
7167}
7168#endif /* CONFIG_COMPAT */
7169
7170static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7171{
7172 hdd_priv_data_t priv_data;
7173 int ret = 0;
7174
7175 /*
7176 * Note that pAdapter and ifr have already been verified by caller,
7177 * and HDD context has also been validated
7178 */
7179 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
7180 ret = -EFAULT;
7181 } else {
7182 ret = hdd_driver_command(pAdapter, &priv_data);
7183 }
7184 return ret;
7185}
7186
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307187int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007188{
7189 hdd_adapter_t *pAdapter;
7190 hdd_context_t *pHddCtx;
7191 int ret;
7192
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307193 ENTER();
7194
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007195 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7196 if (NULL == pAdapter) {
7197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7198 "%s: HDD adapter context is Null", __func__);
7199 ret = -ENODEV;
7200 goto exit;
7201 }
7202 if (dev != pAdapter->dev) {
7203 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7204 "%s: HDD adapter/dev inconsistency", __func__);
7205 ret = -ENODEV;
7206 goto exit;
7207 }
7208
7209 if ((!ifr) || (!ifr->ifr_data)) {
7210 ret = -EINVAL;
7211 goto exit;
7212 }
7213
7214 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7215 ret = wlan_hdd_validate_context(pHddCtx);
7216 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007217 ret = -EBUSY;
7218 goto exit;
7219 }
7220
7221 switch (cmd) {
7222 case (SIOCDEVPRIVATE + 1):
7223 if (is_compat_task())
7224 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
7225 else
7226 ret = hdd_driver_ioctl(pAdapter, ifr);
7227 break;
7228 default:
7229 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
7230 __func__, cmd);
7231 ret = -EINVAL;
7232 break;
7233 }
7234 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307235 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007236 return ret;
7237}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007238
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307239int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7240{
7241 int ret;
7242
7243 vos_ssr_protect(__func__);
7244 ret = __hdd_ioctl(dev, ifr, cmd);
7245 vos_ssr_unprotect(__func__);
7246
7247 return ret;
7248}
7249
Katya Nigame7b69a82015-04-28 15:24:06 +05307250int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7251{
7252 return 0;
7253}
7254
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007255#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007256/**---------------------------------------------------------------------------
7257
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007258 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007259
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007260 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007261 CCXBEACONREQ<space><Number of fields><space><Measurement token>
7262 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
7263 <space>Scan Mode N<space>Meas Duration N
7264 if the Number of bcn req fields (N) does not match with the actual number of fields passed
7265 then take N.
7266 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
7267 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
7268 This function does not take care of removing duplicate channels from the list
7269
7270 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007271 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007272
7273 \return - 0 for success non-zero for failure
7274
7275 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007276static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
7277 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007278{
7279 tANI_U8 *inPtr = pValue;
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307280 uint8_t input = 0;
7281 uint32_t tempInt = 0;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007282 int j = 0, i = 0, v = 0;
7283 char buf[32];
7284
7285 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7286 /*no argument after the command*/
7287 if (NULL == inPtr)
7288 {
7289 return -EINVAL;
7290 }
7291 /*no space after the command*/
7292 else if (SPACE_ASCII_VALUE != *inPtr)
7293 {
7294 return -EINVAL;
7295 }
7296
7297 /*removing empty spaces*/
7298 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
7299
7300 /*no argument followed by spaces*/
7301 if ('\0' == *inPtr) return -EINVAL;
7302
7303 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007304 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007305 if (1 != v) return -EINVAL;
7306
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307307 v = kstrtos8(buf, 10, &input);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007308 if ( v < 0) return -EINVAL;
7309
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307310 input = VOS_MIN(input, SIR_ESE_MAX_MEAS_IE_REQS);
7311 pEseBcnReq->numBcnReqIe = input;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007312
Srinivas Girigowda725a88e2016-03-31 19:24:25 +05307313 hddLog(LOG1, "Number of Bcn Req Ie fields: %d", pEseBcnReq->numBcnReqIe);
7314
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007315
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007316 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007317 {
7318 for (i = 0; i < 4; i++)
7319 {
7320 /*inPtr pointing to the beginning of first space after number of ie fields*/
7321 inPtr = strpbrk( inPtr, " " );
7322 /*no ie data after the number of ie fields argument*/
7323 if (NULL == inPtr) return -EINVAL;
7324
7325 /*removing empty space*/
7326 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
7327
7328 /*no ie data after the number of ie fields argument and spaces*/
7329 if ( '\0' == *inPtr ) return -EINVAL;
7330
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007331 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007332 if (1 != v) return -EINVAL;
7333
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307334 v = kstrtou32(buf, 10, &tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007335 if (v < 0) return -EINVAL;
7336
7337 switch (i)
7338 {
7339 case 0: /* Measurement token */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307340 if (!tempInt)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007341 {
7342 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307343 "Invalid Measurement Token: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007344 return -EINVAL;
7345 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007346 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007347 break;
7348
7349 case 1: /* Channel number */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307350 if ((!tempInt) ||
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007351 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7352 {
7353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307354 "Invalid Channel Number: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007355 return -EINVAL;
7356 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007357 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007358 break;
7359
7360 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08007361 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007362 {
7363 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307364 "Invalid Scan Mode(%u) Expected{0|1|2}", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007365 return -EINVAL;
7366 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007367 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007368 break;
7369
7370 case 3: /* Measurement duration */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307371 if (((!tempInt) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
7372 ((pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007373 {
7374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307375 "Invalid Measurement Duration: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007376 return -EINVAL;
7377 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007378 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007379 break;
7380 }
7381 }
7382 }
7383
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007384 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007385 {
7386 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05307387 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007388 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007389 pEseBcnReq->bcnReq[j].measurementToken,
7390 pEseBcnReq->bcnReq[j].channel,
7391 pEseBcnReq->bcnReq[j].scanMode,
7392 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007393 }
7394
7395 return VOS_STATUS_SUCCESS;
7396}
7397
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307398struct tsm_priv {
7399 tAniTrafStrmMetrics tsm_metrics;
7400};
7401
7402static void hdd_get_tsm_stats_cb(tAniTrafStrmMetrics tsm_metrics,
7403 const tANI_U32 sta_id, void *context )
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007404{
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307405 struct hdd_request *request;
7406 struct tsm_priv *priv;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007407
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307408 ENTER();
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007409
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307410 request = hdd_request_get(context);
7411 if (!request) {
7412 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
7413 return;
7414 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007415
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307416 priv = hdd_request_priv(request);
7417 priv->tsm_metrics = tsm_metrics;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007418
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307419 hdd_request_complete(request);
7420 hdd_request_put(request);
Jeff Johnson72a40512013-12-19 10:14:15 -08007421
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307422 EXIT();
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007423}
7424
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007425static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
7426 tAniTrafStrmMetrics* pTsmMetrics)
7427{
7428 hdd_station_ctx_t *pHddStaCtx = NULL;
7429 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08007430 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007431 hdd_context_t *pHddCtx = NULL;
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307432 int ret;
7433 void *cookie;
7434 struct hdd_request *request;
7435 struct tsm_priv *priv;
7436 static const struct hdd_request_params params = {
7437 .priv_size = sizeof(*priv),
7438 .timeout_ms = WLAN_WAIT_TIME_STATS,
7439 };
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007440
7441 if (NULL == pAdapter)
7442 {
7443 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
7444 return VOS_STATUS_E_FAULT;
7445 }
7446
7447 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7448 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7449
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307450 request = hdd_request_alloc(&params);
7451 if (!request) {
7452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
7453 return VOS_STATUS_E_NOMEM;
7454 }
7455 cookie = hdd_request_cookie(request);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007456
7457 /* query tsm stats */
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307458 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_get_tsm_stats_cb,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007459 pHddStaCtx->conn_info.staId[ 0 ],
7460 pHddStaCtx->conn_info.bssId,
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307461 cookie, pHddCtx->pvosContext, tid);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007462
7463 if (eHAL_STATUS_SUCCESS != hstatus)
7464 {
Jeff Johnson72a40512013-12-19 10:14:15 -08007465 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
7466 __func__);
7467 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007468 }
7469 else
7470 {
7471 /* request was sent -- wait for the response */
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307472 ret = hdd_request_wait_for_response(request);
7473 if (ret) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007474 hddLog(VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307475 "SME timeout while retrieving statistics");
Jeff Johnson72a40512013-12-19 10:14:15 -08007476 vstatus = VOS_STATUS_E_TIMEOUT;
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307477 } else {
7478 priv = hdd_request_priv(request);
7479 *pTsmMetrics = priv->tsm_metrics;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007480 }
7481 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007482
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307483 hdd_request_put(request);
Jeff Johnson72a40512013-12-19 10:14:15 -08007484
Jeff Johnson72a40512013-12-19 10:14:15 -08007485 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007486}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007487#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007488
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007489#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08007490void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
7491{
7492 eCsrBand band = -1;
7493 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
7494 switch (band)
7495 {
7496 case eCSR_BAND_ALL:
7497 *pBand = WLAN_HDD_UI_BAND_AUTO;
7498 break;
7499
7500 case eCSR_BAND_24:
7501 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
7502 break;
7503
7504 case eCSR_BAND_5G:
7505 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
7506 break;
7507
7508 default:
7509 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
7510 *pBand = -1;
7511 break;
7512 }
7513}
7514
7515/**---------------------------------------------------------------------------
7516
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007517 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
7518
7519 This function parses the send action frame data passed in the format
7520 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
7521
Srinivas Girigowda56076852013-08-20 14:00:50 -07007522 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007523 \param - pTargetApBssid Pointer to target Ap bssid
7524 \param - pChannel Pointer to the Target AP channel
7525 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
7526 \param - pBuf Pointer to data
7527 \param - pBufLen Pointer to data length
7528
7529 \return - 0 for success non-zero for failure
7530
7531 --------------------------------------------------------------------------*/
7532VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
7533 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
7534{
7535 tANI_U8 *inPtr = pValue;
7536 tANI_U8 *dataEnd;
7537 int tempInt;
7538 int j = 0;
7539 int i = 0;
7540 int v = 0;
7541 tANI_U8 tempBuf[32];
7542 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007543 /* 12 hexa decimal digits, 5 ':' and '\0' */
7544 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007545
7546 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7547 /*no argument after the command*/
7548 if (NULL == inPtr)
7549 {
7550 return -EINVAL;
7551 }
7552
7553 /*no space after the command*/
7554 else if (SPACE_ASCII_VALUE != *inPtr)
7555 {
7556 return -EINVAL;
7557 }
7558
7559 /*removing empty spaces*/
7560 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7561
7562 /*no argument followed by spaces*/
7563 if ('\0' == *inPtr)
7564 {
7565 return -EINVAL;
7566 }
7567
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007568 v = sscanf(inPtr, "%17s", macAddress);
7569 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007570 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7572 "Invalid MAC address or All hex inputs are not read (%d)", v);
7573 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007574 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007575
7576 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7577 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7578 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7579 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7580 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7581 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007582
7583 /* point to the next argument */
7584 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7585 /*no argument after the command*/
7586 if (NULL == inPtr) return -EINVAL;
7587
7588 /*removing empty spaces*/
7589 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7590
7591 /*no argument followed by spaces*/
7592 if ('\0' == *inPtr)
7593 {
7594 return -EINVAL;
7595 }
7596
7597 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007598 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007599 if (1 != v) return -EINVAL;
7600
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007601 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05307602 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05307603 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007604
7605 *pChannel = tempInt;
7606
7607 /* point to the next argument */
7608 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7609 /*no argument after the command*/
7610 if (NULL == inPtr) return -EINVAL;
7611 /*removing empty spaces*/
7612 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7613
7614 /*no argument followed by spaces*/
7615 if ('\0' == *inPtr)
7616 {
7617 return -EINVAL;
7618 }
7619
7620 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007621 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007622 if (1 != v) return -EINVAL;
7623
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007624 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08007625 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007626
7627 *pDwellTime = tempInt;
7628
7629 /* point to the next argument */
7630 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7631 /*no argument after the command*/
7632 if (NULL == inPtr) return -EINVAL;
7633 /*removing empty spaces*/
7634 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7635
7636 /*no argument followed by spaces*/
7637 if ('\0' == *inPtr)
7638 {
7639 return -EINVAL;
7640 }
7641
7642 /* find the length of data */
7643 dataEnd = inPtr;
7644 while(('\0' != *dataEnd) )
7645 {
7646 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007647 }
Kiet Lambe150c22013-11-21 16:30:32 +05307648 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007649 if ( *pBufLen <= 0) return -EINVAL;
7650
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07007651 /* Allocate the number of bytes based on the number of input characters
7652 whether it is even or odd.
7653 if the number of input characters are even, then we need N/2 byte.
7654 if the number of input characters are odd, then we need do (N+1)/2 to
7655 compensate rounding off.
7656 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7657 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7658 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007659 if (NULL == *pBuf)
7660 {
7661 hddLog(VOS_TRACE_LEVEL_FATAL,
7662 "%s: vos_mem_alloc failed ", __func__);
7663 return -EINVAL;
7664 }
7665
7666 /* the buffer received from the upper layer is character buffer,
7667 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7668 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7669 and f0 in 3rd location */
7670 for (i = 0, j = 0; j < *pBufLen; j += 2)
7671 {
Kiet Lambe150c22013-11-21 16:30:32 +05307672 if( j+1 == *pBufLen)
7673 {
7674 tempByte = hdd_parse_hex(inPtr[j]);
7675 }
7676 else
7677 {
7678 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
7679 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007680 (*pBuf)[i++] = tempByte;
7681 }
7682 *pBufLen = i;
7683 return VOS_STATUS_SUCCESS;
7684}
7685
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007686/**---------------------------------------------------------------------------
7687
Srinivas Girigowdade697412013-02-14 16:31:48 -08007688 \brief hdd_parse_channellist() - HDD Parse channel list
7689
7690 This function parses the channel list passed in the format
7691 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007692 if the Number of channels (N) does not match with the actual number of channels passed
7693 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
7694 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
7695 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
7696 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08007697
7698 \param - pValue Pointer to input channel list
7699 \param - ChannelList Pointer to local output array to record channel list
7700 \param - pNumChannels Pointer to number of roam scan channels
7701
7702 \return - 0 for success non-zero for failure
7703
7704 --------------------------------------------------------------------------*/
7705VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
7706{
7707 tANI_U8 *inPtr = pValue;
7708 int tempInt;
7709 int j = 0;
7710 int v = 0;
7711 char buf[32];
7712
7713 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7714 /*no argument after the command*/
7715 if (NULL == inPtr)
7716 {
7717 return -EINVAL;
7718 }
7719
7720 /*no space after the command*/
7721 else if (SPACE_ASCII_VALUE != *inPtr)
7722 {
7723 return -EINVAL;
7724 }
7725
7726 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007727 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08007728
7729 /*no argument followed by spaces*/
7730 if ('\0' == *inPtr)
7731 {
7732 return -EINVAL;
7733 }
7734
7735 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007736 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007737 if (1 != v) return -EINVAL;
7738
Srinivas Girigowdade697412013-02-14 16:31:48 -08007739 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007740 if ((v < 0) ||
7741 (tempInt <= 0) ||
7742 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
7743 {
7744 return -EINVAL;
7745 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007746
7747 *pNumChannels = tempInt;
7748
7749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7750 "Number of channels are: %d", *pNumChannels);
7751
7752 for (j = 0; j < (*pNumChannels); j++)
7753 {
7754 /*inPtr pointing to the beginning of first space after number of channels*/
7755 inPtr = strpbrk( inPtr, " " );
7756 /*no channel list after the number of channels argument*/
7757 if (NULL == inPtr)
7758 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007759 if (0 != j)
7760 {
7761 *pNumChannels = j;
7762 return VOS_STATUS_SUCCESS;
7763 }
7764 else
7765 {
7766 return -EINVAL;
7767 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007768 }
7769
7770 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007771 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08007772
7773 /*no channel list after the number of channels argument and spaces*/
7774 if ( '\0' == *inPtr )
7775 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007776 if (0 != j)
7777 {
7778 *pNumChannels = j;
7779 return VOS_STATUS_SUCCESS;
7780 }
7781 else
7782 {
7783 return -EINVAL;
7784 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007785 }
7786
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007787 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007788 if (1 != v) return -EINVAL;
7789
Srinivas Girigowdade697412013-02-14 16:31:48 -08007790 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007791 if ((v < 0) ||
7792 (tempInt <= 0) ||
7793 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7794 {
7795 return -EINVAL;
7796 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007797 pChannelList[j] = tempInt;
7798
7799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7800 "Channel %d added to preferred channel list",
7801 pChannelList[j] );
7802 }
7803
Srinivas Girigowdade697412013-02-14 16:31:48 -08007804 return VOS_STATUS_SUCCESS;
7805}
7806
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007807
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05307808/**
7809 * hdd_parse_reassoc_command_v1_data() - HDD Parse reassoc command data
7810 * This function parses the reasoc command data passed in the format
7811 * REASSOC<space><bssid><space><channel>
7812 *
7813 * @pValue: Pointer to input data (its a NUL terminated string)
7814 * @pTargetApBssid: Pointer to target Ap bssid
7815 * @pChannel: Pointer to the Target AP channel
7816 *
7817 * Return: 0 for success non-zero for failure
7818 */
7819static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
7820 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007821{
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05307822 const tANI_U8 *inPtr = pValue;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007823 int tempInt;
7824 int v = 0;
7825 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08007826 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007827 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007828
7829 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7830 /*no argument after the command*/
7831 if (NULL == inPtr)
7832 {
7833 return -EINVAL;
7834 }
7835
7836 /*no space after the command*/
7837 else if (SPACE_ASCII_VALUE != *inPtr)
7838 {
7839 return -EINVAL;
7840 }
7841
7842 /*removing empty spaces*/
7843 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7844
7845 /*no argument followed by spaces*/
7846 if ('\0' == *inPtr)
7847 {
7848 return -EINVAL;
7849 }
7850
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007851 v = sscanf(inPtr, "%17s", macAddress);
7852 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007853 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7855 "Invalid MAC address or All hex inputs are not read (%d)", v);
7856 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007857 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007858
7859 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7860 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7861 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7862 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7863 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7864 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007865
7866 /* point to the next argument */
7867 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7868 /*no argument after the command*/
7869 if (NULL == inPtr) return -EINVAL;
7870
7871 /*removing empty spaces*/
7872 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7873
7874 /*no argument followed by spaces*/
7875 if ('\0' == *inPtr)
7876 {
7877 return -EINVAL;
7878 }
7879
7880 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007881 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007882 if (1 != v) return -EINVAL;
7883
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007884 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007885 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05307886 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007887 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7888 {
7889 return -EINVAL;
7890 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007891
7892 *pChannel = tempInt;
7893 return VOS_STATUS_SUCCESS;
7894}
7895
7896#endif
7897
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007898#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007899/**---------------------------------------------------------------------------
7900
7901 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
7902
7903 This function parses the SETCCKM IE command
7904 SETCCKMIE<space><ie data>
7905
7906 \param - pValue Pointer to input data
7907 \param - pCckmIe Pointer to output cckm Ie
7908 \param - pCckmIeLen Pointer to output cckm ie length
7909
7910 \return - 0 for success non-zero for failure
7911
7912 --------------------------------------------------------------------------*/
7913VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
7914 tANI_U8 *pCckmIeLen)
7915{
7916 tANI_U8 *inPtr = pValue;
7917 tANI_U8 *dataEnd;
7918 int j = 0;
7919 int i = 0;
7920 tANI_U8 tempByte = 0;
7921
7922 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7923 /*no argument after the command*/
7924 if (NULL == inPtr)
7925 {
7926 return -EINVAL;
7927 }
7928
7929 /*no space after the command*/
7930 else if (SPACE_ASCII_VALUE != *inPtr)
7931 {
7932 return -EINVAL;
7933 }
7934
7935 /*removing empty spaces*/
7936 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7937
7938 /*no argument followed by spaces*/
7939 if ('\0' == *inPtr)
7940 {
7941 return -EINVAL;
7942 }
7943
7944 /* find the length of data */
7945 dataEnd = inPtr;
7946 while(('\0' != *dataEnd) )
7947 {
7948 dataEnd++;
7949 ++(*pCckmIeLen);
7950 }
7951 if ( *pCckmIeLen <= 0) return -EINVAL;
7952
7953 /* Allocate the number of bytes based on the number of input characters
7954 whether it is even or odd.
7955 if the number of input characters are even, then we need N/2 byte.
7956 if the number of input characters are odd, then we need do (N+1)/2 to
7957 compensate rounding off.
7958 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7959 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7960 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
7961 if (NULL == *pCckmIe)
7962 {
7963 hddLog(VOS_TRACE_LEVEL_FATAL,
7964 "%s: vos_mem_alloc failed ", __func__);
7965 return -EINVAL;
7966 }
7967 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
7968 /* the buffer received from the upper layer is character buffer,
7969 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7970 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7971 and f0 in 3rd location */
7972 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
7973 {
7974 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
7975 (*pCckmIe)[i++] = tempByte;
7976 }
7977 *pCckmIeLen = i;
7978
7979 return VOS_STATUS_SUCCESS;
7980}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007981#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007982
Jeff Johnson295189b2012-06-20 16:38:30 -07007983/**---------------------------------------------------------------------------
7984
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007985 \brief hdd_is_valid_mac_address() - Validate MAC address
7986
7987 This function validates whether the given MAC address is valid or not
7988 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
7989 where X is the hexa decimal digit character and separated by ':'
7990 This algorithm works even if MAC address is not separated by ':'
7991
7992 This code checks given input string mac contains exactly 12 hexadecimal digits.
7993 and a separator colon : appears in the input string only after
7994 an even number of hex digits.
7995
7996 \param - pMacAddr pointer to the input MAC address
7997 \return - 1 for valid and 0 for invalid
7998
7999 --------------------------------------------------------------------------*/
8000
8001v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
8002{
8003 int xdigit = 0;
8004 int separator = 0;
8005 while (*pMacAddr)
8006 {
8007 if (isxdigit(*pMacAddr))
8008 {
8009 xdigit++;
8010 }
8011 else if (':' == *pMacAddr)
8012 {
8013 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
8014 break;
8015
8016 ++separator;
8017 }
8018 else
8019 {
8020 separator = -1;
8021 /* Invalid MAC found */
8022 return 0;
8023 }
8024 ++pMacAddr;
8025 }
8026 return (xdigit == 12 && (separator == 5 || separator == 0));
8027}
8028
8029/**---------------------------------------------------------------------------
8030
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308031 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07008032
8033 \param - dev Pointer to net_device structure
8034
8035 \return - 0 for success non-zero for failure
8036
8037 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308038int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008039{
8040 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8041 hdd_context_t *pHddCtx;
8042 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8043 VOS_STATUS status;
8044 v_BOOL_t in_standby = TRUE;
8045
8046 if (NULL == pAdapter)
8047 {
8048 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05308049 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008050 return -ENODEV;
8051 }
8052
8053 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308054 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
8055 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07008056 if (NULL == pHddCtx)
8057 {
8058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008059 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008060 return -ENODEV;
8061 }
8062
8063 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8064 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
8065 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008066 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
8067 {
8068 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308069 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008070 in_standby = FALSE;
8071 break;
8072 }
8073 else
8074 {
8075 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8076 pAdapterNode = pNext;
8077 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008078 }
8079
8080 if (TRUE == in_standby)
8081 {
8082 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
8083 {
8084 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
8085 "wlan out of power save", __func__);
8086 return -EINVAL;
8087 }
8088 }
8089
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008090 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07008091 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8092 {
8093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008094 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008095 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308096 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008097 netif_tx_start_all_queues(dev);
8098 }
8099
8100 return 0;
8101}
8102
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308103/**---------------------------------------------------------------------------
8104
8105 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
8106
8107 This is called in response to ifconfig up
8108
8109 \param - dev Pointer to net_device structure
8110
8111 \return - 0 for success non-zero for failure
8112
8113 --------------------------------------------------------------------------*/
8114int hdd_open(struct net_device *dev)
8115{
8116 int ret;
8117
8118 vos_ssr_protect(__func__);
8119 ret = __hdd_open(dev);
8120 vos_ssr_unprotect(__func__);
8121
8122 return ret;
8123}
8124
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308125int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008126{
8127 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308128 hdd_adapter_t *sta_adapter;
8129 hdd_context_t *hdd_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008130
8131 if(pAdapter == NULL) {
8132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008133 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008134 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008135 }
8136
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308137 if (vos_get_concurrency_mode() != VOS_STA_MON)
8138 return 0;
8139
8140 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8141 if (wlan_hdd_validate_context(hdd_ctx))
8142 return -EINVAL;
8143
8144 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
8145 if (!sta_adapter) {
8146 hddLog(LOGE, FL("No valid STA interface"));
8147 return -EINVAL;
8148 }
8149
8150 if (!test_bit(DEVICE_IFACE_OPENED, &sta_adapter->event_flags)) {
8151 hddLog(LOGE, FL("STA Interface is not OPENED"));
8152 return -EINVAL;
8153 }
8154
8155 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
8156
Jeff Johnson295189b2012-06-20 16:38:30 -07008157 return 0;
8158}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308159
8160int hdd_mon_open (struct net_device *dev)
8161{
8162 int ret;
8163
8164 vos_ssr_protect(__func__);
8165 ret = __hdd_mon_open(dev);
8166 vos_ssr_unprotect(__func__);
8167
8168 return ret;
8169}
8170
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308171int __hdd_mon_stop (struct net_device *dev)
8172{
8173 hdd_adapter_t *mon_adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8174 hdd_context_t *hdd_ctx;
8175
8176 if (vos_get_concurrency_mode() != VOS_STA_MON)
8177 return 0;
8178
8179 if(!mon_adapter) {
8180 hddLog(LOGE, FL("HDD adapter is Null"));
8181 return -EINVAL;
8182 }
8183
8184 hdd_ctx = WLAN_HDD_GET_CTX(mon_adapter);
8185 if (wlan_hdd_validate_context(hdd_ctx))
8186 return -EINVAL;
8187
8188 if (!test_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags)) {
8189 hddLog(LOGE, FL("NETDEV Interface is not OPENED"));
8190 return -ENODEV;
8191 }
8192
8193 clear_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags);
8194 hdd_stop_adapter(hdd_ctx, mon_adapter, VOS_FALSE);
8195
8196 return 0;
8197}
8198
Katya Nigame7b69a82015-04-28 15:24:06 +05308199int hdd_mon_stop(struct net_device *dev)
8200{
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308201 int ret;
8202
8203 vos_ssr_protect(__func__);
8204 ret = __hdd_mon_stop(dev);
8205 vos_ssr_unprotect(__func__);
8206
8207 return ret;
Katya Nigame7b69a82015-04-28 15:24:06 +05308208}
8209
Jeff Johnson295189b2012-06-20 16:38:30 -07008210/**---------------------------------------------------------------------------
8211
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308212 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07008213
8214 \param - dev Pointer to net_device structure
8215
8216 \return - 0 for success non-zero for failure
8217
8218 --------------------------------------------------------------------------*/
8219
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308220int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008221{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308222 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008223 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8224 hdd_context_t *pHddCtx;
8225 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8226 VOS_STATUS status;
8227 v_BOOL_t enter_standby = TRUE;
8228
8229 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008230 if (NULL == pAdapter)
8231 {
8232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05308233 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008234 return -ENODEV;
8235 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05308236 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308237 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308238
8239 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8240 ret = wlan_hdd_validate_context(pHddCtx);
8241 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07008242 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308243 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008244 }
8245
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308246 /* Nothing to be done if the interface is not opened */
8247 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
8248 {
8249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8250 "%s: NETDEV Interface is not OPENED", __func__);
8251 return -ENODEV;
8252 }
8253
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308254 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308255 /*
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05308256 * In STA + Monitor mode concurrency, no point in running
8257 * capture on monitor interface, when STA interface is stopped
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308258 */
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05308259 wlan_hdd_stop_mon(pHddCtx, true);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308260 }
8261
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308262 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008263 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07008264 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308265
8266 /* Disable TX on the interface, after this hard_start_xmit() will not
8267 * be called on that interface
8268 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308269 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008270 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308271
8272 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07008273 netif_carrier_off(pAdapter->dev);
8274
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308275 /* The interface is marked as down for outside world (aka kernel)
8276 * But the driver is pretty much alive inside. The driver needs to
8277 * tear down the existing connection on the netdev (session)
8278 * cleanup the data pipes and wait until the control plane is stabilized
8279 * for this interface. The call also needs to wait until the above
8280 * mentioned actions are completed before returning to the caller.
8281 * Notice that the hdd_stop_adapter is requested not to close the session
8282 * That is intentional to be able to scan if it is a STA/P2P interface
8283 */
8284 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308285#ifdef FEATURE_WLAN_TDLS
8286 mutex_lock(&pHddCtx->tdls_lock);
8287#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308288 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05308289 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308290#ifdef FEATURE_WLAN_TDLS
8291 mutex_unlock(&pHddCtx->tdls_lock);
8292#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008293 /* SoftAP ifaces should never go in power save mode
8294 making sure same here. */
8295 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07008296 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07008297 )
8298 {
8299 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8301 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008302 EXIT();
8303 return 0;
8304 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308305 /* Find if any iface is up. If any iface is up then can't put device to
8306 * sleep/power save mode
8307 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008308 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8309 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
8310 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008311 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
8312 {
8313 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308314 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008315 enter_standby = FALSE;
8316 break;
8317 }
8318 else
8319 {
8320 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8321 pAdapterNode = pNext;
8322 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008323 }
8324
8325 if (TRUE == enter_standby)
8326 {
8327 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
8328 "entering standby", __func__);
8329 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
8330 {
8331 /*log and return success*/
8332 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
8333 "wlan in power save", __func__);
8334 }
8335 }
Hanumanth Reddy Pothula972e1df2018-06-14 13:33:47 +05308336
8337 /*
8338 * Upon wifi turn off, DUT has to flush the scan results so if
8339 * this is the last cli iface, flush the scan database.
8340 */
8341 if (!hdd_is_cli_iface_up(pHddCtx))
8342 sme_ScanFlushResult(pHddCtx->hHal, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07008343
8344 EXIT();
8345 return 0;
8346}
8347
8348/**---------------------------------------------------------------------------
8349
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308350 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07008351
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308352 This is called in response to ifconfig down
8353
8354 \param - dev Pointer to net_device structure
8355
8356 \return - 0 for success non-zero for failure
8357-----------------------------------------------------------------------------*/
8358int hdd_stop (struct net_device *dev)
8359{
8360 int ret;
8361
8362 vos_ssr_protect(__func__);
8363 ret = __hdd_stop(dev);
8364 vos_ssr_unprotect(__func__);
8365
8366 return ret;
8367}
8368
8369/**---------------------------------------------------------------------------
8370
8371 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07008372
8373 \param - dev Pointer to net_device structure
8374
8375 \return - void
8376
8377 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308378static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008379{
8380 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308381 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008382 ENTER();
8383
8384 do
8385 {
8386 if (NULL == pAdapter)
8387 {
8388 hddLog(VOS_TRACE_LEVEL_FATAL,
8389 "%s: NULL pAdapter", __func__);
8390 break;
8391 }
8392
8393 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8394 {
8395 hddLog(VOS_TRACE_LEVEL_FATAL,
8396 "%s: Invalid magic", __func__);
8397 break;
8398 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308399 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8400 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07008401 {
8402 hddLog(VOS_TRACE_LEVEL_FATAL,
8403 "%s: NULL pHddCtx", __func__);
8404 break;
8405 }
8406
8407 if (dev != pAdapter->dev)
8408 {
8409 hddLog(VOS_TRACE_LEVEL_FATAL,
8410 "%s: Invalid device reference", __func__);
8411 /* we haven't validated all cases so let this go for now */
8412 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308413#ifdef FEATURE_WLAN_TDLS
8414 mutex_lock(&pHddCtx->tdls_lock);
8415#endif
c_hpothu002231a2015-02-05 14:58:51 +05308416 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308417#ifdef FEATURE_WLAN_TDLS
8418 mutex_unlock(&pHddCtx->tdls_lock);
8419#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008420
8421 /* after uninit our adapter structure will no longer be valid */
8422 pAdapter->dev = NULL;
8423 pAdapter->magic = 0;
Manjeet Singh47ee8472016-04-11 11:57:18 +05308424 pAdapter->pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008425 } while (0);
8426
8427 EXIT();
8428}
8429
8430/**---------------------------------------------------------------------------
8431
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308432 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
8433
8434 This is called during the netdev unregister to uninitialize all data
8435associated with the device
8436
8437 \param - dev Pointer to net_device structure
8438
8439 \return - void
8440
8441 --------------------------------------------------------------------------*/
8442static void hdd_uninit (struct net_device *dev)
8443{
8444 vos_ssr_protect(__func__);
8445 __hdd_uninit(dev);
8446 vos_ssr_unprotect(__func__);
8447}
8448
8449/**---------------------------------------------------------------------------
8450
Jeff Johnson295189b2012-06-20 16:38:30 -07008451 \brief hdd_release_firmware() -
8452
8453 This function calls the release firmware API to free the firmware buffer.
8454
8455 \param - pFileName Pointer to the File Name.
8456 pCtx - Pointer to the adapter .
8457
8458
8459 \return - 0 for success, non zero for failure
8460
8461 --------------------------------------------------------------------------*/
8462
8463VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
8464{
8465 VOS_STATUS status = VOS_STATUS_SUCCESS;
8466 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8467 ENTER();
8468
8469
8470 if (!strcmp(WLAN_FW_FILE, pFileName)) {
8471
8472 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
8473
8474 if(pHddCtx->fw) {
8475 release_firmware(pHddCtx->fw);
8476 pHddCtx->fw = NULL;
8477 }
8478 else
8479 status = VOS_STATUS_E_FAILURE;
8480 }
8481 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
8482 if(pHddCtx->nv) {
8483 release_firmware(pHddCtx->nv);
8484 pHddCtx->nv = NULL;
8485 }
8486 else
8487 status = VOS_STATUS_E_FAILURE;
8488
8489 }
8490
8491 EXIT();
8492 return status;
8493}
8494
8495/**---------------------------------------------------------------------------
8496
8497 \brief hdd_request_firmware() -
8498
8499 This function reads the firmware file using the request firmware
8500 API and returns the the firmware data and the firmware file size.
8501
8502 \param - pfileName - Pointer to the file name.
8503 - pCtx - Pointer to the adapter .
8504 - ppfw_data - Pointer to the pointer of the firmware data.
8505 - pSize - Pointer to the file size.
8506
8507 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
8508
8509 --------------------------------------------------------------------------*/
8510
8511
8512VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
8513{
8514 int status;
8515 VOS_STATUS retval = VOS_STATUS_SUCCESS;
8516 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8517 ENTER();
8518
8519 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
8520
8521 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
8522
8523 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8524 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
8525 __func__, pfileName);
8526 retval = VOS_STATUS_E_FAILURE;
8527 }
8528
8529 else {
8530 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
8531 *pSize = pHddCtx->fw->size;
8532 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
8533 __func__, *pSize);
8534 }
8535 }
8536 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
8537
8538 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
8539
8540 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
8541 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
8542 __func__, pfileName);
8543 retval = VOS_STATUS_E_FAILURE;
8544 }
8545
8546 else {
8547 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
8548 *pSize = pHddCtx->nv->size;
8549 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
8550 __func__, *pSize);
8551 }
8552 }
8553
8554 EXIT();
8555 return retval;
8556}
8557/**---------------------------------------------------------------------------
8558 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
8559
8560 This is the function invoked by SME to inform the result of a full power
8561 request issued by HDD
8562
8563 \param - callbackcontext - Pointer to cookie
8564 status - result of request
8565
8566 \return - None
8567
8568--------------------------------------------------------------------------*/
8569void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
8570{
8571 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
8572
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008573 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008574 if(&pHddCtx->full_pwr_comp_var)
8575 {
8576 complete(&pHddCtx->full_pwr_comp_var);
8577 }
8578}
8579
Abhishek Singh00b71972016-01-07 10:51:04 +05308580#ifdef WLAN_FEATURE_RMC
8581static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo)
8582{
8583 int payload_len;
8584 struct sk_buff *skb;
8585 struct nlmsghdr *nlh;
8586 v_U8_t *data;
8587
8588 payload_len = ETH_ALEN;
8589
8590 if (0 == cesium_pid)
8591 {
8592 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: cesium process not registered",
8593 __func__);
8594 return;
8595 }
8596
8597 if ((skb = nlmsg_new(payload_len,GFP_ATOMIC)) == NULL)
8598 {
8599 hddLog(VOS_TRACE_LEVEL_ERROR,
8600 "%s: nlmsg_new() failed for msg size[%d]",
8601 __func__, NLMSG_SPACE(payload_len));
8602 return;
8603 }
8604
8605 nlh = nlmsg_put(skb, cesium_pid, seqNo, 0, payload_len, NLM_F_REQUEST);
8606
8607 if (NULL == nlh)
8608 {
8609 hddLog(VOS_TRACE_LEVEL_ERROR,
8610 "%s: nlmsg_put() failed for msg size[%d]",
8611 __func__, NLMSG_SPACE(payload_len));
8612
8613 kfree_skb(skb);
8614 return;
8615 }
8616
8617 data = nlmsg_data(nlh);
8618 memcpy(data, MacAddr, ETH_ALEN);
8619
8620 if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0)
8621 {
8622 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_unicast() failed for msg size[%d]",
8623 __func__, NLMSG_SPACE(payload_len));
8624 }
8625
8626 return;
8627}
8628
8629/**---------------------------------------------------------------------------
8630 \brief hdd_ParseuserParams - return a pointer to the next argument
8631
8632 \return - status
8633
8634--------------------------------------------------------------------------*/
8635static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg)
8636{
8637 tANI_U8 *pVal;
8638
8639 pVal = strchr(pValue, ' ');
8640
8641 if (NULL == pVal)
8642 {
8643 /* no argument remains */
8644 return -EINVAL;
8645 }
8646 else if (SPACE_ASCII_VALUE != *pVal)
8647 {
8648 /* no space after the current argument */
8649 return -EINVAL;
8650 }
8651
8652 pVal++;
8653
8654 /* remove empty spaces */
8655 while ((SPACE_ASCII_VALUE == *pVal) && ('\0' != *pVal))
8656 {
8657 pVal++;
8658 }
8659
8660 /* no argument followed by spaces */
8661 if ('\0' == *pVal)
8662 {
8663 return -EINVAL;
8664 }
8665
8666 *ppArg = pVal;
8667
8668 return 0;
8669}
8670
8671/**----------------------------------------------------------------------------
8672 \brief hdd_ParseIBSSTXFailEventParams - Parse params for SETIBSSTXFAILEVENT
8673
8674 \return - status
8675
8676------------------------------------------------------------------------------*/
8677static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
8678 tANI_U8 *tx_fail_count,
8679 tANI_U16 *pid)
8680{
8681 tANI_U8 *param = NULL;
8682 int ret;
8683
8684 ret = hdd_ParseUserParams(pValue, &param);
8685
8686 if (0 == ret && NULL != param)
8687 {
8688 if (1 != sscanf(param, "%hhu", tx_fail_count))
8689 {
8690 ret = -EINVAL;
8691 goto done;
8692 }
8693 }
8694 else
8695 {
8696 goto done;
8697 }
8698
8699 if (0 == *tx_fail_count)
8700 {
8701 *pid = 0;
8702 goto done;
8703 }
8704
8705 pValue = param;
8706 pValue++;
8707
8708 ret = hdd_ParseUserParams(pValue, &param);
8709
8710 if (0 == ret)
8711 {
8712 if (1 != sscanf(param, "%hu", pid))
8713 {
8714 ret = -EINVAL;
8715 goto done;
8716 }
8717 }
8718 else
8719 {
8720 goto done;
8721 }
8722
8723done:
8724 return ret;
8725}
8726
8727static int hdd_open_cesium_nl_sock()
8728{
8729#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8730 struct netlink_kernel_cfg cfg = {
8731 .groups = WLAN_NLINK_MCAST_GRP_ID,
8732 .input = NULL
8733 };
8734#endif
8735 int ret = 0;
8736
8737#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8738 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
8739#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
8740 THIS_MODULE,
8741#endif
8742 &cfg);
8743#else
8744 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
8745 WLAN_NLINK_MCAST_GRP_ID, NULL, NULL, THIS_MODULE);
8746#endif
8747
8748 if (cesium_nl_srv_sock == NULL)
8749 {
8750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8751 "NLINK: cesium netlink_kernel_create failed");
8752 ret = -ECONNREFUSED;
8753 }
8754
8755 return ret;
8756}
8757
8758static void hdd_close_cesium_nl_sock()
8759{
8760 if (NULL != cesium_nl_srv_sock)
8761 {
8762 netlink_kernel_release(cesium_nl_srv_sock);
8763 cesium_nl_srv_sock = NULL;
8764 }
8765}
8766#endif /* WLAN_FEATURE_RMC */
Jeff Johnson295189b2012-06-20 16:38:30 -07008767/**---------------------------------------------------------------------------
8768
8769 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
8770
8771 This is the function invoked by SME to inform the result of BMPS
8772 request issued by HDD
8773
8774 \param - callbackcontext - Pointer to cookie
8775 status - result of request
8776
8777 \return - None
8778
8779--------------------------------------------------------------------------*/
8780void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
8781{
8782
8783 struct completion *completion_var = (struct completion*) callbackContext;
8784
Arif Hussain6d2a3322013-11-17 19:50:10 -08008785 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008786 if(completion_var != NULL)
8787 {
8788 complete(completion_var);
8789 }
8790}
8791
8792/**---------------------------------------------------------------------------
8793
8794 \brief hdd_get_cfg_file_size() -
8795
8796 This function reads the configuration file using the request firmware
8797 API and returns the configuration file size.
8798
8799 \param - pCtx - Pointer to the adapter .
8800 - pFileName - Pointer to the file name.
8801 - pBufSize - Pointer to the buffer size.
8802
8803 \return - 0 for success, non zero for failure
8804
8805 --------------------------------------------------------------------------*/
8806
8807VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
8808{
8809 int status;
8810 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8811
8812 ENTER();
8813
8814 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
8815
8816 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8817 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
8818 status = VOS_STATUS_E_FAILURE;
8819 }
8820 else {
8821 *pBufSize = pHddCtx->fw->size;
8822 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
8823 release_firmware(pHddCtx->fw);
8824 pHddCtx->fw = NULL;
8825 }
8826
8827 EXIT();
8828 return VOS_STATUS_SUCCESS;
8829}
8830
8831/**---------------------------------------------------------------------------
8832
8833 \brief hdd_read_cfg_file() -
8834
8835 This function reads the configuration file using the request firmware
8836 API and returns the cfg data and the buffer size of the configuration file.
8837
8838 \param - pCtx - Pointer to the adapter .
8839 - pFileName - Pointer to the file name.
8840 - pBuffer - Pointer to the data buffer.
8841 - pBufSize - Pointer to the buffer size.
8842
8843 \return - 0 for success, non zero for failure
8844
8845 --------------------------------------------------------------------------*/
8846
8847VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
8848 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
8849{
8850 int status;
8851 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8852
8853 ENTER();
8854
8855 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
8856
8857 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8858 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
8859 return VOS_STATUS_E_FAILURE;
8860 }
8861 else {
8862 if(*pBufSize != pHddCtx->fw->size) {
8863 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
8864 "file size", __func__);
8865 release_firmware(pHddCtx->fw);
8866 pHddCtx->fw = NULL;
8867 return VOS_STATUS_E_FAILURE;
8868 }
8869 else {
8870 if(pBuffer) {
8871 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
8872 }
8873 release_firmware(pHddCtx->fw);
8874 pHddCtx->fw = NULL;
8875 }
8876 }
8877
8878 EXIT();
8879
8880 return VOS_STATUS_SUCCESS;
8881}
8882
8883/**---------------------------------------------------------------------------
8884
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308885 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008886
8887 This function sets the user specified mac address using
8888 the command ifconfig wlanX hw ether <mac adress>.
8889
8890 \param - dev - Pointer to the net device.
8891 - addr - Pointer to the sockaddr.
8892 \return - 0 for success, non zero for failure
8893
8894 --------------------------------------------------------------------------*/
8895
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308896static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07008897{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308898 hdd_adapter_t *pAdapter;
8899 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008900 struct sockaddr *psta_mac_addr = addr;
8901 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308902 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008903
8904 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308905 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8906 if (NULL == pAdapter)
8907 {
8908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8909 "%s: Adapter is NULL",__func__);
8910 return -EINVAL;
8911 }
8912 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8913 ret = wlan_hdd_validate_context(pHddCtx);
8914 if (0 != ret)
8915 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308916 return ret;
8917 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008918
8919 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07008920 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
8921
8922 EXIT();
8923 return halStatus;
8924}
8925
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308926/**---------------------------------------------------------------------------
8927
8928 \brief hdd_set_mac_address() -
8929
8930 Wrapper function to protect __hdd_set_mac_address() function from ssr
8931
8932 \param - dev - Pointer to the net device.
8933 - addr - Pointer to the sockaddr.
8934 \return - 0 for success, non zero for failure
8935
8936 --------------------------------------------------------------------------*/
8937static int hdd_set_mac_address(struct net_device *dev, void *addr)
8938{
8939 int ret;
8940
8941 vos_ssr_protect(__func__);
8942 ret = __hdd_set_mac_address(dev, addr);
8943 vos_ssr_unprotect(__func__);
8944
8945 return ret;
8946}
8947
Jeff Johnson295189b2012-06-20 16:38:30 -07008948tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
8949{
8950 int i;
8951 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8952 {
Abhishek Singheb183782014-02-06 13:37:21 +05308953 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008954 break;
8955 }
8956
8957 if( VOS_MAX_CONCURRENCY_PERSONA == i)
8958 return NULL;
8959
8960 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
8961 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
8962}
8963
8964void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
8965{
8966 int i;
8967 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8968 {
8969 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
8970 {
8971 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
8972 break;
8973 }
8974 }
8975 return;
8976}
8977
8978#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
8979 static struct net_device_ops wlan_drv_ops = {
8980 .ndo_open = hdd_open,
8981 .ndo_stop = hdd_stop,
8982 .ndo_uninit = hdd_uninit,
8983 .ndo_start_xmit = hdd_hard_start_xmit,
8984 .ndo_tx_timeout = hdd_tx_timeout,
8985 .ndo_get_stats = hdd_stats,
8986 .ndo_do_ioctl = hdd_ioctl,
8987 .ndo_set_mac_address = hdd_set_mac_address,
8988 .ndo_select_queue = hdd_select_queue,
8989#ifdef WLAN_FEATURE_PACKET_FILTERING
8990#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
8991 .ndo_set_rx_mode = hdd_set_multicast_list,
8992#else
8993 .ndo_set_multicast_list = hdd_set_multicast_list,
8994#endif //LINUX_VERSION_CODE
8995#endif
8996 };
Jeff Johnson295189b2012-06-20 16:38:30 -07008997 static struct net_device_ops wlan_mon_drv_ops = {
8998 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05308999 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07009000 .ndo_uninit = hdd_uninit,
9001 .ndo_start_xmit = hdd_mon_hard_start_xmit,
9002 .ndo_tx_timeout = hdd_tx_timeout,
9003 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05309004 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07009005 .ndo_set_mac_address = hdd_set_mac_address,
9006 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05309007
Jeff Johnson295189b2012-06-20 16:38:30 -07009008#endif
9009
9010void hdd_set_station_ops( struct net_device *pWlanDev )
9011{
9012#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07009013 pWlanDev->netdev_ops = &wlan_drv_ops;
9014#else
9015 pWlanDev->open = hdd_open;
9016 pWlanDev->stop = hdd_stop;
9017 pWlanDev->uninit = hdd_uninit;
9018 pWlanDev->hard_start_xmit = NULL;
9019 pWlanDev->tx_timeout = hdd_tx_timeout;
9020 pWlanDev->get_stats = hdd_stats;
9021 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07009022 pWlanDev->set_mac_address = hdd_set_mac_address;
9023#endif
9024}
9025
Katya Nigam1fd24402015-02-16 14:52:19 +05309026void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
9027{
9028 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
9029 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
9030 #else
9031 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
9032 #endif
9033}
9034
Jeff Johnsoneed415b2013-01-18 16:11:20 -08009035static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07009036{
9037 struct net_device *pWlanDev = NULL;
9038 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009039 /*
9040 * cfg80211 initialization and registration....
9041 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05309042 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
9043#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
9044 NET_NAME_UNKNOWN,
9045#endif
9046 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07009047 if(pWlanDev != NULL)
9048 {
9049
9050 //Save the pointer to the net_device in the HDD adapter
9051 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
9052
Jeff Johnson295189b2012-06-20 16:38:30 -07009053 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
9054
9055 pAdapter->dev = pWlanDev;
9056 pAdapter->pHddCtx = pHddCtx;
9057 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05309058 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07009059
Rajeev79dbe4c2013-10-05 11:03:42 +05309060#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05309061 pAdapter->pBatchScanRsp = NULL;
9062 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07009063 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08009064 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05309065 mutex_init(&pAdapter->hdd_batch_scan_lock);
9066#endif
9067
Jeff Johnson295189b2012-06-20 16:38:30 -07009068 pAdapter->isLinkUpSvcNeeded = FALSE;
9069 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
9070 //Init the net_device structure
9071 strlcpy(pWlanDev->name, name, IFNAMSIZ);
9072
9073 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
9074 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
9075 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
Alok Kumar84458542018-05-14 15:03:08 +05309076
9077 pWlanDev->needed_headroom = LIBRA_HW_NEEDED_HEADROOM;
Jeff Johnson295189b2012-06-20 16:38:30 -07009078
9079 hdd_set_station_ops( pAdapter->dev );
9080
9081 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009082 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
9083 pAdapter->wdev.wiphy = pHddCtx->wiphy;
9084 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009085 /* set pWlanDev's parent to underlying device */
9086 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07009087
9088 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009089 }
9090
9091 return pAdapter;
9092}
9093
9094VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
9095{
9096 struct net_device *pWlanDev = pAdapter->dev;
9097 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
9098 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9099 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
9100
9101 if( rtnl_lock_held )
9102 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08009103 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07009104 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
9105 {
9106 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
9107 return VOS_STATUS_E_FAILURE;
9108 }
9109 }
9110 if (register_netdevice(pWlanDev))
9111 {
9112 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
9113 return VOS_STATUS_E_FAILURE;
9114 }
9115 }
9116 else
9117 {
9118 if(register_netdev(pWlanDev))
9119 {
9120 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
9121 return VOS_STATUS_E_FAILURE;
9122 }
9123 }
9124 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
9125
9126 return VOS_STATUS_SUCCESS;
9127}
9128
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009129static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07009130{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009131 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009132
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009133 if (NULL == pAdapter)
9134 {
9135 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
9136 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07009137 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009138
9139 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
9140 {
9141 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
9142 return eHAL_STATUS_NOT_INITIALIZED;
9143 }
9144
9145 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
9146
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009147#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009148 /* need to make sure all of our scheduled work has completed.
9149 * This callback is called from MC thread context, so it is safe to
9150 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009151 *
9152 * Even though this is called from MC thread context, if there is a faulty
9153 * work item in the system, that can hang this call forever. So flushing
9154 * this global work queue is not safe; and now we make sure that
9155 * individual work queues are stopped correctly. But the cancel work queue
9156 * is a GPL only API, so the proprietary version of the driver would still
9157 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009158 */
9159 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009160#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009161
9162 /* We can be blocked while waiting for scheduled work to be
9163 * flushed, and the adapter structure can potentially be freed, in
9164 * which case the magic will have been reset. So make sure the
9165 * magic is still good, and hence the adapter structure is still
9166 * valid, before signaling completion */
9167 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
9168 {
9169 complete(&pAdapter->session_close_comp_var);
9170 }
9171
Jeff Johnson295189b2012-06-20 16:38:30 -07009172 return eHAL_STATUS_SUCCESS;
9173}
Manjeet Singh47ee8472016-04-11 11:57:18 +05309174/**
9175 * hdd_close_tx_queues() - close tx queues
9176 * @hdd_ctx: hdd global context
9177 *
9178 * Return: None
9179 */
9180static void hdd_close_tx_queues(hdd_context_t *hdd_ctx)
9181{
9182 VOS_STATUS status;
9183 hdd_adapter_t *adapter;
9184 hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter = NULL;
9185 /* Not validating hdd_ctx as it's already done by the caller */
9186 ENTER();
9187 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
9188 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
9189 adapter = adapter_node->pAdapter;
9190 if (adapter && adapter->dev) {
9191 netif_tx_disable (adapter->dev);
9192 netif_carrier_off(adapter->dev);
9193 }
9194 status = hdd_get_next_adapter(hdd_ctx, adapter_node,
9195 &next_adapter);
9196 adapter_node = next_adapter;
9197 }
9198 EXIT();
9199}
Jeff Johnson295189b2012-06-20 16:38:30 -07009200
9201VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
9202{
9203 struct net_device *pWlanDev = pAdapter->dev;
9204 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
9205 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9206 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
9207 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309208 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009209
Nirav Shah7e3c8132015-06-22 23:51:42 +05309210 spin_lock_init( &pAdapter->sta_hash_lock);
9211 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
9212
Jeff Johnson295189b2012-06-20 16:38:30 -07009213 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07009214 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009215 //Open a SME session for future operation
9216 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07009217 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009218 if ( !HAL_STATUS_SUCCESS( halStatus ) )
9219 {
9220 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009221 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009222 halStatus, halStatus );
9223 status = VOS_STATUS_E_FAILURE;
9224 goto error_sme_open;
9225 }
9226
9227 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05309228 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009229 &pAdapter->session_open_comp_var,
9230 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309231 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009232 {
9233 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309234 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07009235 status = VOS_STATUS_E_FAILURE;
9236 goto error_sme_open;
9237 }
9238
9239 // Register wireless extensions
9240 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
9241 {
9242 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009243 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009244 halStatus, halStatus );
9245 status = VOS_STATUS_E_FAILURE;
9246 goto error_register_wext;
9247 }
Katya Nigam1fd24402015-02-16 14:52:19 +05309248
Jeff Johnson295189b2012-06-20 16:38:30 -07009249 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05309250 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
9251 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
9252 #else
9253 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
9254 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009255
9256 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05309257 hddLog(VOS_TRACE_LEVEL_INFO,
9258 "%s: Set HDD connState to eConnectionState_NotConnected",
9259 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009260 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
9261
9262 //Set the default operation channel
9263 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
9264
9265 /* Make the default Auth Type as OPEN*/
9266 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9267
9268 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
9269 {
9270 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009271 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009272 status, status );
9273 goto error_init_txrx;
9274 }
9275
9276 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9277
9278 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
9279 {
9280 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009281 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009282 status, status );
9283 goto error_wmm_init;
9284 }
9285
9286 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9287
9288 return VOS_STATUS_SUCCESS;
9289
9290error_wmm_init:
9291 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9292 hdd_deinit_tx_rx(pAdapter);
9293error_init_txrx:
9294 hdd_UnregisterWext(pWlanDev);
9295error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009296 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009297 {
9298 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009299 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05309300 pAdapter->sessionId, FALSE, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009301 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07009302 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309303 unsigned long rc;
9304
Jeff Johnson295189b2012-06-20 16:38:30 -07009305 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309306 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009307 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009308 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309309 if (rc <= 0)
9310 hddLog(VOS_TRACE_LEVEL_ERROR,
9311 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009312 }
9313}
9314error_sme_open:
9315 return status;
9316}
9317
Jeff Johnson295189b2012-06-20 16:38:30 -07009318void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
9319{
9320 hdd_cfg80211_state_t *cfgState;
9321
9322 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
9323
9324 if( NULL != cfgState->buf )
9325 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309326 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07009327 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
9328 rc = wait_for_completion_interruptible_timeout(
9329 &pAdapter->tx_action_cnf_event,
9330 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309331 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009332 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05309333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9334 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
9335 , __func__, rc);
9336
9337 // Inform tx status as FAILURE to upper layer and free cfgState->buf
9338 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009339 }
9340 }
9341 return;
9342}
Jeff Johnson295189b2012-06-20 16:38:30 -07009343
c_hpothu002231a2015-02-05 14:58:51 +05309344void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07009345{
9346 ENTER();
9347 switch ( pAdapter->device_mode )
9348 {
Katya Nigam1fd24402015-02-16 14:52:19 +05309349 case WLAN_HDD_IBSS:
9350 {
9351 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9352 {
9353 hdd_ibss_deinit_tx_rx( pAdapter );
9354 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9355 }
9356 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009357 case WLAN_HDD_INFRA_STATION:
9358 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009359 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009360 {
9361 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9362 {
9363 hdd_deinit_tx_rx( pAdapter );
9364 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9365 }
9366
9367 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9368 {
9369 hdd_wmm_adapter_close( pAdapter );
9370 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9371 }
9372
Jeff Johnson295189b2012-06-20 16:38:30 -07009373 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009374 break;
9375 }
9376
9377 case WLAN_HDD_SOFTAP:
9378 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009379 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05309380
9381 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9382 {
9383 hdd_wmm_adapter_close( pAdapter );
9384 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9385 }
9386
Jeff Johnson295189b2012-06-20 16:38:30 -07009387 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009388
c_hpothu002231a2015-02-05 14:58:51 +05309389 hdd_unregister_hostapd(pAdapter, rtnl_held);
Agrawal Ashisha0584d42016-09-29 13:03:45 +05309390 /* set con_mode to STA only when no SAP concurrency mode */
9391 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
9392 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07009393 break;
9394 }
9395
9396 case WLAN_HDD_MONITOR:
9397 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009398 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9399 {
9400 hdd_deinit_tx_rx( pAdapter );
9401 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9402 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009403 break;
9404 }
9405
9406
9407 default:
9408 break;
9409 }
9410
9411 EXIT();
9412}
9413
9414void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
9415{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08009416 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309417
9418 ENTER();
9419 if (NULL == pAdapter)
9420 {
9421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9422 "%s: HDD adapter is Null", __func__);
9423 return;
9424 }
9425
9426 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009427
Rajeev79dbe4c2013-10-05 11:03:42 +05309428#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309429 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
9430 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08009431 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309432 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
9433 )
9434 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08009435 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05309436 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08009437 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
9438 {
9439 hdd_deinit_batch_scan(pAdapter);
9440 }
Rajeev79dbe4c2013-10-05 11:03:42 +05309441 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08009442 }
Rajeev79dbe4c2013-10-05 11:03:42 +05309443#endif
9444
Jeff Johnson295189b2012-06-20 16:38:30 -07009445 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
9446 if( rtnl_held )
9447 {
9448 unregister_netdevice(pWlanDev);
9449 }
9450 else
9451 {
9452 unregister_netdev(pWlanDev);
9453 }
9454 // note that the pAdapter is no longer valid at this point
9455 // since the memory has been reclaimed
9456 }
9457
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309458 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009459}
9460
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009461void hdd_set_pwrparams(hdd_context_t *pHddCtx)
9462{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309463 VOS_STATUS status;
9464 hdd_adapter_t *pAdapter = NULL;
9465 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009466
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309467 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009468
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309469 /*loop through all adapters.*/
9470 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009471 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309472 pAdapter = pAdapterNode->pAdapter;
9473 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
9474 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009475
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309476 { // we skip this registration for modes other than STA and P2P client modes.
9477 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9478 pAdapterNode = pNext;
9479 continue;
9480 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009481
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309482 //Apply Dynamic DTIM For P2P
9483 //Only if ignoreDynamicDtimInP2pMode is not set in ini
9484 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
9485 pHddCtx->cfg_ini->enableModulatedDTIM) &&
9486 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9487 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
9488 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
9489 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
9490 (eConnectionState_Associated ==
9491 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
9492 (pHddCtx->cfg_ini->fIsBmpsEnabled))
9493 {
9494 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009495
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309496 powerRequest.uIgnoreDTIM = 1;
9497 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
9498
9499 if (pHddCtx->cfg_ini->enableModulatedDTIM)
9500 {
9501 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
9502 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
9503 }
9504 else
9505 {
9506 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
9507 }
9508
9509 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
9510 * specified during Enter/Exit BMPS when LCD off*/
9511 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
9512 NULL, eANI_BOOLEAN_FALSE);
9513 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
9514 NULL, eANI_BOOLEAN_FALSE);
9515
9516 /* switch to the DTIM specified in cfg.ini */
9517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05309518 "Switch to DTIM %d Listen interval %d",
9519 powerRequest.uDTIMPeriod,
9520 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309521 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
9522 break;
9523
9524 }
9525
9526 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9527 pAdapterNode = pNext;
9528 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009529}
9530
9531void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
9532{
9533 /*Switch back to DTIM 1*/
9534 tSirSetPowerParamsReq powerRequest = { 0 };
9535
9536 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
9537 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07009538 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009539
9540 /* Update ignoreDTIM and ListedInterval in CFG with default values */
9541 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
9542 NULL, eANI_BOOLEAN_FALSE);
9543 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
9544 NULL, eANI_BOOLEAN_FALSE);
9545
9546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9547 "Switch to DTIM%d",powerRequest.uListenInterval);
9548 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
9549
9550}
9551
Jeff Johnson295189b2012-06-20 16:38:30 -07009552VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
9553{
9554 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05309555 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
9556 {
9557 hddLog( LOGE, FL("Wlan Unload in progress"));
9558 return VOS_STATUS_E_PERM;
9559 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309560
9561 if (wlan_hdd_check_monitor_state(pHddCtx)) {
9562 hddLog(LOG1, FL("Monitor mode is started, cannot enable BMPS"));
9563 return VOS_STATUS_SUCCESS;
9564 }
9565
Jeff Johnson295189b2012-06-20 16:38:30 -07009566 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
9567 {
9568 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
9569 }
9570
9571 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
9572 {
9573 sme_StartAutoBmpsTimer(pHddCtx->hHal);
9574 }
9575
9576 if (pHddCtx->cfg_ini->fIsImpsEnabled)
9577 {
9578 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
9579 }
9580
9581 return status;
9582}
9583
9584VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
9585{
9586 hdd_adapter_t *pAdapter = NULL;
9587 eHalStatus halStatus;
9588 VOS_STATUS status = VOS_STATUS_E_INVAL;
9589 v_BOOL_t disableBmps = FALSE;
9590 v_BOOL_t disableImps = FALSE;
9591
9592 switch(session_type)
9593 {
9594 case WLAN_HDD_INFRA_STATION:
9595 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07009596 case WLAN_HDD_P2P_CLIENT:
9597 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009598 //Exit BMPS -> Is Sta/P2P Client is already connected
9599 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
9600 if((NULL != pAdapter)&&
9601 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9602 {
9603 disableBmps = TRUE;
9604 }
9605
9606 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
9607 if((NULL != pAdapter)&&
9608 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9609 {
9610 disableBmps = TRUE;
9611 }
9612
9613 //Exit both Bmps and Imps incase of Go/SAP Mode
9614 if((WLAN_HDD_SOFTAP == session_type) ||
9615 (WLAN_HDD_P2P_GO == session_type))
9616 {
9617 disableBmps = TRUE;
9618 disableImps = TRUE;
9619 }
9620
9621 if(TRUE == disableImps)
9622 {
9623 if (pHddCtx->cfg_ini->fIsImpsEnabled)
9624 {
9625 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
9626 }
9627 }
9628
9629 if(TRUE == disableBmps)
9630 {
9631 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
9632 {
9633 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
9634
9635 if(eHAL_STATUS_SUCCESS != halStatus)
9636 {
9637 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009638 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009639 VOS_ASSERT(0);
9640 return status;
9641 }
9642 }
9643
9644 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
9645 {
9646 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
9647
9648 if(eHAL_STATUS_SUCCESS != halStatus)
9649 {
9650 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009651 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009652 VOS_ASSERT(0);
9653 return status;
9654 }
9655 }
9656 }
9657
9658 if((TRUE == disableBmps) ||
9659 (TRUE == disableImps))
9660 {
9661 /* Now, get the chip into Full Power now */
9662 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
9663 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
9664 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
9665
9666 if(halStatus != eHAL_STATUS_SUCCESS)
9667 {
9668 if(halStatus == eHAL_STATUS_PMC_PENDING)
9669 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309670 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009671 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309672 ret = wait_for_completion_interruptible_timeout(
9673 &pHddCtx->full_pwr_comp_var,
9674 msecs_to_jiffies(1000));
9675 if (ret <= 0)
9676 {
9677 hddLog(VOS_TRACE_LEVEL_ERROR,
9678 "%s: wait on full_pwr_comp_var failed %ld",
9679 __func__, ret);
9680 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009681 }
9682 else
9683 {
9684 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009685 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009686 VOS_ASSERT(0);
9687 return status;
9688 }
9689 }
9690
9691 status = VOS_STATUS_SUCCESS;
9692 }
9693
9694 break;
9695 }
9696 return status;
9697}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309698
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309699void hdd_mon_post_msg_cb(void *context)
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309700{
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309701 struct hdd_request *request;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309702
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309703 request = hdd_request_get(context);
9704 if (!request) {
9705 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
9706 return;
9707 }
9708
9709 hdd_request_complete(request);
9710 hdd_request_put(request);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309711}
9712
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309713
Katya Nigame7b69a82015-04-28 15:24:06 +05309714void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
9715 {
9716 hdd_mon_ctx_t *pMonCtx = NULL;
Katya Nigame7b69a82015-04-28 15:24:06 +05309717
Rajeev Kumar Sirasanagandla54447612018-03-06 15:49:56 +05309718 spin_lock_init(&pAdapter->sta_hash_lock);
9719 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
9720
9721 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
Katya Nigame7b69a82015-04-28 15:24:06 +05309722 pMonCtx->state = 0;
9723 pMonCtx->ChannelNo = 1;
9724 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05309725 pMonCtx->crcCheckEnabled = 1;
9726 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
9727 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05309728 pMonCtx->numOfMacFilters = 0;
9729 }
9730
Jeff Johnson295189b2012-06-20 16:38:30 -07009731
9732hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08009733 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07009734 tANI_U8 rtnl_held )
9735{
9736 hdd_adapter_t *pAdapter = NULL;
9737 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
9738 VOS_STATUS status = VOS_STATUS_E_FAILURE;
9739 VOS_STATUS exitbmpsStatus;
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309740 v_CONTEXT_t pVosContext = NULL;
9741
9742 /* No need to check for NULL, reaching this step
9743 * means vos context is initialized
9744 */
9745 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009746
Arif Hussain6d2a3322013-11-17 19:50:10 -08009747 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009748
Nirav Shah436658f2014-02-28 17:05:45 +05309749 if(macAddr == NULL)
9750 {
9751 /* Not received valid macAddr */
9752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9753 "%s:Unable to add virtual intf: Not able to get"
9754 "valid mac address",__func__);
9755 return NULL;
9756 }
9757
Jeff Johnson295189b2012-06-20 16:38:30 -07009758 //Disable BMPS incase of Concurrency
9759 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
9760
9761 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
9762 {
9763 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309764 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009765 VOS_ASSERT(0);
9766 return NULL;
9767 }
9768
9769 switch(session_type)
9770 {
9771 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07009772 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009773 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009774 {
9775 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9776
9777 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309778 {
9779 hddLog(VOS_TRACE_LEVEL_FATAL,
9780 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009781 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309782 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009783
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309784#ifdef FEATURE_WLAN_TDLS
9785 /* A Mutex Lock is introduced while changing/initializing the mode to
9786 * protect the concurrent access for the Adapters by TDLS module.
9787 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309788 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309789#endif
9790
Jeff Johnsone7245742012-09-05 17:12:55 -07009791 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
9792 NL80211_IFTYPE_P2P_CLIENT:
9793 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07009794
Jeff Johnson295189b2012-06-20 16:38:30 -07009795 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309796#ifdef FEATURE_WLAN_TDLS
9797 mutex_unlock(&pHddCtx->tdls_lock);
9798#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05309799
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309800 hdd_initialize_adapter_common(pAdapter);
Sunil Dutt66485cb2013-12-19 19:05:03 +05309801 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009802 if( VOS_STATUS_SUCCESS != status )
9803 goto err_free_netdev;
9804
9805 status = hdd_register_interface( pAdapter, rtnl_held );
9806 if( VOS_STATUS_SUCCESS != status )
9807 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05309808#ifdef FEATURE_WLAN_TDLS
9809 mutex_lock(&pHddCtx->tdls_lock);
9810#endif
c_hpothu002231a2015-02-05 14:58:51 +05309811 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05309812#ifdef FEATURE_WLAN_TDLS
9813 mutex_unlock(&pHddCtx->tdls_lock);
9814#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009815 goto err_free_netdev;
9816 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309817
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05309818 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309819 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05309820
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309821#ifdef WLAN_NS_OFFLOAD
9822 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309823 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309824#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009825 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309826 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009827 netif_tx_disable(pAdapter->dev);
9828 //netif_tx_disable(pWlanDev);
9829 netif_carrier_off(pAdapter->dev);
9830
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309831 if (WLAN_HDD_P2P_CLIENT == session_type ||
9832 WLAN_HDD_P2P_DEVICE == session_type)
9833 {
9834 /* Initialize the work queue to defer the
9835 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309836 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309837 hdd_p2p_roc_work_queue);
9838 }
9839
Jeff Johnson295189b2012-06-20 16:38:30 -07009840 break;
9841 }
9842
Jeff Johnson295189b2012-06-20 16:38:30 -07009843 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009844 case WLAN_HDD_SOFTAP:
9845 {
9846 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
9847 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309848 {
9849 hddLog(VOS_TRACE_LEVEL_FATAL,
9850 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009851 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309852 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009853
Jeff Johnson295189b2012-06-20 16:38:30 -07009854 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
9855 NL80211_IFTYPE_AP:
9856 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009857 pAdapter->device_mode = session_type;
9858
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309859 hdd_initialize_adapter_common(pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +05309860 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -07009861 if( VOS_STATUS_SUCCESS != status )
9862 goto err_free_netdev;
9863
Nirav Shah7e3c8132015-06-22 23:51:42 +05309864 status = hdd_sta_id_hash_attach(pAdapter);
9865 if (VOS_STATUS_SUCCESS != status)
9866 {
9867 hddLog(VOS_TRACE_LEVEL_FATAL,
9868 FL("failed to attach hash for session %d"), session_type);
9869 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
9870 goto err_free_netdev;
9871 }
9872
Jeff Johnson295189b2012-06-20 16:38:30 -07009873 status = hdd_register_hostapd( pAdapter, rtnl_held );
9874 if( VOS_STATUS_SUCCESS != status )
9875 {
c_hpothu002231a2015-02-05 14:58:51 +05309876 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07009877 goto err_free_netdev;
9878 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309879 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009880 netif_tx_disable(pAdapter->dev);
9881 netif_carrier_off(pAdapter->dev);
9882
9883 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309884
Hanumanth Reddy Pothulab4537b82018-03-02 12:20:38 +05309885 // Workqueue which gets scheduled in IPv4 notification callback.
9886 vos_init_work(&pAdapter->ipv4NotifierWorkQueue,
9887 hdd_ipv4_notifier_work_queue);
9888
9889#ifdef WLAN_NS_OFFLOAD
9890 // Workqueue which gets scheduled in IPv6 notification callback.
9891 vos_init_work(&pAdapter->ipv6NotifierWorkQueue,
9892 hdd_ipv6_notifier_work_queue);
9893#endif
9894
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309895 if (WLAN_HDD_P2P_GO == session_type)
9896 {
9897 /* Initialize the work queue to
9898 * defer the back to back RoC request */
9899 INIT_DELAYED_WORK(&pAdapter->roc_work,
9900 hdd_p2p_roc_work_queue);
9901 }
Bhargav Shahd0715912015-10-01 18:17:37 +05309902
Jeff Johnson295189b2012-06-20 16:38:30 -07009903 break;
9904 }
9905 case WLAN_HDD_MONITOR:
9906 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009907 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9908 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309909 {
9910 hddLog(VOS_TRACE_LEVEL_FATAL,
9911 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009912 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309913 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009914
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309915 pAdapter->device_mode = session_type;
9916 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
9917
Katya Nigame7b69a82015-04-28 15:24:06 +05309918 // Register wireless extensions
9919 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
9920 {
9921 hddLog(VOS_TRACE_LEVEL_FATAL,
9922 "hdd_register_wext() failed with status code %08d [x%08x]",
9923 status, status );
9924 status = VOS_STATUS_E_FAILURE;
9925 }
9926
Jeff Johnson295189b2012-06-20 16:38:30 -07009927#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
9928 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
9929#else
9930 pAdapter->dev->open = hdd_mon_open;
9931 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05309932 pAdapter->dev->stop = hdd_mon_stop;
9933 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07009934#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05309935 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309936 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009937 hdd_init_tx_rx( pAdapter );
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309938
9939 if (VOS_MONITOR_MODE != hdd_get_conparam())
9940 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9941
Jeff Johnson295189b2012-06-20 16:38:30 -07009942 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309943 status = hdd_register_interface( pAdapter, rtnl_held );
Katya Nigame7b69a82015-04-28 15:24:06 +05309944 //Stop the Interface TX queue.
9945 netif_tx_disable(pAdapter->dev);
9946 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009947 }
9948 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009949 case WLAN_HDD_FTM:
9950 {
9951 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9952
9953 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309954 {
9955 hddLog(VOS_TRACE_LEVEL_FATAL,
9956 FL("failed to allocate adapter for session %d"), session_type);
9957 return NULL;
9958 }
9959
Jeff Johnson295189b2012-06-20 16:38:30 -07009960 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
9961 * message while loading driver in FTM mode. */
9962 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
9963 pAdapter->device_mode = session_type;
9964 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309965
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309966 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309967 hdd_init_tx_rx( pAdapter );
9968
9969 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309970 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309971 netif_tx_disable(pAdapter->dev);
9972 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009973 }
9974 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009975 default:
9976 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309977 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
9978 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009979 VOS_ASSERT(0);
9980 return NULL;
9981 }
9982 }
9983
Jeff Johnson295189b2012-06-20 16:38:30 -07009984 if( VOS_STATUS_SUCCESS == status )
9985 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309986 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -07009987 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
9988 if( NULL == pHddAdapterNode )
9989 {
9990 status = VOS_STATUS_E_NOMEM;
9991 }
9992 else
9993 {
9994 pHddAdapterNode->pAdapter = pAdapter;
9995 status = hdd_add_adapter_back ( pHddCtx,
9996 pHddAdapterNode );
9997 }
9998 }
9999
10000 if( VOS_STATUS_SUCCESS != status )
10001 {
10002 if( NULL != pAdapter )
10003 {
10004 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
10005 pAdapter = NULL;
10006 }
10007 if( NULL != pHddAdapterNode )
10008 {
10009 vos_mem_free( pHddAdapterNode );
10010 }
10011
10012 goto resume_bmps;
10013 }
10014
10015 if(VOS_STATUS_SUCCESS == status)
10016 {
10017 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -070010018 //Initialize the WoWL service
10019 if(!hdd_init_wowl(pAdapter))
10020 {
10021 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
10022 goto err_free_netdev;
10023 }
Manjeet Singh3ed79242017-01-11 19:04:32 +053010024 //Initialize the TSF capture data
10025 wlan_hdd_tsf_init(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010026 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010027 return pAdapter;
10028
10029err_free_netdev:
Jeff Johnson295189b2012-06-20 16:38:30 -070010030 wlan_hdd_release_intf_addr( pHddCtx,
10031 pAdapter->macAddressCurrent.bytes );
Hanumanth Reddy Pothulaab8e1942018-05-24 18:10:39 +053010032 free_netdev(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070010033
10034resume_bmps:
10035 //If bmps disabled enable it
10036 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
10037 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010038 if (pHddCtx->hdd_wlan_suspended)
10039 {
10040 hdd_set_pwrparams(pHddCtx);
10041 }
10042 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010043 }
10044 return NULL;
10045}
10046
10047VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
10048 tANI_U8 rtnl_held )
10049{
10050 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
10051 VOS_STATUS status;
10052
10053 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
10054 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010055 {
10056 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
10057 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010058 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010059 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010060
10061 while ( pCurrent->pAdapter != pAdapter )
10062 {
10063 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
10064 if( VOS_STATUS_SUCCESS != status )
10065 break;
10066
10067 pCurrent = pNext;
10068 }
10069 pAdapterNode = pCurrent;
10070 if( VOS_STATUS_SUCCESS == status )
10071 {
10072 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10073 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010074
10075#ifdef FEATURE_WLAN_TDLS
10076
10077 /* A Mutex Lock is introduced while changing/initializing the mode to
10078 * protect the concurrent access for the Adapters by TDLS module.
10079 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010080 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010081#endif
10082
Jeff Johnson295189b2012-06-20 16:38:30 -070010083 hdd_remove_adapter( pHddCtx, pAdapterNode );
10084 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080010085 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010086
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010087#ifdef FEATURE_WLAN_TDLS
10088 mutex_unlock(&pHddCtx->tdls_lock);
10089#endif
10090
Jeff Johnson295189b2012-06-20 16:38:30 -070010091
10092 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +053010093 if ((!vos_concurrent_open_sessions_running()) &&
10094 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
10095 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010096 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010097 if (pHddCtx->hdd_wlan_suspended)
10098 {
10099 hdd_set_pwrparams(pHddCtx);
10100 }
10101 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010102 }
10103
10104 return VOS_STATUS_SUCCESS;
10105 }
10106
10107 return VOS_STATUS_E_FAILURE;
10108}
10109
10110VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
10111{
10112 hdd_adapter_list_node_t *pHddAdapterNode;
10113 VOS_STATUS status;
10114
10115 ENTER();
10116
10117 do
10118 {
10119 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
10120 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
10121 {
10122 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
10123 vos_mem_free( pHddAdapterNode );
10124 }
10125 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
10126
10127 EXIT();
10128
10129 return VOS_STATUS_SUCCESS;
10130}
10131
10132void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
10133{
10134 v_U8_t addIE[1] = {0};
10135
10136 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10137 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
10138 eANI_BOOLEAN_FALSE) )
10139 {
10140 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010141 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010142 }
10143
10144 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10145 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10146 eANI_BOOLEAN_FALSE) )
10147 {
10148 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010149 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010150 }
10151
10152 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10153 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10154 eANI_BOOLEAN_FALSE) )
10155 {
10156 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010157 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010158 }
10159}
10160
Anurag Chouhan83026002016-12-13 22:46:21 +053010161VOS_STATUS hdd_cleanup_ap_events(hdd_adapter_t *adapter)
10162{
10163#ifdef DHCP_SERVER_OFFLOAD
10164 vos_event_destroy(&adapter->dhcp_status.vos_event);
10165#endif
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010166#ifdef MDNS_OFFLOAD
10167 vos_event_destroy(&adapter->mdns_status.vos_event);
10168#endif
Anurag Chouhan83026002016-12-13 22:46:21 +053010169 return VOS_STATUS_SUCCESS;
10170}
10171
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010172int wlan_hdd_stop_mon(hdd_context_t *hdd_ctx, bool wait)
10173{
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010174 hdd_adapter_t *adapter;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010175 hdd_mon_ctx_t *mon_ctx;
10176 void (*func_ptr)(void *context) = NULL;
10177 int ret = 0;
10178 void *cookie = NULL;
10179 struct hdd_request *request;
10180 static const struct hdd_request_params params = {
10181 .priv_size = 0,
10182 .timeout_ms = MON_MODE_MSG_TIMEOUT,
10183 };
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010184
10185 adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
10186 if (!adapter) {
10187 hddLog(LOGE, FL("Invalid STA + MON mode"));
10188 return -EINVAL;
10189 }
10190
10191 mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(adapter);
10192 if (!mon_ctx)
10193 return 0;
10194
10195 if (mon_ctx->state != MON_MODE_START)
10196 return 0;
10197
10198 mon_ctx->state = MON_MODE_STOP;
10199 if (wait) {
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010200 func_ptr = hdd_mon_post_msg_cb;
10201 request = hdd_request_alloc(&params);
10202 if (!request) {
10203 hddLog(VOS_TRACE_LEVEL_ERROR,
10204 FL("Request allocation failure"));
10205 return -ENOMEM;
10206 }
10207 cookie = hdd_request_cookie(request);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010208 }
10209
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010210 /*
10211 * If func_ptr is NULL, on receiving WDI_MON_START_RSP or
10212 * WDI_MON_STOP_RSP hdd_mon_post_msg_cb() won't be invoked
10213 * and so uninitialized cookie won't be accessed.
10214 */
10215 if (VOS_STATUS_SUCCESS != wlan_hdd_mon_postMsg(cookie,
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010216 mon_ctx,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010217 func_ptr)) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010218 hddLog(LOGE, FL("failed to stop MON MODE"));
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010219 ret = -EINVAL;
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010220 }
10221
10222 if (!wait)
10223 goto bmps_roaming;
10224
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010225 if (!ret)
10226 ret = hdd_request_wait_for_response(request);
10227 hdd_request_put(request);
10228 if (ret) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010229 hddLog(LOGE,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010230 FL("timeout on stop monitor mode completion %d"), ret);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010231 return -EINVAL;
10232 }
10233
10234bmps_roaming:
10235 hddLog(LOG1, FL("Enable BMPS"));
10236 hdd_enable_bmps_imps(hdd_ctx);
10237 hdd_restore_roaming(hdd_ctx);
10238
10239 return 0;
10240}
10241
10242bool wlan_hdd_check_monitor_state(hdd_context_t *hdd_ctx)
10243{
10244 hdd_adapter_t *mon_adapter;
10245 hdd_mon_ctx_t *mon_ctx;
10246
10247 if (hdd_ctx->concurrency_mode != VOS_STA_MON)
10248 return false;
10249
10250 mon_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
10251 if (!mon_adapter) {
10252 hddLog(LOGE, FL("Invalid concurrency mode"));
10253 return false;
10254 }
10255
10256 mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(mon_adapter);
10257 if (mon_ctx->state == MON_MODE_START)
10258 return true;
10259
10260 return false;
10261}
10262
10263int wlan_hdd_check_and_stop_mon(hdd_adapter_t *sta_adapter, bool wait)
10264{
10265 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(sta_adapter);
10266
10267 if ((sta_adapter->device_mode != WLAN_HDD_INFRA_STATION) ||
10268 !wlan_hdd_check_monitor_state(hdd_ctx))
10269 return 0;
10270
10271 if (wlan_hdd_stop_mon(hdd_ctx, wait))
10272 return -EINVAL;
10273
10274 return 0;
10275}
10276
10277void hdd_disable_roaming(hdd_context_t *hdd_ctx)
10278{
10279 if (!hdd_ctx)
10280 return;
10281
10282 if (!hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled) {
10283 hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
10284 return;
10285 }
10286
10287 hddLog(LOG1, FL("Disable driver and firmware roaming"));
10288
10289 hdd_ctx->roaming_ini_original =
10290 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled;
10291
10292 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
10293 CFG_LFR_FEATURE_ENABLED_MIN;
10294
10295 sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
10296 CFG_LFR_FEATURE_ENABLED_MIN);
10297}
10298
10299void hdd_restore_roaming(hdd_context_t *hdd_ctx)
10300{
10301 if (!hdd_ctx->roaming_ini_original)
10302 return;
10303
10304 hddLog(LOG1, FL("Enable driver and firmware roaming"));
10305
10306 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
10307 CFG_LFR_FEATURE_ENABLED_MAX;
10308
10309 hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
10310
10311 sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
10312 CFG_LFR_FEATURE_ENABLED_MAX);
10313}
Anurag Chouhan83026002016-12-13 22:46:21 +053010314
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010315VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
10316 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -070010317{
10318 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
10319 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010320 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010321 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010322 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010323 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +053010324 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010325
Anand N Sunkad26d71b92014-12-24 18:08:22 +053010326 if (pHddCtx->isLogpInProgress) {
10327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10328 "%s:LOGP in Progress. Ignore!!!",__func__);
10329 return VOS_STATUS_E_FAILURE;
10330 }
10331
Jeff Johnson295189b2012-06-20 16:38:30 -070010332 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010333
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010334 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -070010335 switch(pAdapter->device_mode)
10336 {
Nirav Shah0cf4d892015-11-05 16:27:27 +053010337 case WLAN_HDD_IBSS:
10338 if ( VOS_TRUE == bCloseSession )
10339 {
10340 status = hdd_sta_id_hash_detach(pAdapter);
10341 if (status != VOS_STATUS_SUCCESS)
10342 hddLog(VOS_TRACE_LEVEL_ERROR,
10343 FL("sta id hash detach failed"));
10344 }
10345
Jeff Johnson295189b2012-06-20 16:38:30 -070010346 case WLAN_HDD_INFRA_STATION:
10347 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -070010348 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010349 {
10350 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +053010351#ifdef FEATURE_WLAN_TDLS
10352 mutex_lock(&pHddCtx->tdls_lock);
10353 wlan_hdd_tdls_exit(pAdapter, TRUE);
10354 mutex_unlock(&pHddCtx->tdls_lock);
10355#endif
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010356 if(hdd_connIsConnected(pstation) ||
10357 (pstation->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070010358 {
10359 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010360 {
10361 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010362 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
10363 pAdapter->sessionId,
10364 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010365 /* Success implies disconnect command got queued up successfully
10366 * Or cmd not queued as scan for SSID is in progress
10367 */
10368 if((eHAL_STATUS_SUCCESS == halStatus) ||
10369 (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
10370 {
10371 ret = wait_for_completion_timeout(
10372 &pAdapter->disconnect_comp_var,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010373 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010374 if (ret <= 0 &&
10375 (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
10376 {
10377 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010378 "%s: wait on disconnect_comp_var failed %ld",
10379 __func__, ret);
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010380 }
10381 }
10382 else
10383 {
10384 hddLog(LOGE, "%s: failed to post disconnect event to SME",
10385 __func__);
10386 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010387 }
10388 else
10389 {
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010390 wlan_hdd_disconnect(pAdapter, eCSR_DISCONNECT_REASON_DEAUTH);
Jeff Johnson295189b2012-06-20 16:38:30 -070010391 }
10392 memset(&wrqu, '\0', sizeof(wrqu));
10393 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
10394 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
10395 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
10396 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010397 else if(pstation->conn_info.connState ==
10398 eConnectionState_Disconnecting)
10399 {
10400 ret = wait_for_completion_interruptible_timeout(
10401 &pAdapter->disconnect_comp_var,
10402 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10403 if (ret <= 0)
10404 {
10405 hddLog(VOS_TRACE_LEVEL_ERROR,
10406 FL("wait on disconnect_comp_var failed %ld"), ret);
10407 }
10408 }
Sachin Ahuja27dd2402016-08-01 20:30:31 +053010409 if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -070010410 {
Mahesh A Saptasagar0b61dcc2016-02-15 14:23:38 +053010411 wlan_hdd_scan_abort(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010412 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +053010413 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
10414 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010415 {
10416 while (pAdapter->is_roc_inprogress)
10417 {
10418 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10419 "%s: ROC in progress for session %d!!!",
10420 __func__, pAdapter->sessionId);
10421 // waiting for ROC to expire
10422 msleep(500);
10423 /* In GO present case , if retry exceeds 3,
10424 it means something went wrong. */
10425 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
10426 {
10427 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10428 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +053010429 if (eHAL_STATUS_SUCCESS !=
10430 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
10431 pAdapter->sessionId ))
10432 {
10433 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10434 FL("Failed to Cancel Remain on Channel"));
10435 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010436 wait_for_completion_interruptible_timeout(
10437 &pAdapter->cancel_rem_on_chan_var,
10438 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
10439 break;
10440 }
10441 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010442 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010443 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +053010444#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010445 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +053010446#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010447
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010448 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010449
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010450 /* It is possible that the caller of this function does not
10451 * wish to close the session
10452 */
10453 if (VOS_TRUE == bCloseSession &&
10454 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010455 {
10456 INIT_COMPLETION(pAdapter->session_close_comp_var);
10457 if (eHAL_STATUS_SUCCESS ==
Agrawal Ashish5a3522c2016-03-02 15:08:28 +053010458 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, FALSE,
10459 VOS_FALSE, hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010460 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010461 unsigned long ret;
10462
Jeff Johnson295189b2012-06-20 16:38:30 -070010463 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010464 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010465 &pAdapter->session_close_comp_var,
10466 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010467 if ( 0 >= ret)
10468 {
10469 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010470 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010471 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010472 }
10473 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010474 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010475 break;
10476
10477 case WLAN_HDD_SOFTAP:
Abhishek Singh3dc4c972019-05-09 11:04:24 +053010478 /* Delete all associated STAs before stopping AP */
10479 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10480 hdd_del_all_sta(pAdapter);
10481 /* Fall through */
Jeff Johnson295189b2012-06-20 16:38:30 -070010482 case WLAN_HDD_P2P_GO:
Abhishek Singh3dc4c972019-05-09 11:04:24 +053010483
Nirav Shah0cf4d892015-11-05 16:27:27 +053010484 if ( VOS_TRUE == bCloseSession )
10485 {
10486 status = hdd_sta_id_hash_detach(pAdapter);
10487 if (status != VOS_STATUS_SUCCESS)
10488 hddLog(VOS_TRACE_LEVEL_ERROR,
10489 FL("sta id hash detach failed"));
10490 }
10491
Jeff Johnson295189b2012-06-20 16:38:30 -070010492 //Any softap specific cleanup here...
Anurag Chouhan83026002016-12-13 22:46:21 +053010493 hdd_cleanup_ap_events(pAdapter);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010494 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
10495 while (pAdapter->is_roc_inprogress) {
10496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10497 "%s: ROC in progress for session %d!!!",
10498 __func__, pAdapter->sessionId);
10499 msleep(500);
10500 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
10501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10502 "%s: ROC completion is not received.!!!", __func__);
10503 WLANSAP_CancelRemainOnChannel(
10504 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
10505 wait_for_completion_interruptible_timeout(
10506 &pAdapter->cancel_rem_on_chan_var,
10507 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
10508 break;
10509 }
10510 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +053010511
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010512 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010513 }
Agrawal Ashish17ef5082016-10-17 18:33:21 +053010514#ifdef SAP_AUTH_OFFLOAD
10515 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
10516 hdd_set_sap_auth_offload(pAdapter, FALSE);
10517#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010518 mutex_lock(&pHddCtx->sap_lock);
10519 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10520 {
10521 VOS_STATUS status;
10522 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053010523 hdd_hostapd_state_t *pHostapdState =
10524 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010525
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053010526 vos_event_reset(&pHostapdState->vosEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -070010527 //Stop Bss.
10528 status = WLANSAP_StopBss(pHddCtx->pvosContext);
10529 if (VOS_IS_STATUS_SUCCESS(status))
10530 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010531 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10532
10533 if (!VOS_IS_STATUS_SUCCESS(status))
10534 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010535 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
10536 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010537 }
10538 }
10539 else
10540 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010541 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010542 }
10543 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010544 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010545
10546 if (eHAL_STATUS_FAILURE ==
10547 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
10548 0, NULL, eANI_BOOLEAN_FALSE))
10549 {
10550 hddLog(LOGE,
10551 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010552 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010553 }
10554
10555 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
10556 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10557 eANI_BOOLEAN_FALSE) )
10558 {
10559 hddLog(LOGE,
10560 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
10561 }
10562
10563 // Reset WNI_CFG_PROBE_RSP Flags
10564 wlan_hdd_reset_prob_rspies(pAdapter);
10565 kfree(pAdapter->sessionCtx.ap.beacon);
10566 pAdapter->sessionCtx.ap.beacon = NULL;
10567 }
10568 mutex_unlock(&pHddCtx->sap_lock);
Hanumanth Reddy Pothulab4537b82018-03-02 12:20:38 +053010569
10570#ifdef WLAN_NS_OFFLOAD
10571 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
10572#endif
10573 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
10574
Jeff Johnson295189b2012-06-20 16:38:30 -070010575 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -070010576
Jeff Johnson295189b2012-06-20 16:38:30 -070010577 case WLAN_HDD_MONITOR:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010578 if (VOS_MONITOR_MODE != hdd_get_conparam())
10579 wlan_hdd_stop_mon(pHddCtx, true);
10580 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -070010581
Jeff Johnson295189b2012-06-20 16:38:30 -070010582 default:
10583 break;
10584 }
10585
10586 EXIT();
10587 return VOS_STATUS_SUCCESS;
10588}
10589
Kapil Gupta137ef892016-12-13 19:38:00 +053010590/**
10591 * wlan_hdd_restart_sap() - to restart SAP in driver internally
10592 * @ap_adapter: - Pointer to SAP hdd_adapter_t structure
10593 *
10594 * wlan_hdd_restart_sap first delete SAP and do cleanup.
10595 * After that WLANSAP_StartBss start re-start process of SAP.
10596 *
10597 * Return: None
10598 */
10599static void wlan_hdd_restart_sap(hdd_adapter_t *ap_adapter)
10600{
10601 hdd_ap_ctx_t *pHddApCtx;
10602 hdd_hostapd_state_t *pHostapdState;
10603 VOS_STATUS vos_status;
10604 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(ap_adapter);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010605#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053010606 struct station_del_parameters delStaParams;
10607#endif
10608 tsap_Config_t *pConfig;
10609
10610 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
10611 pConfig = &pHddApCtx->sapConfig;
10612
10613 mutex_lock(&pHddCtx->sap_lock);
10614 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010615#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053010616 delStaParams.mac = NULL;
10617 delStaParams.subtype = SIR_MAC_MGMT_DEAUTH >> 4;
10618 delStaParams.reason_code = eCsrForcedDeauthSta;
10619 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
10620 &delStaParams);
10621#else
10622 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
10623 NULL);
10624#endif
10625 hdd_cleanup_actionframe(pHddCtx, ap_adapter);
10626
10627 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
10628 vos_event_reset(&pHostapdState->vosEvent);
10629
10630 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10631 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
10632 10000);
10633 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10634 hddLog(LOGE, FL("SAP Stop Failed"));
10635 goto end;
10636 }
10637 }
10638 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
10639 wlan_hdd_decr_active_session(pHddCtx, ap_adapter->device_mode);
10640 hddLog(LOG1, FL("SAP Stop Success"));
10641
10642 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
10643 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10644 goto end;
10645 }
10646
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053010647 vos_event_reset(&pHostapdState->vosEvent);
Kapil Gupta137ef892016-12-13 19:38:00 +053010648 if (WLANSAP_StartBss(pHddCtx->pvosContext, hdd_hostapd_SAPEventCB,
10649 pConfig, (v_PVOID_t)ap_adapter->dev) != VOS_STATUS_SUCCESS) {
10650 hddLog(LOGE, FL("SAP Start Bss fail"));
10651 goto end;
10652 }
10653
10654 hddLog(LOG1, FL("Waiting for SAP to start"));
10655 vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10656 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10657 hddLog(LOGE, FL("SAP Start failed"));
10658 goto end;
10659 }
10660 hddLog(LOG1, FL("SAP Start Success"));
10661 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
10662 wlan_hdd_incr_active_session(pHddCtx, ap_adapter->device_mode);
10663 pHostapdState->bCommit = TRUE;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010664 if (!VOS_IS_STATUS_SUCCESS(hdd_dhcp_mdns_offload(ap_adapter))) {
10665 hddLog(VOS_TRACE_LEVEL_ERROR, FL("DHCP/MDNS offload Failed!!"));
10666 vos_event_reset(&pHostapdState->vosEvent);
10667 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10668 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
10669 10000);
10670 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10671 hddLog(LOGE, FL("SAP Stop Failed"));
10672 goto end;
10673 }
10674 }
10675 }
Kapil Gupta137ef892016-12-13 19:38:00 +053010676 }
10677end:
10678 mutex_unlock(&pHddCtx->sap_lock);
10679 return;
10680}
10681
10682/**
10683 * __hdd_sap_restart_handle() - to handle restarting of SAP
10684 * @work: name of the work
10685 *
10686 * Purpose of this function is to trigger sap start. this function
10687 * will be called from workqueue.
10688 *
10689 * Return: void.
10690 */
10691static void __hdd_sap_restart_handle(struct work_struct *work)
10692{
10693 hdd_adapter_t *sap_adapter;
10694 hdd_context_t *hdd_ctx = container_of(work,
10695 hdd_context_t,
10696 sap_start_work);
10697 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
10698 vos_ssr_unprotect(__func__);
10699 return;
10700 }
10701 sap_adapter = hdd_get_adapter(hdd_ctx,
10702 WLAN_HDD_SOFTAP);
10703 if (sap_adapter == NULL) {
10704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10705 FL("sap_adapter is NULL"));
10706 vos_ssr_unprotect(__func__);
10707 return;
10708 }
10709
10710 if (hdd_ctx->is_ch_avoid_in_progress) {
10711 sap_adapter->sessionCtx.ap.sapConfig.channel = AUTO_CHANNEL_SELECT;
10712 wlan_hdd_restart_sap(sap_adapter);
10713 hdd_change_ch_avoidance_status(hdd_ctx, false);
10714 }
Agrawal Ashish574b3e62017-02-09 18:58:34 +053010715 if (hdd_ctx->cfg_ini->enable_sap_auth_offload)
10716 wlan_hdd_restart_sap(sap_adapter);
Kapil Gupta137ef892016-12-13 19:38:00 +053010717}
10718
10719/**
10720 * hdd_sap_restart_handle() - to handle restarting of SAP
10721 * @work: name of the work
10722 *
10723 * Purpose of this function is to trigger sap start. this function
10724 * will be called from workqueue.
10725 *
10726 * Return: void.
10727 */
10728static void hdd_sap_restart_handle(struct work_struct *work)
10729{
10730 vos_ssr_protect(__func__);
10731 __hdd_sap_restart_handle(work);
10732 vos_ssr_unprotect(__func__);
10733}
10734
10735
Abhishek Singh78c691f2017-11-30 13:48:44 +053010736/**
10737 * __hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
10738 * @work: name of the work
10739 *
10740 * Purpose of this function is to force SCC using ECSA. This function
10741 * will be called from workqueue.
10742 *
10743 * Return: void.
10744 */
10745static void
10746__hdd_force_scc_with_ecsa_handle(struct work_struct *work)
10747{
10748 hdd_adapter_t *sap_adapter;
10749 hdd_station_ctx_t *sta_ctx;
10750 hdd_adapter_t *sta_adapter;
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010751 ptSapContext sap_ctx = NULL;
10752 v_CONTEXT_t vos_ctx;
10753 tANI_U8 target_channel;
10754 tsap_Config_t *sap_config;
10755 bool sta_sap_scc_on_dfs_chan;
10756 eNVChannelEnabledType chan_state;
Abhishek Singh78c691f2017-11-30 13:48:44 +053010757 hdd_context_t *hdd_ctx = container_of(to_delayed_work(work),
10758 hdd_context_t,
10759 ecsa_chan_change_work);
10760
10761 if (wlan_hdd_validate_context(hdd_ctx))
10762 return;
10763
10764 sap_adapter = hdd_get_adapter(hdd_ctx,
10765 WLAN_HDD_SOFTAP);
10766 if (!sap_adapter) {
10767 hddLog(LOGE, FL("sap_adapter is NULL"));
10768 return;
10769 }
10770
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010771 vos_ctx = hdd_ctx->pvosContext;
10772 if (!vos_ctx) {
10773 hddLog(LOGE, FL("vos_ctx is NULL"));
10774 return;
10775 }
10776
10777 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
10778 if (!sap_ctx) {
10779 hddLog(LOGE, FL("sap_ctx is NULL"));
10780 return;
10781 }
10782
10783 sap_config = &sap_adapter->sessionCtx.ap.sapConfig;
10784
10785 sta_sap_scc_on_dfs_chan = hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_ctx);
10786
Abhishek Singh78c691f2017-11-30 13:48:44 +053010787 sta_adapter = hdd_get_adapter(hdd_ctx,
10788 WLAN_HDD_INFRA_STATION);
10789 if (!sta_adapter) {
10790 hddLog(LOGE, FL("sta_adapter is NULL"));
10791 return;
10792 }
Abhishek Singh78c691f2017-11-30 13:48:44 +053010793
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010794 if (wlansap_chk_n_set_chan_change_in_progress(sap_ctx))
Abhishek Singh78c691f2017-11-30 13:48:44 +053010795 return;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010796 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
10797
10798 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
10799 if (sta_ctx->conn_info.connState != eConnectionState_Associated) {
10800 if (sta_ctx->conn_info.connState == eConnectionState_NotConnected) {
10801 chan_state = vos_nv_getChannelEnabledState(sap_ctx->channel);
10802 hddLog(LOG1, FL("sta not in connected state %d, sta_sap_scc_on_dfs_chan %d, chan_state %d"),
10803 sta_ctx->conn_info.connState, sta_sap_scc_on_dfs_chan,
10804 chan_state);
10805 if (sta_sap_scc_on_dfs_chan &&
10806 (chan_state == NV_CHANNEL_DFS)) {
10807 hddLog(LOGE, FL("Switch SAP to user configured channel"));
10808 target_channel = sap_config->user_config_channel;
10809 goto switch_channel;
10810 }
10811 }
10812 goto abort;
Abhishek Singh78c691f2017-11-30 13:48:44 +053010813 }
10814
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010815 target_channel = sta_ctx->conn_info.operationChannel;
10816switch_channel:
10817 hddLog(LOGE, FL("Switch SAP to %d channel"),
10818 target_channel);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010819 if (!wlansap_set_channel_change(vos_ctx, target_channel, true))
10820 return;
10821
10822abort:
10823 wlansap_reset_chan_change_in_progress(sap_ctx);
10824 complete(&sap_ctx->ecsa_info.chan_switch_comp);
Abhishek Singh78c691f2017-11-30 13:48:44 +053010825}
10826
10827/**
10828 * hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
10829 * @work: name of the work
10830 *
10831 * Purpose of this function is to force SCC using ECSA. This function
10832 * will be called from workqueue.
10833 *
10834 * Return: void.
10835 */
10836static void
10837hdd_force_scc_with_ecsa_handle(struct work_struct *work)
10838{
10839 vos_ssr_protect(__func__);
10840 __hdd_force_scc_with_ecsa_handle(work);
10841 vos_ssr_unprotect(__func__);
10842}
10843
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010844int hdd_wait_for_ecsa_complete(hdd_context_t *hdd_ctx)
10845{
10846 int ret;
10847 ptSapContext sap_ctx = NULL;
10848 v_CONTEXT_t vos_ctx;
10849
10850 vos_ctx = hdd_ctx->pvosContext;
10851 if (!vos_ctx) {
10852 hddLog(LOGE, FL("vos_ctx is NULL"));
10853 return 0;
10854 }
10855
10856 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
10857 if (!sap_ctx) {
10858 hddLog(LOG1, FL("sap_ctx is NULL"));
10859 return 0;
10860 }
10861 if(!sap_ctx->isSapSessionOpen) {
10862 hddLog(LOG1, FL("sap session not opened, SAP in state %d"),
10863 sap_ctx->sapsMachine);
10864 return 0;
10865 }
10866
10867 if (!wlansap_get_change_in_progress(sap_ctx)) {
10868 hddLog(LOG1, FL("channel switch not in progress"));
10869 return 0;
10870 }
10871 ret = wait_for_completion_timeout(&sap_ctx->ecsa_info.chan_switch_comp,
10872 msecs_to_jiffies(HDD_SAP_CHAN_CNG_WAIT_TIME));
10873 if (!ret)
10874 {
10875 hddLog(LOGE, FL("Timeout waiting for SAP channel switch"));
10876 return ret;
10877 }
10878
10879 return 0;
10880}
10881
10882
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010883/**
10884 * hdd_is_sta_sap_scc_allowed_on_dfs_chan() - check if sta+sap scc allowed on
10885 * dfs chan
10886 * @hdd_ctx: pointer to hdd context
10887 *
10888 * This function used to check if sta+sap scc allowed on DFS channel.
10889 *
10890 * Return: None
10891 */
10892bool hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_context_t *hdd_ctx)
10893{
10894 if (hdd_ctx->cfg_ini->force_scc_with_ecsa &&
10895 hdd_ctx->cfg_ini->sta_sap_scc_on_dfs_chan)
10896 return true;
10897 else
10898 return false;
10899}
10900
Jeff Johnson295189b2012-06-20 16:38:30 -070010901VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
10902{
10903 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10904 VOS_STATUS status;
10905 hdd_adapter_t *pAdapter;
10906
10907 ENTER();
10908
10909 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10910
10911 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10912 {
10913 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010914
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010915 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -070010916
10917 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10918 pAdapterNode = pNext;
10919 }
10920
10921 EXIT();
10922
10923 return VOS_STATUS_SUCCESS;
10924}
10925
Rajeev Kumarf999e582014-01-09 17:33:29 -080010926
10927#ifdef FEATURE_WLAN_BATCH_SCAN
10928/**---------------------------------------------------------------------------
10929
10930 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
10931 structures
10932
10933 \param - pAdapter Pointer to HDD adapter
10934
10935 \return - None
10936
10937 --------------------------------------------------------------------------*/
10938void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
10939{
10940 tHddBatchScanRsp *pNode;
10941 tHddBatchScanRsp *pPrev;
10942
Siddharth Bhalb3e9b792014-02-24 15:14:16 +053010943 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -080010944 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +053010945 hddLog(VOS_TRACE_LEVEL_ERROR,
10946 "%s: Adapter context is Null", __func__);
10947 return;
10948 }
10949
10950 pNode = pAdapter->pBatchScanRsp;
10951 while (pNode)
10952 {
10953 pPrev = pNode;
10954 pNode = pNode->pNext;
10955 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -080010956 }
10957
10958 pAdapter->pBatchScanRsp = NULL;
10959 pAdapter->numScanList = 0;
10960 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
10961 pAdapter->prev_batch_id = 0;
10962
10963 return;
10964}
10965#endif
10966
10967
Jeff Johnson295189b2012-06-20 16:38:30 -070010968VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
10969{
10970 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10971 VOS_STATUS status;
10972 hdd_adapter_t *pAdapter;
10973
10974 ENTER();
10975
10976 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10977
10978 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10979 {
10980 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053010981 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010982 netif_tx_disable(pAdapter->dev);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053010983
10984 if (pHddCtx->cfg_ini->sap_internal_restart &&
10985 pAdapter->device_mode == WLAN_HDD_SOFTAP) {
10986 hddLog(LOG1, FL("driver supports sap restart"));
10987 vos_flush_work(&pHddCtx->sap_start_work);
10988 hdd_sap_indicate_disconnect_for_sta(pAdapter);
10989 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053010990 hdd_softap_deinit_tx_rx(pAdapter, true);
10991 hdd_sap_destroy_timers(pAdapter);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053010992 } else {
10993 netif_carrier_off(pAdapter->dev);
10994 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010995
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070010996 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053010997
10998 if (pAdapter->device_mode == WLAN_HDD_MONITOR)
10999 pAdapter->sessionCtx.monitor.state = MON_MODE_STOP;
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070011000
Jeff Johnson295189b2012-06-20 16:38:30 -070011001 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +053011002
Katya Nigam1fd24402015-02-16 14:52:19 +053011003 if(pAdapter->device_mode == WLAN_HDD_IBSS )
11004 hdd_ibss_deinit_tx_rx(pAdapter);
11005
Nirav Shah7e3c8132015-06-22 23:51:42 +053011006 status = hdd_sta_id_hash_detach(pAdapter);
11007 if (status != VOS_STATUS_SUCCESS)
11008 hddLog(VOS_TRACE_LEVEL_ERROR,
11009 FL("sta id hash detach failed for session id %d"),
11010 pAdapter->sessionId);
11011
Agarwal Ashish6267caa2014-08-06 19:16:21 +053011012 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11013
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +053011014 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
11015 {
11016 hdd_wmm_adapter_close( pAdapter );
11017 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
11018 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011019
Siddharth Bhal2db319d2014-12-03 12:37:18 +053011020 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11021 {
11022 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
11023 }
11024
Rajeev Kumarf999e582014-01-09 17:33:29 -080011025#ifdef FEATURE_WLAN_BATCH_SCAN
11026 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
11027 {
11028 hdd_deinit_batch_scan(pAdapter);
11029 }
11030#endif
11031
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +053011032#ifdef FEATURE_WLAN_TDLS
11033 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +053011034 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +053011035 mutex_unlock(&pHddCtx->tdls_lock);
11036#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011037 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11038 pAdapterNode = pNext;
11039 }
11040
11041 EXIT();
11042
11043 return VOS_STATUS_SUCCESS;
11044}
11045
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011046/**
Abhishek Singh5a597e62016-12-05 15:16:30 +053011047 * hdd_get_bss_entry() - Get the bss entry matching the chan, bssid and ssid
11048 * @wiphy: wiphy
11049 * @channel: channel of the BSS to find
11050 * @bssid: bssid of the BSS to find
11051 * @ssid: ssid of the BSS to find
11052 * @ssid_len: ssid len of of the BSS to find
11053 *
11054 * The API is a wrapper to get bss from kernel matching the chan,
11055 * bssid and ssid
11056 *
11057 * Return: Void
11058 */
11059#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
11060 && !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
11061
11062struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
11063 struct ieee80211_channel *channel,
11064 const u8 *bssid,
11065 const u8 *ssid, size_t ssid_len)
11066{
11067 return cfg80211_get_bss(wiphy, channel, bssid,
11068 ssid, ssid_len,
11069 WLAN_CAPABILITY_ESS,
11070 WLAN_CAPABILITY_ESS);
11071}
11072#else
11073struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
11074 struct ieee80211_channel *channel,
11075 const u8 *bssid,
11076 const u8 *ssid, size_t ssid_len)
11077{
11078 return cfg80211_get_bss(wiphy, channel, bssid,
11079 ssid, ssid_len,
11080 IEEE80211_BSS_TYPE_ESS,
11081 IEEE80211_PRIVACY_ANY);
11082}
11083#endif
11084
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011085#if defined(CFG80211_CONNECT_BSS) || \
11086 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
11087
11088#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) || \
11089 defined (CFG80211_CONNECT_TIMEOUT_REASON_CODE)
11090/**
11091 * hdd_connect_bss() - helper function to send connection status to supplicant
11092 * @dev: network device
11093 * @bssid: bssid to which we want to associate
11094 * @bss: information about connected bss
11095 * @req_ie: Request Information Element
11096 * @req_ie_len: len of the req IE
11097 * @resp_ie: Response IE
11098 * @resp_ie_len: len of ht response IE
11099 * @status: status
11100 * @gfp: Kernel Flag
11101 *
11102 * This is a helper function to send connection status to supplicant
11103 * and gets invoked from wrapper API
11104 *
11105 * Return: Void
11106 */
11107static void hdd_connect_bss(struct net_device *dev,
11108 const u8 *bssid,
11109 struct cfg80211_bss *bss,
11110 const u8 *req_ie,
11111 size_t req_ie_len,
11112 const u8 *resp_ie,
11113 size_t resp_ie_len,
11114 u16 status,
11115 gfp_t gfp)
11116{
11117 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
11118 resp_ie, resp_ie_len, status, gfp, NL80211_TIMEOUT_UNSPECIFIED);
11119}
11120#else
11121/**
11122 * hdd_connect_bss() - helper function to send connection status to supplicant
11123 * @dev: network device
11124 * @bssid: bssid to which we want to associate
11125 * @bss: information about connected bss
11126 * @req_ie: Request Information Element
11127 * @req_ie_len: len of the req IE
11128 * @resp_ie: Response IE
11129 * @resp_ie_len: len of ht response IE
11130 * @status: status
11131 * @gfp: Kernel Flag
11132 *
11133 * This is a helper function to send connection status to supplicant
11134 * and gets invoked from wrapper API
11135 *
11136 * Return: Void
11137 */
11138static void hdd_connect_bss(struct net_device *dev,
11139 const u8 *bssid,
11140 struct cfg80211_bss *bss,
11141 const u8 *req_ie,
11142 size_t req_ie_len,
11143 const u8 *resp_ie,
11144 size_t resp_ie_len,
11145 u16 status,
11146 gfp_t gfp)
11147{
11148 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
11149 resp_ie, resp_ie_len, status, gfp);
11150}
11151#endif
11152
Abhishek Singh5a597e62016-12-05 15:16:30 +053011153/**
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011154 * hdd_connect_result() - API to send connection status to supplicant
11155 * @dev: network device
11156 * @bssid: bssid to which we want to associate
11157 * @roam_info: information about connected bss
11158 * @req_ie: Request Information Element
11159 * @req_ie_len: len of the req IE
11160 * @resp_ie: Response IE
11161 * @resp_ie_len: len of ht response IE
11162 * @status: status
11163 * @gfp: Kernel Flag
11164 *
11165 * The API is a wrapper to send connection status to supplicant
11166 *
11167 * Return: Void
11168 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011169void hdd_connect_result(struct net_device *dev,
11170 const u8 *bssid,
11171 tCsrRoamInfo *roam_info,
11172 const u8 *req_ie,
11173 size_t req_ie_len,
11174 const u8 *resp_ie,
11175 size_t resp_ie_len,
11176 u16 status,
11177 gfp_t gfp)
11178{
11179 hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev);
11180 struct cfg80211_bss *bss = NULL;
11181
11182 if (WLAN_STATUS_SUCCESS == status) {
11183 struct ieee80211_channel *chan;
11184 int freq;
11185 int chan_no = roam_info->pBssDesc->channelId;;
11186
11187 if (chan_no <= 14)
11188 freq = ieee80211_channel_to_frequency(chan_no,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011189 HDD_NL80211_BAND_2GHZ);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011190 else
11191 freq = ieee80211_channel_to_frequency(chan_no,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011192 HDD_NL80211_BAND_5GHZ);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011193
11194 chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
Abhishek Singh5a597e62016-12-05 15:16:30 +053011195 bss = hdd_get_bss_entry(padapter->wdev.wiphy,
11196 chan, bssid,
11197 roam_info->u.pConnectedProfile->SSID.ssId,
11198 roam_info->u.pConnectedProfile->SSID.length);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011199 }
11200
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011201 hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie, resp_ie_len,
11202 status, gfp);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011203}
11204#else
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011205/**
11206 * hdd_connect_result() - API to send connection status to supplicant
11207 * @dev: network device
11208 * @bssid: bssid to which we want to associate
11209 * @roam_info: information about connected bss
11210 * @req_ie: Request Information Element
11211 * @req_ie_len: len of the req IE
11212 * @resp_ie: Response IE
11213 * @resp_ie_len: len of ht response IE
11214 * @status: status
11215 * @gfp: Kernel Flag
11216 *
11217 * The API is a wrapper to send connection status to supplicant
11218 *
11219 * Return: Void
11220 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011221void hdd_connect_result(struct net_device *dev,
11222 const u8 *bssid,
11223 tCsrRoamInfo *roam_info,
11224 const u8 *req_ie,
11225 size_t req_ie_len,
11226 const u8 * resp_ie,
11227 size_t resp_ie_len,
11228 u16 status,
11229 gfp_t gfp)
11230{
11231 cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
11232 resp_ie, resp_ie_len, status, gfp);
11233}
11234#endif
11235
Jeff Johnson295189b2012-06-20 16:38:30 -070011236VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
11237{
11238 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11239 VOS_STATUS status;
11240 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011241 eConnectionState connState;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011242 v_CONTEXT_t pVosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011243
11244 ENTER();
11245
11246 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11247
11248 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11249 {
11250 pAdapter = pAdapterNode->pAdapter;
11251
Kumar Anand82c009f2014-05-29 00:29:42 -070011252 hdd_wmm_init( pAdapter );
11253
Jeff Johnson295189b2012-06-20 16:38:30 -070011254 switch(pAdapter->device_mode)
11255 {
11256 case WLAN_HDD_INFRA_STATION:
11257 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -070011258 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011259
11260 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
11261
Jeff Johnson295189b2012-06-20 16:38:30 -070011262 hdd_init_station_mode(pAdapter);
11263 /* Open the gates for HDD to receive Wext commands */
11264 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011265 pHddCtx->scan_info.mScanPending = FALSE;
11266 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011267
11268 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +053011269 if (!pHddCtx->isLogpInProgress)
11270 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011271
11272 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011273 if (eConnectionState_Associated == connState ||
11274 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -070011275 {
11276 union iwreq_data wrqu;
11277 memset(&wrqu, '\0', sizeof(wrqu));
11278 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
11279 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
11280 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070011281 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011282
Jeff Johnson295189b2012-06-20 16:38:30 -070011283 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagar9ff4bcc2016-06-01 17:17:50 +053011284 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, false,
Mahesh A Saptasagarb5a15142016-05-25 11:27:43 +053011285 WLAN_REASON_UNSPECIFIED);
Jeff Johnson295189b2012-06-20 16:38:30 -070011286 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011287 else if (eConnectionState_Connecting == connState)
11288 {
11289 /*
11290 * Indicate connect failure to supplicant if we were in the
11291 * process of connecting
11292 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011293 hdd_connect_result(pAdapter->dev, NULL, NULL,
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011294 NULL, 0, NULL, 0,
11295 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
11296 GFP_KERNEL);
11297 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011298 break;
11299
11300 case WLAN_HDD_SOFTAP:
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011301 if (pHddCtx->cfg_ini->sap_internal_restart) {
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011302 hdd_init_ap_mode(pAdapter, true);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011303 status = hdd_sta_id_hash_attach(pAdapter);
11304 if (VOS_STATUS_SUCCESS != status)
11305 {
11306 hddLog(VOS_TRACE_LEVEL_FATAL,
11307 FL("failed to attach hash for"));
11308 }
11309 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011310 break;
11311
11312 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -070011313 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -070011314 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -070011315 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -070011316 break;
11317
11318 case WLAN_HDD_MONITOR:
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011319 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11320
11321 hddLog(VOS_TRACE_LEVEL_INFO, FL("[SSR] monitor mode"));
11322 if (!pVosContext) {
11323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos context is NULL"));
11324 break;
11325 }
11326
11327 hdd_init_tx_rx(pAdapter);
11328 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk);
Jeff Johnson295189b2012-06-20 16:38:30 -070011329 break;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011330
Jeff Johnson295189b2012-06-20 16:38:30 -070011331 default:
11332 break;
11333 }
11334
11335 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11336 pAdapterNode = pNext;
11337 }
11338
11339 EXIT();
11340
11341 return VOS_STATUS_SUCCESS;
11342}
11343
11344VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
11345{
11346 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11347 hdd_adapter_t *pAdapter;
11348 VOS_STATUS status;
11349 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011350 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011351
11352 ENTER();
11353
11354 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11355
11356 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11357 {
11358 pAdapter = pAdapterNode->pAdapter;
11359
11360 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11361 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11362 {
11363 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11364 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11365
Abhishek Singhf4669da2014-05-26 15:07:49 +053011366 hddLog(VOS_TRACE_LEVEL_INFO,
11367 "%s: Set HDD connState to eConnectionState_NotConnected",
11368 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +053011369 spin_lock_bh(&pAdapter->lock_for_active_session);
11370 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11371 {
11372 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11373 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011374 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +053011375 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -070011376 init_completion(&pAdapter->disconnect_comp_var);
11377 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
11378 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11379
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011380 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070011381 &pAdapter->disconnect_comp_var,
11382 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011383 if (0 >= ret)
11384 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
11385 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -070011386
11387 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
11388 pHddCtx->isAmpAllowed = VOS_FALSE;
11389 sme_RoamConnect(pHddCtx->hHal,
11390 pAdapter->sessionId, &(pWextState->roamProfile),
11391 &roamId);
11392 }
11393
11394 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11395 pAdapterNode = pNext;
11396 }
11397
11398 EXIT();
11399
11400 return VOS_STATUS_SUCCESS;
11401}
11402
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011403void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
11404{
11405 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11406 VOS_STATUS status;
11407 hdd_adapter_t *pAdapter;
11408 hdd_station_ctx_t *pHddStaCtx;
11409 hdd_ap_ctx_t *pHddApCtx;
11410 hdd_hostapd_state_t * pHostapdState;
11411 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
11412 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
11413 const char *p2pMode = "DEV";
11414 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011415
11416 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11417 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11418 {
11419 pAdapter = pAdapterNode->pAdapter;
11420 switch (pAdapter->device_mode) {
11421 case WLAN_HDD_INFRA_STATION:
11422 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11423 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
11424 staChannel = pHddStaCtx->conn_info.operationChannel;
11425 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
11426 }
11427 break;
11428 case WLAN_HDD_P2P_CLIENT:
11429 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11430 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
11431 p2pChannel = pHddStaCtx->conn_info.operationChannel;
11432 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
11433 p2pMode = "CLI";
11434 }
11435 break;
11436 case WLAN_HDD_P2P_GO:
11437 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11438 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11439 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
11440 p2pChannel = pHddApCtx->operatingChannel;
11441 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
11442 }
11443 p2pMode = "GO";
11444 break;
11445 case WLAN_HDD_SOFTAP:
11446 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11447 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11448 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
11449 apChannel = pHddApCtx->operatingChannel;
11450 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
11451 }
11452 break;
11453 default:
11454 break;
11455 }
11456 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11457 pAdapterNode = pNext;
11458 }
11459 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
11460 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
11461 }
Yeshwanth Sriram Guntuka0004c0b2017-12-06 14:43:49 +053011462 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s",
11463 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011464 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053011465 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011466 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
11467 }
11468 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053011469 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011470 apChannel, MAC_ADDR_ARRAY(apBssid));
11471 }
11472
11473 if (p2pChannel > 0 && apChannel > 0) {
11474 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
11475 }
11476}
11477
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011478bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070011479{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011480 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -070011481}
11482
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011483/* Once SSR is disabled then it cannot be set. */
11484void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -070011485{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011486 if (HDD_SSR_DISABLED == isSsrRequired)
11487 return;
11488
Jeff Johnson295189b2012-06-20 16:38:30 -070011489 isSsrRequired = value;
11490}
11491
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +053011492void hdd_set_pre_close( hdd_context_t *pHddCtx)
11493{
11494 sme_PreClose(pHddCtx->hHal);
11495}
11496
Jeff Johnson295189b2012-06-20 16:38:30 -070011497VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
11498 hdd_adapter_list_node_t** ppAdapterNode)
11499{
11500 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011501 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011502 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
11503 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011504 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011505 return status;
11506}
11507
11508VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
11509 hdd_adapter_list_node_t* pAdapterNode,
11510 hdd_adapter_list_node_t** pNextAdapterNode)
11511{
11512 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011513 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011514 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
11515 (hdd_list_node_t*) pAdapterNode,
11516 (hdd_list_node_t**)pNextAdapterNode );
11517
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011518 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011519 return status;
11520}
11521
11522VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
11523 hdd_adapter_list_node_t* pAdapterNode)
11524{
11525 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011526 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011527 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
11528 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011529 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011530 return status;
11531}
11532
11533VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
11534 hdd_adapter_list_node_t** ppAdapterNode)
11535{
11536 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011537 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011538 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
11539 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011540 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011541 return status;
11542}
11543
11544VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
11545 hdd_adapter_list_node_t* pAdapterNode)
11546{
11547 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011548 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011549 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
11550 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011551 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011552 return status;
11553}
11554
11555VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
11556 hdd_adapter_list_node_t* pAdapterNode)
11557{
11558 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011559 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011560 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
11561 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011562 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011563 return status;
11564}
11565
11566hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
11567 tSirMacAddr macAddr )
11568{
11569 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11570 hdd_adapter_t *pAdapter;
11571 VOS_STATUS status;
11572
11573 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11574
11575 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11576 {
11577 pAdapter = pAdapterNode->pAdapter;
11578
11579 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
11580 macAddr, sizeof(tSirMacAddr) ) )
11581 {
11582 return pAdapter;
11583 }
11584 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11585 pAdapterNode = pNext;
11586 }
11587
11588 return NULL;
11589
11590}
11591
11592hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
11593{
11594 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11595 hdd_adapter_t *pAdapter;
11596 VOS_STATUS status;
11597
11598 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11599
11600 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11601 {
11602 pAdapter = pAdapterNode->pAdapter;
11603
11604 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
11605 IFNAMSIZ ) )
11606 {
11607 return pAdapter;
11608 }
11609 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11610 pAdapterNode = pNext;
11611 }
11612
11613 return NULL;
11614
11615}
11616
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053011617hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
11618 tANI_U32 sme_session_id )
11619{
11620 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11621 hdd_adapter_t *pAdapter;
11622 VOS_STATUS vos_status;
11623
11624
11625 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11626
11627 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
11628 {
11629 pAdapter = pAdapterNode->pAdapter;
11630
11631 if (pAdapter->sessionId == sme_session_id)
11632 return pAdapter;
11633
11634 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
11635 pAdapterNode = pNext;
11636 }
11637
11638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11639 "%s: sme_session_id %d does not exist with host",
11640 __func__, sme_session_id);
11641
11642 return NULL;
11643}
11644
Jeff Johnson295189b2012-06-20 16:38:30 -070011645hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
11646{
11647 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11648 hdd_adapter_t *pAdapter;
11649 VOS_STATUS status;
11650
11651 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11652
11653 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11654 {
11655 pAdapter = pAdapterNode->pAdapter;
11656
11657 if( pAdapter && (mode == pAdapter->device_mode) )
11658 {
11659 return pAdapter;
11660 }
11661 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11662 pAdapterNode = pNext;
11663 }
11664
11665 return NULL;
11666
11667}
11668
11669//Remove this function later
11670hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
11671{
11672 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11673 hdd_adapter_t *pAdapter;
11674 VOS_STATUS status;
11675
11676 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11677
11678 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11679 {
11680 pAdapter = pAdapterNode->pAdapter;
11681
11682 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
11683 {
11684 return pAdapter;
11685 }
11686
11687 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11688 pAdapterNode = pNext;
11689 }
11690
11691 return NULL;
11692
11693}
11694
Jeff Johnson295189b2012-06-20 16:38:30 -070011695/**---------------------------------------------------------------------------
11696
Mahesh A Saptasgar64534612014-09-23 13:13:33 +053011697 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -070011698
11699 This API returns the operating channel of the requested device mode
11700
11701 \param - pHddCtx - Pointer to the HDD context.
11702 - mode - Device mode for which operating channel is required
11703 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
11704 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
11705 \return - channel number. "0" id the requested device is not found OR it is not connected.
11706 --------------------------------------------------------------------------*/
11707v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
11708{
11709 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11710 VOS_STATUS status;
11711 hdd_adapter_t *pAdapter;
11712 v_U8_t operatingChannel = 0;
11713
11714 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11715
11716 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11717 {
11718 pAdapter = pAdapterNode->pAdapter;
11719
11720 if( mode == pAdapter->device_mode )
11721 {
11722 switch(pAdapter->device_mode)
11723 {
11724 case WLAN_HDD_INFRA_STATION:
11725 case WLAN_HDD_P2P_CLIENT:
11726 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
11727 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
11728 break;
11729 case WLAN_HDD_SOFTAP:
11730 case WLAN_HDD_P2P_GO:
11731 /*softap connection info */
11732 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11733 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
11734 break;
11735 default:
11736 break;
11737 }
11738
11739 break; //Found the device of interest. break the loop
11740 }
11741
11742 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11743 pAdapterNode = pNext;
11744 }
11745 return operatingChannel;
11746}
11747
11748#ifdef WLAN_FEATURE_PACKET_FILTERING
11749/**---------------------------------------------------------------------------
11750
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011751 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -070011752
11753 This used to set the multicast address list.
11754
11755 \param - dev - Pointer to the WLAN device.
11756 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011757 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -070011758
11759 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011760static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -070011761{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011762 hdd_adapter_t *pAdapter;
11763 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011764 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011765 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011766 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011767
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011768 ENTER();
11769
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011770 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011771 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070011772 {
11773 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011774 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011775 return;
11776 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011777 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11778 ret = wlan_hdd_validate_context(pHddCtx);
11779 if (0 != ret)
11780 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011781 return;
11782 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011783 if (dev->flags & IFF_ALLMULTI)
11784 {
11785 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011786 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011787 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011788 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011789 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011790 {
11791 mc_count = netdev_mc_count(dev);
11792 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011793 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -070011794 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
11795 {
11796 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011797 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011798 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011799 return;
11800 }
11801
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011802 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -070011803
11804 netdev_for_each_mc_addr(ha, dev) {
11805 if (i == mc_count)
11806 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011807 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
11808 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -080011809 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011810 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011811 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -070011812 i++;
11813 }
11814 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011815
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +053011816 if (pHddCtx->hdd_wlan_suspended)
11817 {
11818 /*
11819 * Configure the Mcast address list to FW
11820 * If wlan is already in suspend mode
11821 */
11822 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
11823 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011824 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011825 return;
11826}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011827
11828static void hdd_set_multicast_list(struct net_device *dev)
11829{
11830 vos_ssr_protect(__func__);
11831 __hdd_set_multicast_list(dev);
11832 vos_ssr_unprotect(__func__);
11833}
Jeff Johnson295189b2012-06-20 16:38:30 -070011834#endif
11835
11836/**---------------------------------------------------------------------------
11837
11838 \brief hdd_select_queue() -
11839
11840 This function is registered with the Linux OS for network
11841 core to decide which queue to use first.
11842
11843 \param - dev - Pointer to the WLAN device.
11844 - skb - Pointer to OS packet (sk_buff).
11845 \return - ac, Queue Index/access category corresponding to UP in IP header
11846
11847 --------------------------------------------------------------------------*/
11848v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011849 struct sk_buff *skb
11850#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
11851 , void *accel_priv
11852#endif
11853#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
11854 , select_queue_fallback_t fallback
11855#endif
11856)
Jeff Johnson295189b2012-06-20 16:38:30 -070011857{
11858 return hdd_wmm_select_queue(dev, skb);
11859}
11860
11861
11862/**---------------------------------------------------------------------------
11863
11864 \brief hdd_wlan_initial_scan() -
11865
11866 This function triggers the initial scan
11867
11868 \param - pAdapter - Pointer to the HDD adapter.
11869
11870 --------------------------------------------------------------------------*/
11871void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
11872{
11873 tCsrScanRequest scanReq;
11874 tCsrChannelInfo channelInfo;
11875 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -070011876 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011877 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11878
11879 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
11880 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
11881 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
11882
11883 if(sme_Is11dSupported(pHddCtx->hHal))
11884 {
11885 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
11886 if ( HAL_STATUS_SUCCESS( halStatus ) )
11887 {
11888 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
11889 if( !scanReq.ChannelInfo.ChannelList )
11890 {
11891 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
11892 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080011893 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011894 return;
11895 }
11896 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
11897 channelInfo.numOfChannels);
11898 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
11899 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080011900 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011901 }
11902
11903 scanReq.scanType = eSIR_PASSIVE_SCAN;
11904 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
11905 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
11906 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
11907 }
11908 else
11909 {
11910 scanReq.scanType = eSIR_ACTIVE_SCAN;
11911 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
11912 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
11913 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
11914 }
11915
11916 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
11917 if ( !HAL_STATUS_SUCCESS( halStatus ) )
11918 {
11919 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
11920 __func__, halStatus );
11921 }
11922
11923 if(sme_Is11dSupported(pHddCtx->hHal))
11924 vos_mem_free(scanReq.ChannelInfo.ChannelList);
11925}
11926
Jeff Johnson295189b2012-06-20 16:38:30 -070011927/**---------------------------------------------------------------------------
11928
11929 \brief hdd_full_power_callback() - HDD full power callback function
11930
11931 This is the function invoked by SME to inform the result of a full power
11932 request issued by HDD
11933
11934 \param - callbackcontext - Pointer to cookie
11935 \param - status - result of request
11936
11937 \return - None
11938
11939 --------------------------------------------------------------------------*/
11940static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
11941{
Jeff Johnson72a40512013-12-19 10:14:15 -080011942 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011943
11944 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070011945 "%s: context = %pK, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070011946
11947 if (NULL == callbackContext)
11948 {
11949 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070011950 "%s: Bad param, context [%pK]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011951 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011952 return;
11953 }
11954
Jeff Johnson72a40512013-12-19 10:14:15 -080011955 /* there is a race condition that exists between this callback
11956 function and the caller since the caller could time out either
11957 before or while this code is executing. we use a spinlock to
11958 serialize these actions */
11959 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011960
11961 if (POWER_CONTEXT_MAGIC != pContext->magic)
11962 {
11963 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -080011964 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011965 hddLog(VOS_TRACE_LEVEL_WARN,
11966 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011967 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -070011968 return;
11969 }
11970
Jeff Johnson72a40512013-12-19 10:14:15 -080011971 /* context is valid so caller is still waiting */
11972
11973 /* paranoia: invalidate the magic */
11974 pContext->magic = 0;
11975
11976 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -070011977 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -080011978
11979 /* serialization is complete */
11980 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011981}
11982
Katya Nigamf0511f62015-05-05 16:40:57 +053011983void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
11984{
11985 pMonCtx->typeSubtypeBitmap = 0;
11986 if( type%10 ) /* Management Packets */
11987 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
11988 type/=10;
11989 if( type%10 ) /* Control Packets */
11990 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
11991 type/=10;
11992 if( type%10 ) /* Data Packets */
11993 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
11994}
11995
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053011996VOS_STATUS wlan_hdd_mon_postMsg(void *context, hdd_mon_ctx_t *pMonCtx,
11997 void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +053011998{
11999 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012000 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053012001
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012002 if (MON_MODE_START == pMonCtx->state)
12003 monMsg.type = WDA_MON_START_REQ;
12004 else if (MON_MODE_STOP == pMonCtx->state)
12005 monMsg.type = WDA_MON_STOP_REQ;
12006 else {
12007 hddLog(VOS_TRACE_LEVEL_ERROR,
12008 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +053012009 return VOS_STATUS_E_FAILURE;
12010 }
12011
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012012 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
12013 if (pMonModeReq == NULL) {
12014 hddLog(VOS_TRACE_LEVEL_ERROR,
12015 FL("fail to allocate memory for monitor mode req"));
12016 return VOS_STATUS_E_FAILURE;
12017 }
Katya Nigamf0511f62015-05-05 16:40:57 +053012018
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012019 pMonModeReq->context = context;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012020 pMonModeReq->data = pMonCtx;
12021 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +053012022
Katya Nigamf0511f62015-05-05 16:40:57 +053012023 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012024 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053012025 monMsg.bodyval = 0;
12026
12027 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
12028 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
12029 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012030 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +053012031 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012032 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +053012033}
12034
Katya Nigame7b69a82015-04-28 15:24:06 +053012035void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
12036{
12037 VOS_STATUS vosStatus;
12038 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012039 hdd_mon_ctx_t *pMonCtx = NULL;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012040 int ret;
12041 void *cookie;
12042 struct hdd_request *request;
12043 static const struct hdd_request_params params = {
12044 .priv_size = 0,
12045 .timeout_ms = MON_MODE_MSG_TIMEOUT,
12046 };
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053012047
Katya Nigame7b69a82015-04-28 15:24:06 +053012048 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
12049 if(pAdapter == NULL || pVosContext == NULL)
12050 {
12051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
12052 return ;
12053 }
Katya Nigamf0511f62015-05-05 16:40:57 +053012054
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012055 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
12056 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
12057 pMonCtx->state = MON_MODE_STOP;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012058 request = hdd_request_alloc(&params);
12059 if (!request) {
12060 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
12061 return;
12062 }
12063 cookie = hdd_request_cookie(request);
12064
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012065 if (VOS_STATUS_SUCCESS !=
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012066 wlan_hdd_mon_postMsg(cookie, pMonCtx,
12067 hdd_mon_post_msg_cb)) {
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012068 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12069 FL("failed to post MON MODE REQ"));
12070 pMonCtx->state = MON_MODE_START;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012071 goto req_put;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012072 }
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012073
12074 ret = hdd_request_wait_for_response(request);
12075 if (ret)
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012077 FL("timeout on monitor mode completion %d"), ret);
12078
12079req_put:
12080 hdd_request_put(request);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012081 }
12082
Katya Nigame7b69a82015-04-28 15:24:06 +053012083 hdd_UnregisterWext(pAdapter->dev);
12084
12085 vos_mon_stop( pVosContext );
12086
12087 vosStatus = vos_sched_close( pVosContext );
12088 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
12089 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12090 "%s: Failed to close VOSS Scheduler",__func__);
12091 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12092 }
12093
12094 vosStatus = vos_nv_close();
12095 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12096 {
12097 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12098 "%s: Failed to close NV", __func__);
12099 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12100 }
12101
12102 vos_close(pVosContext);
12103
12104 #ifdef WLAN_KD_READY_NOTIFIER
12105 nl_srv_exit(pHddCtx->ptt_pid);
12106 #else
12107 nl_srv_exit();
12108 #endif
12109
Katya Nigame7b69a82015-04-28 15:24:06 +053012110 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +053012111}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012112/**
12113 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
12114 * @ wiphy: the wiphy to validate against
12115 *
12116 * Return: void
12117 */
12118void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
12119{
12120 int i =0;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053012121 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012122 {
12123 if (NULL != wiphy->bands[i] &&
12124 (NULL != wiphy->bands[i]->channels))
12125 {
12126 vos_mem_free(wiphy->bands[i]->channels);
12127 wiphy->bands[i]->channels = NULL;
12128 }
12129 }
12130}
Jeff Johnson295189b2012-06-20 16:38:30 -070012131/**---------------------------------------------------------------------------
12132
12133 \brief hdd_wlan_exit() - HDD WLAN exit function
12134
12135 This is the driver exit point (invoked during rmmod)
12136
12137 \param - pHddCtx - Pointer to the HDD Context
12138
12139 \return - None
12140
12141 --------------------------------------------------------------------------*/
12142void hdd_wlan_exit(hdd_context_t *pHddCtx)
12143{
12144 eHalStatus halStatus;
12145 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
12146 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +053012147 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080012148 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -080012149 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012150 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +053012151 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012152
12153 ENTER();
12154
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012155
Katya Nigame7b69a82015-04-28 15:24:06 +053012156 if (VOS_MONITOR_MODE == hdd_get_conparam())
12157 {
12158 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
12159 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053012160 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +053012161 }
12162 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -080012163 {
12164 // Unloading, restart logic is no more required.
12165 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -070012166
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053012167#ifdef FEATURE_WLAN_TDLS
12168 /* At the time of driver unloading; if tdls connection is present;
12169 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
12170 * wlan_hdd_tdls_find_peer always checks for valid context;
12171 * as load/unload in progress there can be a race condition.
12172 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
12173 * when tdls state is enabled.
12174 * As soon as driver set load/unload flag; tdls flag also needs
12175 * to be disabled so that hdd_rx_packet_cbk won't call
12176 * wlan_hdd_tdls_find_peer.
12177 */
Masti, Narayanraddi20494af2015-12-17 20:56:42 +053012178 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE,
12179 HDD_SET_TDLS_MODE_SOURCE_USER);
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053012180#endif
12181
c_hpothu5ab05e92014-06-13 17:34:05 +053012182 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12183 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -070012184 {
c_hpothu5ab05e92014-06-13 17:34:05 +053012185 pAdapter = pAdapterNode->pAdapter;
12186 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070012187 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053012188 /* Disable TX on the interface, after this hard_start_xmit() will
12189 * not be called on that interface
12190 */
12191 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
12192 netif_tx_disable(pAdapter->dev);
12193
12194 /* Mark the interface status as "down" for outside world */
12195 netif_carrier_off(pAdapter->dev);
12196
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053012197 /* DeInit the adapter. This ensures that all data packets
12198 * are freed.
12199 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053012200#ifdef FEATURE_WLAN_TDLS
12201 mutex_lock(&pHddCtx->tdls_lock);
12202#endif
c_hpothu002231a2015-02-05 14:58:51 +053012203 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053012204#ifdef FEATURE_WLAN_TDLS
12205 mutex_unlock(&pHddCtx->tdls_lock);
12206#endif
Masti, Narayanraddi26378462016-01-05 18:20:28 +053012207 vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work);
12208
12209 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053012210
c_hpothu5ab05e92014-06-13 17:34:05 +053012211 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012212 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
12213 WLAN_HDD_MONITOR == pAdapter->device_mode)
c_hpothu5ab05e92014-06-13 17:34:05 +053012214 {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012215 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12216 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
12217 wlan_hdd_cfg80211_deregister_frames(pAdapter);
12218
c_hpothu5ab05e92014-06-13 17:34:05 +053012219 hdd_UnregisterWext(pAdapter->dev);
12220 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012221
Jeff Johnson295189b2012-06-20 16:38:30 -070012222 }
c_hpothu5ab05e92014-06-13 17:34:05 +053012223 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12224 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012225 }
mukul sharmabab477d2015-06-11 17:14:55 +053012226
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012227 // Cancel any outstanding scan requests. We are about to close all
12228 // of our adapters, but an adapter structure is what SME passes back
12229 // to our callback function. Hence if there are any outstanding scan
12230 // requests then there is a race condition between when the adapter
12231 // is closed and when the callback is invoked.We try to resolve that
12232 // race condition here by canceling any outstanding scans before we
12233 // close the adapters.
12234 // Note that the scans may be cancelled in an asynchronous manner,
12235 // so ideally there needs to be some kind of synchronization. Rather
12236 // than introduce a new synchronization here, we will utilize the
12237 // fact that we are about to Request Full Power, and since that is
12238 // synchronized, the expectation is that by the time Request Full
12239 // Power has completed all scans will be cancelled.
12240 if (pHddCtx->scan_info.mScanPending)
12241 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +053012242 if(NULL != pAdapter)
12243 {
12244 hddLog(VOS_TRACE_LEVEL_INFO,
12245 FL("abort scan mode: %d sessionId: %d"),
12246 pAdapter->device_mode,
12247 pAdapter->sessionId);
12248 }
12249 hdd_abort_mac_scan(pHddCtx,
12250 pHddCtx->scan_info.sessionId,
12251 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012252 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012253 }
c_hpothu5ab05e92014-06-13 17:34:05 +053012254 else
Jeff Johnson88ba7742013-02-27 14:36:02 -080012255 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012256 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +053012257 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
12258 {
12259 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
12260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12261 "%s: in middle of FTM START", __func__);
12262 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
12263 msecs_to_jiffies(20000));
12264 if(!lrc)
12265 {
12266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12267 "%s: timedout on ftmStartCmpVar fatal error", __func__);
12268 }
12269 }
Jeff Johnson88ba7742013-02-27 14:36:02 -080012270 wlan_hdd_ftm_close(pHddCtx);
12271 goto free_hdd_ctx;
12272 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012273
Jeff Johnson295189b2012-06-20 16:38:30 -070012274 /* DeRegister with platform driver as client for Suspend/Resume */
12275 vosStatus = hddDeregisterPmOps(pHddCtx);
12276 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
12277 {
12278 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
12279 VOS_ASSERT(0);
12280 }
12281
12282 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
12283 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
12284 {
12285 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
12286 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012287
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012288 //Stop the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053012289 if ((pHddCtx->cfg_ini->dynSplitscan) && (VOS_TIMER_STATE_RUNNING ==
12290 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012291 {
12292 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
12293 }
12294
12295 // Destroy the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053012296 if ((pHddCtx->cfg_ini->dynSplitscan) &&
12297 (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
12298 &pHddCtx->tx_rx_trafficTmr))))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012299 {
12300 hddLog(VOS_TRACE_LEVEL_ERROR,
12301 "%s: Cannot deallocate Traffic monitor timer", __func__);
12302 }
12303
Bhargav Shahd0715912015-10-01 18:17:37 +053012304 if (VOS_TIMER_STATE_RUNNING ==
12305 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
12306 vos_timer_stop(&pHddCtx->delack_timer);
12307 }
12308
12309 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
12310 &pHddCtx->delack_timer))) {
12311 hddLog(VOS_TRACE_LEVEL_ERROR,
12312 "%s: Cannot deallocate Bus bandwidth timer", __func__);
12313 }
12314
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012315 if (VOS_TIMER_STATE_RUNNING ==
12316 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) {
12317 vos_timer_stop(&pHddCtx->tdls_source_timer);
12318 }
12319
Abhishek Singh8a3e4dc2017-01-02 10:39:18 +053012320 vos_set_snoc_high_freq_voting(false);
12321
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012322 vos_timer_destroy(&pHddCtx->tdls_source_timer);
12323
Jeff Johnson295189b2012-06-20 16:38:30 -070012324 //Disable IMPS/BMPS as we do not want the device to enter any power
12325 //save mode during shutdown
12326 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
12327 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
12328 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
12329
12330 //Ensure that device is in full power as we will touch H/W during vos_Stop
12331 init_completion(&powerContext.completion);
12332 powerContext.magic = POWER_CONTEXT_MAGIC;
12333
12334 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
12335 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
12336
12337 if (eHAL_STATUS_SUCCESS != halStatus)
12338 {
12339 if (eHAL_STATUS_PMC_PENDING == halStatus)
12340 {
12341 /* request was sent -- wait for the response */
12342 lrc = wait_for_completion_interruptible_timeout(
12343 &powerContext.completion,
12344 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -070012345 if (lrc <= 0)
12346 {
12347 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012348 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -070012349 }
12350 }
12351 else
12352 {
12353 hddLog(VOS_TRACE_LEVEL_ERROR,
12354 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012355 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -070012356 /* continue -- need to clean up as much as possible */
12357 }
12358 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +053012359 if ((eHAL_STATUS_SUCCESS == halStatus) ||
12360 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
12361 {
12362 /* This will issue a dump command which will clean up
12363 BTQM queues and unblock MC thread */
12364 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
12365 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012366
Jeff Johnson72a40512013-12-19 10:14:15 -080012367 /* either we never sent a request, we sent a request and received a
12368 response or we sent a request and timed out. if we never sent a
12369 request or if we sent a request and got a response, we want to
12370 clear the magic out of paranoia. if we timed out there is a
12371 race condition such that the callback function could be
12372 executing at the same time we are. of primary concern is if the
12373 callback function had already verified the "magic" but had not
12374 yet set the completion variable when a timeout occurred. we
12375 serialize these activities by invalidating the magic while
12376 holding a shared spinlock which will cause us to block if the
12377 callback is currently executing */
12378 spin_lock(&hdd_context_lock);
12379 powerContext.magic = 0;
12380 spin_unlock(&hdd_context_lock);
12381
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +053012382 /* If Device is shutdown, no point for SME to wait for responses
12383 from device. Pre Close SME */
12384 if(wcnss_device_is_shutdown())
12385 {
12386 sme_PreClose(pHddCtx->hHal);
12387 }
Yue Ma0d4891e2013-08-06 17:01:45 -070012388 hdd_debugfs_exit(pHddCtx);
12389
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012390#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +053012391 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012392 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
12393#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +053012394 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012395 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
12396
Jeff Johnson295189b2012-06-20 16:38:30 -070012397 // Unregister the Net Device Notifier
12398 unregister_netdevice_notifier(&hdd_netdev_notifier);
12399
Jeff Johnson295189b2012-06-20 16:38:30 -070012400 hdd_stop_all_adapters( pHddCtx );
12401
Jeff Johnson295189b2012-06-20 16:38:30 -070012402#ifdef WLAN_BTAMP_FEATURE
12403 vosStatus = WLANBAP_Stop(pVosContext);
12404 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12405 {
12406 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12407 "%s: Failed to stop BAP",__func__);
12408 }
12409#endif //WLAN_BTAMP_FEATURE
12410
12411 //Stop all the modules
12412 vosStatus = vos_stop( pVosContext );
12413 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12414 {
12415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12416 "%s: Failed to stop VOSS",__func__);
12417 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053012418 if (isSsrPanicOnFailure())
12419 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012420 }
12421
Jeff Johnson295189b2012-06-20 16:38:30 -070012422 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -070012423 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012424
12425 //Close the scheduler before calling vos_close to make sure no thread is
12426 // scheduled after the each module close is called i.e after all the data
12427 // structures are freed.
12428 vosStatus = vos_sched_close( pVosContext );
12429 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
12430 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12431 "%s: Failed to close VOSS Scheduler",__func__);
12432 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12433 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012434#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
12435 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012436 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070012437#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012438 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012439 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012440
Mihir Shete7a24b5f2013-12-21 12:18:31 +053012441#ifdef CONFIG_ENABLE_LINUX_REG
12442 vosStatus = vos_nv_close();
12443 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12444 {
12445 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12446 "%s: Failed to close NV", __func__);
12447 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12448 }
12449#endif
12450
Jeff Johnson295189b2012-06-20 16:38:30 -070012451 //Close VOSS
12452 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
12453 vos_close(pVosContext);
12454
Jeff Johnson295189b2012-06-20 16:38:30 -070012455 //Close Watchdog
12456 if(pHddCtx->cfg_ini->fIsLogpEnabled)
12457 vos_watchdog_close(pVosContext);
12458
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053012459 //Clean up HDD Nlink Service
12460 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053012461
Manjeet Singh47ee8472016-04-11 11:57:18 +053012462 hdd_close_tx_queues(pHddCtx);
c_manjeecfd1efb2015-09-25 19:32:34 +053012463 wlan_free_fwr_mem_dump_buffer();
12464 memdump_deinit();
12465
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012466#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012467 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012468 {
12469 wlan_logging_sock_deactivate_svc();
12470 }
12471#endif
12472
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053012473#ifdef WLAN_KD_READY_NOTIFIER
12474 nl_srv_exit(pHddCtx->ptt_pid);
12475#else
12476 nl_srv_exit();
12477#endif /* WLAN_KD_READY_NOTIFIER */
12478
Abhishek Singh00b71972016-01-07 10:51:04 +053012479#ifdef WLAN_FEATURE_RMC
12480 hdd_close_cesium_nl_sock();
12481#endif /* WLAN_FEATURE_RMC */
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053012482
Jeff Johnson295189b2012-06-20 16:38:30 -070012483 hdd_close_all_adapters( pHddCtx );
12484
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012485 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
Abhishek Singh78c691f2017-11-30 13:48:44 +053012486 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
Kapil Gupta137ef892016-12-13 19:38:00 +053012487 vos_flush_work(&pHddCtx->sap_start_work);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012488
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +053012489free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -070012490 /* free the power on lock from platform driver */
12491 if (free_riva_power_on_lock("wlan"))
12492 {
12493 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
12494 __func__);
12495 }
12496
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053012497 /* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */
12498 wlan_hdd_free_cache_channels(pHddCtx);
12499
c_hpothu78c7b602014-05-17 17:35:49 +053012500 //Free up dynamically allocated members inside HDD Adapter
12501 if (pHddCtx->cfg_ini)
12502 {
12503 kfree(pHddCtx->cfg_ini);
12504 pHddCtx->cfg_ini= NULL;
12505 }
12506
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053012507 hdd_request_manager_deinit();
12508
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053012509 /* FTM/MONITOR mode, WIPHY did not registered
Leo Changf04ddad2013-09-18 13:46:38 -070012510 If un-register here, system crash will happen */
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053012511 if (!(VOS_FTM_MODE == hdd_get_conparam() ||
12512 VOS_MONITOR_MODE == hdd_get_conparam()))
Leo Changf04ddad2013-09-18 13:46:38 -070012513 {
12514 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012515 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -070012516 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012517 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070012518 if (hdd_is_ssr_required())
12519 {
12520 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -070012521 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -070012522 msleep(5000);
12523 }
12524 hdd_set_ssr_required (VOS_FALSE);
12525}
12526
12527
12528/**---------------------------------------------------------------------------
12529
12530 \brief hdd_update_config_from_nv() - Function to update the contents of
12531 the running configuration with parameters taken from NV storage
12532
12533 \param - pHddCtx - Pointer to the HDD global context
12534
12535 \return - VOS_STATUS_SUCCESS if successful
12536
12537 --------------------------------------------------------------------------*/
12538static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
12539{
Jeff Johnson295189b2012-06-20 16:38:30 -070012540 v_BOOL_t itemIsValid = VOS_FALSE;
12541 VOS_STATUS status;
12542 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
12543 v_U8_t macLoop;
12544
12545 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
12546 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
12547 if(status != VOS_STATUS_SUCCESS)
12548 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012549 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070012550 return VOS_STATUS_E_FAILURE;
12551 }
12552
12553 if (itemIsValid == VOS_TRUE)
12554 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012555 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -070012556 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
12557 VOS_MAX_CONCURRENCY_PERSONA);
12558 if(status != VOS_STATUS_SUCCESS)
12559 {
12560 /* Get MAC from NV fail, not update CFG info
12561 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -080012562 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070012563 return VOS_STATUS_E_FAILURE;
12564 }
12565
12566 /* If first MAC is not valid, treat all others are not valid
12567 * Then all MACs will be got from ini file */
12568 if(vos_is_macaddr_zero(&macFromNV[0]))
12569 {
12570 /* MAC address in NV file is not configured yet */
12571 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
12572 return VOS_STATUS_E_INVAL;
12573 }
12574
12575 /* Get MAC address from NV, update CFG info */
12576 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
12577 {
12578 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
12579 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012580 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -070012581 /* This MAC is not valid, skip it
12582 * This MAC will be got from ini file */
12583 }
12584 else
12585 {
12586 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
12587 (v_U8_t *)&macFromNV[macLoop].bytes[0],
12588 VOS_MAC_ADDR_SIZE);
12589 }
12590 }
12591 }
12592 else
12593 {
12594 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
12595 return VOS_STATUS_E_FAILURE;
12596 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012597
Jeff Johnson295189b2012-06-20 16:38:30 -070012598
12599 return VOS_STATUS_SUCCESS;
12600}
12601
12602/**---------------------------------------------------------------------------
12603
12604 \brief hdd_post_voss_start_config() - HDD post voss start config helper
12605
12606 \param - pAdapter - Pointer to the HDD
12607
12608 \return - None
12609
12610 --------------------------------------------------------------------------*/
12611VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
12612{
12613 eHalStatus halStatus;
12614 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012615 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -070012616
Jeff Johnson295189b2012-06-20 16:38:30 -070012617
12618 // Send ready indication to the HDD. This will kick off the MAC
12619 // into a 'running' state and should kick off an initial scan.
12620 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
12621 if ( !HAL_STATUS_SUCCESS( halStatus ) )
12622 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053012623 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -070012624 "code %08d [x%08x]",__func__, halStatus, halStatus );
12625 return VOS_STATUS_E_FAILURE;
12626 }
12627
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012628 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -070012629 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
12630 // And RIVA will crash
12631 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
12632 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012633 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
12634 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
12635
12636
Jeff Johnson295189b2012-06-20 16:38:30 -070012637 return VOS_STATUS_SUCCESS;
12638}
12639
Jeff Johnson295189b2012-06-20 16:38:30 -070012640/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012641void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070012642{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012643
12644 vos_wake_lock_acquire(&wlan_wake_lock, reason);
12645
Jeff Johnson295189b2012-06-20 16:38:30 -070012646}
12647
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012648void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070012649{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012650
12651 vos_wake_lock_release(&wlan_wake_lock, reason);
12652
Jeff Johnson295189b2012-06-20 16:38:30 -070012653}
12654
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012655void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012656{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012657
12658 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
12659 reason);
12660
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012661}
12662
Rajeev Kumar Sirasanagandla4c068d42019-02-22 21:39:36 +053012663/**
12664 * hdd_get_feature_caps_cb() - Callback invoked from WDA
12665 * @cookie: to identify HDD request to firmware
12666 *
12667 * This function is invoked from WDA when feature capabilities response
12668 * is received from firmware.
12669 *
12670 * Return: None
12671 */
12672static void hdd_get_feature_caps_cb(void *cookie)
12673{
12674 struct hdd_request *request;
12675
12676 request = hdd_request_get(cookie);
12677 if (!request) {
12678 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
12679 return;
12680 }
12681
12682 pr_info("%s: Firmware feature capabilities received\n", __func__);
12683
12684 hdd_request_complete(request);
12685 hdd_request_put(request);
12686}
12687
12688/**
12689 * hdd_get_feature_caps() - Get features supported by firmware
12690 * @hdd_ctx: Pointer to HDD context
12691 *
12692 * This function uses request manager framework to get the feature
12693 * capabilities from firmware.
12694 *
12695 * Return: None
12696 */
12697static void hdd_get_feature_caps(hdd_context_t *hdd_ctx)
12698{
12699 VOS_STATUS status;
12700 void *cookie;
12701 int ret;
12702 struct hdd_request *request;
12703 static const struct hdd_request_params params = {
12704 .priv_size = 0,
12705 .timeout_ms = WLAN_WAIT_TIME_FEATURE_CAPS,
12706 };
12707 struct sir_feature_caps_params caps_params = {0};
12708
12709 request = hdd_request_alloc(&params);
12710 if (!request) {
12711 pr_err("%s: Request allocation failure\n", __func__);
12712 return;
12713 }
12714
12715 cookie = hdd_request_cookie(request);
12716 caps_params.user_data = cookie;
12717 caps_params.feature_caps_cb = hdd_get_feature_caps_cb;
12718
12719 status = sme_featureCapsExchange(&caps_params);
12720 if (status != VOS_STATUS_SUCCESS) {
12721 pr_err("%s: Unable to get feature caps\n", __func__);
12722 goto end;
12723 }
12724
12725 /* request was sent -- wait for the response */
12726 ret = hdd_request_wait_for_response(request);
12727 if (ret) {
12728 pr_err("%s: SME timeout while retrieving feature caps\n",
12729 __func__);
12730 goto end;
12731 }
12732
12733end:
12734 hdd_request_put(request);
12735}
12736
Jeff Johnson295189b2012-06-20 16:38:30 -070012737/**---------------------------------------------------------------------------
12738
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012739 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
12740 information between Host and Riva
12741
12742 This function gets reported version of FW
12743 It also finds the version of Riva headers used to compile the host
12744 It compares the above two and prints a warning if they are different
12745 It gets the SW and HW version string
12746 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
12747 indicating the features they support through a bitmap
12748
12749 \param - pHddCtx - Pointer to HDD context
12750
12751 \return - void
12752
12753 --------------------------------------------------------------------------*/
12754
12755void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
12756{
12757
12758 tSirVersionType versionCompiled;
12759 tSirVersionType versionReported;
12760 tSirVersionString versionString;
12761 tANI_U8 fwFeatCapsMsgSupported = 0;
12762 VOS_STATUS vstatus;
12763
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080012764 memset(&versionCompiled, 0, sizeof(versionCompiled));
12765 memset(&versionReported, 0, sizeof(versionReported));
12766
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012767 /* retrieve and display WCNSS version information */
12768 do {
12769
12770 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
12771 &versionCompiled);
12772 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12773 {
12774 hddLog(VOS_TRACE_LEVEL_FATAL,
12775 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012776 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012777 break;
12778 }
12779
12780 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
12781 &versionReported);
12782 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12783 {
12784 hddLog(VOS_TRACE_LEVEL_FATAL,
12785 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012786 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012787 break;
12788 }
12789
12790 if ((versionCompiled.major != versionReported.major) ||
12791 (versionCompiled.minor != versionReported.minor) ||
12792 (versionCompiled.version != versionReported.version) ||
12793 (versionCompiled.revision != versionReported.revision))
12794 {
12795 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
12796 "Host expected %u.%u.%u.%u\n",
12797 WLAN_MODULE_NAME,
12798 (int)versionReported.major,
12799 (int)versionReported.minor,
12800 (int)versionReported.version,
12801 (int)versionReported.revision,
12802 (int)versionCompiled.major,
12803 (int)versionCompiled.minor,
12804 (int)versionCompiled.version,
12805 (int)versionCompiled.revision);
12806 }
12807 else
12808 {
12809 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
12810 WLAN_MODULE_NAME,
12811 (int)versionReported.major,
12812 (int)versionReported.minor,
12813 (int)versionReported.version,
12814 (int)versionReported.revision);
12815 }
12816
12817 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
12818 versionString,
12819 sizeof(versionString));
12820 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12821 {
12822 hddLog(VOS_TRACE_LEVEL_FATAL,
12823 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012824 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012825 break;
12826 }
12827
12828 pr_info("%s: WCNSS software version %s\n",
12829 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +053012830 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012831
12832 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
12833 versionString,
12834 sizeof(versionString));
12835 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12836 {
12837 hddLog(VOS_TRACE_LEVEL_FATAL,
12838 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012839 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012840 break;
12841 }
12842
12843 pr_info("%s: WCNSS hardware version %s\n",
12844 WLAN_MODULE_NAME, versionString);
12845
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012846 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
12847 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012848 send the message only if it the riva is 1.1
12849 minor numbers for different riva branches:
12850 0 -> (1.0)Mainline Build
12851 1 -> (1.1)Mainline Build
12852 2->(1.04) Stability Build
12853 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012854 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012855 ((versionReported.minor>=1) && (versionReported.version>=1)))
12856 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
12857 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012858
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012859 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -080012860 {
12861#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
12862 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
12863 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
12864#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -070012865 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
12866 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
12867 {
12868 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
12869 }
12870
Rajeev Kumar Sirasanagandla4c068d42019-02-22 21:39:36 +053012871 hdd_get_feature_caps(pHddCtx);
Yathish9f22e662012-12-10 14:21:35 -080012872 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012873
12874 } while (0);
12875
12876}
Rajeev Kumar Sirasanagandla4c068d42019-02-22 21:39:36 +053012877
Neelansh Mittaledafed22014-09-04 18:54:39 +053012878void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
12879{
12880 struct sk_buff *skb;
12881 struct nlmsghdr *nlh;
12882 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053012883 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +053012884 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012885
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053012886 if (in_interrupt() || irqs_disabled() || in_atomic())
12887 flags = GFP_ATOMIC;
12888
12889 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +053012890
12891 if(skb == NULL) {
12892 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12893 "%s: alloc_skb failed", __func__);
12894 return;
12895 }
12896
12897 nlh = (struct nlmsghdr *)skb->data;
12898 nlh->nlmsg_pid = 0; /* from kernel */
12899 nlh->nlmsg_flags = 0;
12900 nlh->nlmsg_seq = 0;
12901 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
12902
12903 ani_hdr = NLMSG_DATA(nlh);
12904 ani_hdr->type = type;
12905
12906 switch(type) {
12907 case WLAN_SVC_SAP_RESTART_IND:
12908 ani_hdr->length = 0;
12909 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
12910 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
12911 break;
Bhargav Shahd0715912015-10-01 18:17:37 +053012912 case WLAN_SVC_WLAN_TP_IND:
12913 ani_hdr->length = len;
12914 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
12915 + len));
12916 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12917 memcpy(nl_data, data, len);
12918 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
12919 break;
Bhargav shah23c94942015-10-13 12:48:35 +053012920 case WLAN_MSG_RPS_ENABLE_IND:
12921 ani_hdr->length = len;
12922 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
12923 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12924 memcpy(nl_data, data, len);
12925 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
12926 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012927 default:
12928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12929 "Attempt to send unknown nlink message %d", type);
12930 kfree_skb(skb);
12931 return;
12932 }
12933
12934 nl_srv_bcast(skb);
12935
12936 return;
12937}
12938
Bhargav Shahd0715912015-10-01 18:17:37 +053012939/**
12940 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
12941 * @pHddCtx: Valid Global HDD context pointer
12942 * @rx_packets: Number of RX packet in perticular time
12943 *
12944 * Based on the RX packet this function calculate next value of tcp delack.
12945 * This function compare rx packet value to high and low threshold limit.
12946 *
12947 * Return: void
12948 */
12949void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
12950{
12951 /* average of rx_packets and prev_rx is taken so that
12952 bus width doesnot fluctuate much */
12953 uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
Alok Kumarf3724462018-04-05 15:18:54 +053012954 enum wlan_tp_level next_rx_level = pHddCtx->cur_rx_level;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012955
Bhargav Shahd0715912015-10-01 18:17:37 +053012956 pHddCtx->prev_rx = rx_packets;
12957 if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
Alok Kumarf3724462018-04-05 15:18:54 +053012958 next_rx_level = WLAN_SVC_TP_HIGH;
Bhargav Shahd0715912015-10-01 18:17:37 +053012959 else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
Alok Kumarf3724462018-04-05 15:18:54 +053012960 next_rx_level = WLAN_SVC_TP_LOW;
Bhargav Shahd0715912015-10-01 18:17:37 +053012961
12962 hdd_set_delack_value(pHddCtx, next_rx_level);
12963}
12964
12965#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))
12966
12967/**
12968 * hdd_tcp_delack_compute_function() - get link status
12969 * @priv: Valid Global HDD context pointer
12970 *
12971 * This function find number of RX packet during timer life span.
12972 * It request tcp delack with number of RX packet and re-configure delack timer
12973 * for tcpDelAckComputeInterval timer interval.
12974 *
12975 * Return: void
12976 */
12977void hdd_tcp_delack_compute_function(void *priv)
12978{
12979 hdd_context_t *pHddCtx = (hdd_context_t *)priv;
12980 hdd_adapter_t *pAdapter = NULL;
12981 v_U32_t rx_packets = 0;
12982 hdd_adapter_list_node_t *pAdapterNode = NULL;
12983 VOS_STATUS status = 0;
12984
12985 for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12986 NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
12987 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
12988 if ((pAdapter = pAdapterNode->pAdapter) == NULL)
12989 continue;
12990
12991 rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
12992 pAdapter->prev_rx_packets);
12993 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
12994 }
12995
12996 hdd_request_tcp_delack(pHddCtx, rx_packets);
12997
12998 vos_timer_start(&pHddCtx->delack_timer,
12999 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
13000}
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070013001
13002/**---------------------------------------------------------------------------
13003
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013004 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
13005
13006 \param - pHddCtx - Pointer to the hdd context
13007
13008 \return - true if hardware supports 5GHz
13009
13010 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +053013011boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013012{
13013 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
13014 * then hardware support 5Ghz.
13015 */
13016 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
13017 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013018 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013019 return true;
13020 }
13021 else
13022 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013023 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013024 __func__);
13025 return false;
13026 }
13027}
13028
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013029/**---------------------------------------------------------------------------
13030
13031 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
13032 generate function
13033
13034 This is generate the random mac address for WLAN interface
13035
13036 \param - pHddCtx - Pointer to HDD context
13037 idx - Start interface index to get auto
13038 generated mac addr.
13039 mac_addr - Mac address
13040
13041 \return - 0 for success, < 0 for failure
13042
13043 --------------------------------------------------------------------------*/
13044
13045static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
13046 int idx, v_MACADDR_t mac_addr)
13047{
13048 int i;
13049 unsigned int serialno;
13050 serialno = wcnss_get_serial_number();
13051
13052 if (0 != serialno)
13053 {
13054 /* MAC address has 3 bytes of OUI so we have a maximum of 3
13055 bytes of the serial number that can be used to generate
13056 the other 3 bytes of the MAC address. Mask off all but
13057 the lower 3 bytes (this will also make sure we don't
13058 overflow in the next step) */
13059 serialno &= 0x00FFFFFF;
13060
13061 /* we need a unique address for each session */
13062 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
13063
13064 /* autogen other Mac addresses */
13065 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
13066 {
13067 /* start with the entire default address */
13068 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
13069 /* then replace the lower 3 bytes */
13070 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
13071 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
13072 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
13073
Nachiket Kukadede2e24f2017-09-25 16:24:27 +053013074 if (0 == memcmp(&pHddCtx->cfg_ini->intfMacAddr[i].bytes[0],
13075 &mac_addr.bytes[0], VOS_MAC_ADDR_SIZE))
13076 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] +=
13077 VOS_MAX_CONCURRENCY_PERSONA;
13078
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013079 serialno++;
13080 hddLog(VOS_TRACE_LEVEL_ERROR,
13081 "%s: Derived Mac Addr: "
13082 MAC_ADDRESS_STR, __func__,
13083 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
13084 }
13085
13086 }
13087 else
13088 {
13089 hddLog(LOGE, FL("Failed to Get Serial NO"));
13090 return -1;
13091 }
13092 return 0;
13093}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013094
Katya Nigame7b69a82015-04-28 15:24:06 +053013095int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
13096{
13097 VOS_STATUS status;
13098 v_CONTEXT_t pVosContext= NULL;
13099 hdd_adapter_t *pAdapter= NULL;
13100
13101 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13102
13103 if (NULL == pVosContext)
13104 {
13105 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13106 "%s: Trying to open VOSS without a PreOpen", __func__);
13107 VOS_ASSERT(0);
13108 return VOS_STATUS_E_FAILURE;
13109 }
13110
13111 status = vos_nv_open();
13112 if (!VOS_IS_STATUS_SUCCESS(status))
13113 {
13114 /* NV module cannot be initialized */
13115 hddLog( VOS_TRACE_LEVEL_FATAL,
13116 "%s: vos_nv_open failed", __func__);
13117 return VOS_STATUS_E_FAILURE;
13118 }
13119
13120 status = vos_init_wiphy_from_nv_bin();
13121 if (!VOS_IS_STATUS_SUCCESS(status))
13122 {
13123 /* NV module cannot be initialized */
13124 hddLog( VOS_TRACE_LEVEL_FATAL,
13125 "%s: vos_init_wiphy failed", __func__);
13126 goto err_vos_nv_close;
13127 }
13128
13129 status = vos_open( &pVosContext, pHddCtx->parent_dev);
13130 if ( !VOS_IS_STATUS_SUCCESS( status ))
13131 {
13132 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
13133 goto err_vos_nv_close;
13134 }
13135
13136 status = vos_mon_start( pVosContext );
13137 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13138 {
13139 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
13140 goto err_vosclose;
13141 }
13142
13143 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
Rajeev Kumar Sirasanagandla4c068d42019-02-22 21:39:36 +053013144 sme_featureCapsExchange(NULL);
Katya Nigame7b69a82015-04-28 15:24:06 +053013145 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
13146
13147 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
13148 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13149 if( pAdapter == NULL )
13150 {
13151 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
13152 goto err_close_adapter;
13153 }
13154
13155 //Initialize the nlink service
13156 if(nl_srv_init() != 0)
13157 {
13158 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
13159 goto err_close_adapter;
13160 }
13161 return VOS_STATUS_SUCCESS;
13162
13163err_close_adapter:
13164 hdd_close_all_adapters( pHddCtx );
13165 vos_mon_stop( pVosContext );
13166err_vosclose:
13167 status = vos_sched_close( pVosContext );
13168 if (!VOS_IS_STATUS_SUCCESS(status)) {
13169 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
13170 "%s: Failed to close VOSS Scheduler", __func__);
13171 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
13172 }
13173 vos_close(pVosContext );
13174
13175err_vos_nv_close:
13176 vos_nv_close();
13177
13178return status;
13179}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013180/**---------------------------------------------------------------------------
13181
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013182 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
13183 completed to flush out the scan results
13184
13185 11d scan is done during driver load and is a passive scan on all
13186 channels supported by the device, 11d scans may find some APs on
13187 frequencies which are forbidden to be used in the regulatory domain
13188 the device is operating in. If these APs are notified to the supplicant
13189 it may try to connect to these APs, thus flush out all the scan results
13190 which are present in SME after 11d scan is done.
13191
13192 \return - eHalStatus
13193
13194 --------------------------------------------------------------------------*/
13195static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
13196 tANI_U32 scanId, eCsrScanStatus status)
13197{
13198 ENTER();
13199
13200 sme_ScanFlushResult(halHandle, 0);
13201
13202 EXIT();
13203
13204 return eHAL_STATUS_SUCCESS;
13205}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013206/**---------------------------------------------------------------------------
13207
13208 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
13209 logging is completed successfully.
13210
13211 \return - None
13212
13213 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +053013214void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013215{
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013216 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013217
13218 if (NULL == pHddCtx)
13219 {
13220 hddLog(VOS_TRACE_LEVEL_ERROR,
13221 "%s: HDD context is NULL",__func__);
13222 return;
13223 }
13224
c_manjeecfd1efb2015-09-25 19:32:34 +053013225 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +053013226 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013227 {
13228 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
13229 pHddCtx->mgmt_frame_logging = TRUE;
13230 }
13231 else
13232 {
13233 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
13234 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +053013235 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013236 }
13237
c_manjeecfd1efb2015-09-25 19:32:34 +053013238 /*Check feature supported by FW*/
13239 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
13240 {
13241 //Store fwr mem dump size given by firmware.
13242 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
13243 }
13244 else
13245 {
13246 wlan_store_fwr_mem_dump_size(0);
13247 }
13248
13249
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013250}
13251/**---------------------------------------------------------------------------
13252
13253 \brief hdd_init_frame_logging - function to initialize frame logging.
13254 Currently only Mgmt Frames are logged in both TX
13255 and Rx direction and are sent to userspace
13256 application using logger thread when queried.
13257
13258 \return - None
13259
13260 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013261void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013262{
13263 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013264 tSirFWLoggingInitParam wlanFWLoggingInitParam = {0};
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013265
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013266 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
13267 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013268 {
13269 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
13270 return;
13271 }
13272
c_manjeecfd1efb2015-09-25 19:32:34 +053013273 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013274 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
13275 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +053013276 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
13277 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013278
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013279 if (pHddCtx->cfg_ini->enableFWLogging ||
13280 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013281 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013282 wlanFWLoggingInitParam.enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013283 }
13284
Sushant Kaushik46804902015-07-08 14:46:03 +053013285 if (pHddCtx->cfg_ini->enableMgmtLogging)
13286 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013287 wlanFWLoggingInitParam.enableFlag |= WLAN_FRAME_LOG_EN;
Sushant Kaushik46804902015-07-08 14:46:03 +053013288 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013289 if (pHddCtx->cfg_ini->enableBMUHWtracing)
13290 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013291 wlanFWLoggingInitParam.enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013292 }
c_manjeecfd1efb2015-09-25 19:32:34 +053013293 if(pHddCtx->cfg_ini->enableFwrMemDump &&
13294 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
13295 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013296 wlanFWLoggingInitParam.enableFlag |= WLAN_FW_MEM_DUMP_EN;
c_manjeecfd1efb2015-09-25 19:32:34 +053013297 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013298 if( wlanFWLoggingInitParam.enableFlag == 0 )
c_manjeecfd1efb2015-09-25 19:32:34 +053013299 {
13300 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
13301 return;
13302 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013303 wlanFWLoggingInitParam.frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
13304 wlanFWLoggingInitParam.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
13305 wlanFWLoggingInitParam.bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
13306 wlanFWLoggingInitParam.continuousFrameLogging =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013307 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013308
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013309 wlanFWLoggingInitParam.enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013310
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013311 wlanFWLoggingInitParam.minLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013312 pHddCtx->cfg_ini->minLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013313 wlanFWLoggingInitParam.maxLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013314 pHddCtx->cfg_ini->maxLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013315 wlanFWLoggingInitParam.fwlogInitCallback = hdd_init_frame_logging_done;
13316 wlanFWLoggingInitParam.fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013317
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013318 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, &wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013319
13320 if (eHAL_STATUS_SUCCESS != halStatus)
13321 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013322 hddLog(LOGE, FL("sme_InitMgmtFrameLogging failed, returned %d"),
13323 halStatus);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013324 }
13325
13326 return;
13327}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013328
Bhargav shah23c94942015-10-13 12:48:35 +053013329static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
13330{
13331 hdd_adapter_t *adapter;
13332 hdd_adapter_list_node_t *adapter_node, *next;
13333 VOS_STATUS status = VOS_STATUS_SUCCESS;
13334 struct wlan_rps_data rps_data;
13335 int count;
13336
13337 if(!hdd_ctxt->cfg_ini->rps_mask)
13338 {
13339 return;
13340 }
13341
13342 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
13343 {
13344 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
13345 }
13346
13347 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
13348
13349 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
13350 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
13351 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
13352
13353 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
13354
13355 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
13356 {
13357 adapter = adapter_node->pAdapter;
13358 if (NULL != adapter) {
13359 strlcpy(rps_data.ifname, adapter->dev->name,
13360 sizeof(rps_data.ifname));
13361 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
13362 (void *)&rps_data,sizeof(rps_data));
13363 }
13364 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
13365 adapter_node = next;
13366 }
13367}
13368
Masti, Narayanraddi26378462016-01-05 18:20:28 +053013369void wlan_hdd_schedule_defer_scan(struct work_struct *work)
13370{
13371 scan_context_t *scan_ctx =
13372 container_of(work, scan_context_t, scan_work.work);
13373
13374 if (NULL == scan_ctx)
13375 {
13376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13377 FL("scan_ctx is NULL"));
13378 return;
13379 }
13380
13381 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
13382 return;
13383
13384 scan_ctx->attempt++;
13385
13386 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
13387#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13388 scan_ctx->dev,
13389#endif
13390 scan_ctx->scan_request);
13391}
13392
13393int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx,
13394 struct wiphy *wiphy,
13395#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13396 struct net_device *dev,
13397#endif
13398 struct cfg80211_scan_request *request)
13399{
13400 scan_context_t *scan_ctx;
13401
13402 ENTER();
13403 if (0 != (wlan_hdd_validate_context(pHddCtx)))
13404 {
13405 return -1;
13406 }
13407
13408 scan_ctx = &pHddCtx->scan_ctxt;
13409
13410 scan_ctx->wiphy = wiphy;
13411#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13412 scan_ctx->dev = dev;
13413#endif
13414
13415 scan_ctx->scan_request = request;
13416
13417 EXIT();
13418 return 0;
13419}
13420
13421void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
13422 struct wiphy *wiphy,
13423#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13424 struct net_device *dev,
13425#endif
13426 struct cfg80211_scan_request *request,
13427 unsigned long delay)
13428{
13429 if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic)
13430 {
13431#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13432 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request);
13433#else
13434 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request);
13435#endif
13436 pHddCtx->scan_ctxt.attempt = 0;
13437 pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC;
13438 }
13439 schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay);
13440}
13441
13442void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx)
13443{
13444 scan_ctx->magic = 0;
13445 scan_ctx->attempt = 0;
13446 scan_ctx->reject = 0;
13447 scan_ctx->scan_request = NULL;
13448
13449 return;
13450}
13451
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013452/**---------------------------------------------------------------------------
13453
Jeff Johnson295189b2012-06-20 16:38:30 -070013454 \brief hdd_wlan_startup() - HDD init function
13455
13456 This is the driver startup code executed once a WLAN device has been detected
13457
13458 \param - dev - Pointer to the underlying device
13459
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013460 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -070013461
13462 --------------------------------------------------------------------------*/
13463
13464int hdd_wlan_startup(struct device *dev )
13465{
13466 VOS_STATUS status;
13467 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070013468 hdd_adapter_t *pP2pAdapter = NULL;
Arunk Khandavalli95608be2019-01-22 13:12:54 +053013469 hdd_adapter_t *softapAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013470 hdd_context_t *pHddCtx = NULL;
13471 v_CONTEXT_t pVosContext= NULL;
13472#ifdef WLAN_BTAMP_FEATURE
13473 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
13474 WLANBAP_ConfigType btAmpConfig;
13475 hdd_config_t *pConfig;
13476#endif
13477 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013478 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013479 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -070013480
13481 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013482 /*
13483 * cfg80211: wiphy allocation
13484 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013485 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070013486
13487 if(wiphy == NULL)
13488 {
13489 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013490 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013491 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013492 pHddCtx = wiphy_priv(wiphy);
13493
Jeff Johnson295189b2012-06-20 16:38:30 -070013494 //Initialize the adapter context to zeros.
13495 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
13496
Jeff Johnson295189b2012-06-20 16:38:30 -070013497 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013498 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +053013499 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070013500
13501 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
13502
Siddharth Bhalcd92b782015-06-29 12:25:40 +053013503 /* register for riva power on lock to platform driver
13504 * Locking power early to ensure FW doesn't reset by kernel while
13505 * host driver is busy initializing itself */
13506 if (req_riva_power_on_lock("wlan"))
13507 {
13508 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
13509 __func__);
13510 goto err_free_hdd_context;
13511 }
13512
Jeff Johnson295189b2012-06-20 16:38:30 -070013513 /*Get vos context here bcoz vos_open requires it*/
13514 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13515
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -080013516 if(pVosContext == NULL)
13517 {
13518 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
13519 goto err_free_hdd_context;
13520 }
13521
Jeff Johnson295189b2012-06-20 16:38:30 -070013522 //Save the Global VOSS context in adapter context for future.
13523 pHddCtx->pvosContext = pVosContext;
13524
13525 //Save the adapter context in global context for future.
13526 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
13527
Jeff Johnson295189b2012-06-20 16:38:30 -070013528 pHddCtx->parent_dev = dev;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053013529 pHddCtx->last_scan_reject_session_id = 0xFF;
13530 pHddCtx->last_scan_reject_reason = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013531 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053013532 pHddCtx->scan_reject_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013533
13534 init_completion(&pHddCtx->full_pwr_comp_var);
13535 init_completion(&pHddCtx->standby_comp_var);
13536 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013537 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013538 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +053013539 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053013540 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053013541 init_completion(&pHddCtx->mc_sus_event_var);
13542 init_completion(&pHddCtx->tx_sus_event_var);
13543 init_completion(&pHddCtx->rx_sus_event_var);
13544
Amar Singhala49cbc52013-10-08 18:37:44 -070013545
mukul sharma4bd8d2e2015-08-13 20:33:25 +053013546 hdd_init_ll_stats_ctx(pHddCtx);
Anurag Chouhan6ee81542017-02-09 18:09:27 +053013547 hdd_init_nud_stats_ctx(pHddCtx);
mukul sharma4bd8d2e2015-08-13 20:33:25 +053013548
Amar Singhala49cbc52013-10-08 18:37:44 -070013549#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -070013550 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -070013551#else
13552 init_completion(&pHddCtx->driver_crda_req);
13553#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013554
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +053013555#ifdef WLAN_FEATURE_EXTSCAN
13556 init_completion(&pHddCtx->ext_scan_context.response_event);
13557#endif /* WLAN_FEATURE_EXTSCAN */
13558
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013559 spin_lock_init(&pHddCtx->schedScan_lock);
Kapil Gupta137ef892016-12-13 19:38:00 +053013560 vos_spin_lock_init(&pHddCtx->sap_update_info_lock);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013561
Jeff Johnson295189b2012-06-20 16:38:30 -070013562 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
13563
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053013564 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
13565 hdd_processSpoofMacAddrRequest);
Kapil Gupta137ef892016-12-13 19:38:00 +053013566 vos_init_work(&pHddCtx->sap_start_work, hdd_sap_restart_handle);
Abhishek Singh78c691f2017-11-30 13:48:44 +053013567 vos_init_delayed_work(&pHddCtx->ecsa_chan_change_work,
13568 hdd_force_scc_with_ecsa_handle);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053013569
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013570#ifdef FEATURE_WLAN_TDLS
13571 /* tdls_lock is initialized before an hdd_open_adapter ( which is
13572 * invoked by other instances also) to protect the concurrent
13573 * access for the Adapters by TDLS module.
13574 */
13575 mutex_init(&pHddCtx->tdls_lock);
13576#endif
Siddharth Bhal76972212014-10-15 16:22:51 +053013577 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +053013578 mutex_init(&pHddCtx->wmmLock);
13579
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +053013580 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +053013581 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013582
Agarwal Ashish1f422872014-07-22 00:11:55 +053013583 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013584 // Load all config first as TL config is needed during vos_open
13585 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
13586 if(pHddCtx->cfg_ini == NULL)
13587 {
13588 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
13589 goto err_free_hdd_context;
13590 }
13591
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053013592 hdd_request_manager_init();
13593
Jeff Johnson295189b2012-06-20 16:38:30 -070013594 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
13595
13596 // Read and parse the qcom_cfg.ini file
13597 status = hdd_parse_config_ini( pHddCtx );
13598 if ( VOS_STATUS_SUCCESS != status )
13599 {
13600 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
13601 __func__, WLAN_INI_FILE);
13602 goto err_config;
13603 }
Arif Hussaind5218912013-12-05 01:10:55 -080013604#ifdef MEMORY_DEBUG
13605 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
13606 vos_mem_init();
13607
13608 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
13609 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
13610#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013611
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +053013612 /* INI has been read, initialise the configuredMcastBcastFilter with
13613 * INI value as this will serve as the default value
13614 */
13615 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
13616 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
13617 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013618
13619 if (false == hdd_is_5g_supported(pHddCtx))
13620 {
13621 //5Ghz is not supported.
13622 if (1 != pHddCtx->cfg_ini->nBandCapability)
13623 {
13624 hddLog(VOS_TRACE_LEVEL_INFO,
13625 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
13626 pHddCtx->cfg_ini->nBandCapability = 1;
13627 }
13628 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013629
13630 /* If SNR Monitoring is enabled, FW has to parse all beacons
13631 * for calcaluting and storing the average SNR, so set Nth beacon
13632 * filter to 1 to enable FW to parse all the beaocons
13633 */
13634 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
13635 {
13636 /* The log level is deliberately set to WARN as overriding
13637 * nthBeaconFilter to 1 will increase power cosumption and this
13638 * might just prove helpful to detect the power issue.
13639 */
13640 hddLog(VOS_TRACE_LEVEL_WARN,
13641 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
13642 pHddCtx->cfg_ini->nthBeaconFilter = 1;
13643 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013644 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013645 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -070013646 */
Manjeet Singh61016fa2016-12-02 11:10:19 +053013647 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
Jeff Johnson295189b2012-06-20 16:38:30 -070013648 {
Manjeet Singh61016fa2016-12-02 11:10:19 +053013649 hddLog(VOS_TRACE_LEVEL_FATAL,
13650 "%s: wlan_hdd_cfg80211_init return failure", __func__);
13651 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070013652 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013653
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013654 // Update VOS trace levels based upon the cfg.ini
13655 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
13656 pHddCtx->cfg_ini->vosTraceEnableBAP);
13657 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
13658 pHddCtx->cfg_ini->vosTraceEnableTL);
13659 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
13660 pHddCtx->cfg_ini->vosTraceEnableWDI);
13661 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
13662 pHddCtx->cfg_ini->vosTraceEnableHDD);
13663 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
13664 pHddCtx->cfg_ini->vosTraceEnableSME);
13665 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
13666 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +053013667 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
13668 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013669 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
13670 pHddCtx->cfg_ini->vosTraceEnableWDA);
13671 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
13672 pHddCtx->cfg_ini->vosTraceEnableSYS);
13673 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
13674 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013675 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
13676 pHddCtx->cfg_ini->vosTraceEnableSAP);
13677 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
13678 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013679
Jeff Johnson295189b2012-06-20 16:38:30 -070013680 // Update WDI trace levels based upon the cfg.ini
13681 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
13682 pHddCtx->cfg_ini->wdiTraceEnableDAL);
13683 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
13684 pHddCtx->cfg_ini->wdiTraceEnableCTL);
13685 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
13686 pHddCtx->cfg_ini->wdiTraceEnableDAT);
13687 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
13688 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -070013689
Jeff Johnson88ba7742013-02-27 14:36:02 -080013690 if (VOS_FTM_MODE == hdd_get_conparam())
13691 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013692 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
13693 {
13694 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
13695 goto err_free_hdd_context;
13696 }
13697 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +053013698 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +053013699 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -070013700 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -080013701 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013702
Katya Nigame7b69a82015-04-28 15:24:06 +053013703 if( VOS_MONITOR_MODE == hdd_get_conparam())
13704 {
13705 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
13706 {
13707 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
13708 goto err_free_hdd_context;
13709 }
13710 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
13711 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
13712 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
13713 return VOS_STATUS_SUCCESS;
13714 }
13715
Jeff Johnson88ba7742013-02-27 14:36:02 -080013716 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -070013717 if(pHddCtx->cfg_ini->fIsLogpEnabled)
13718 {
13719 status = vos_watchdog_open(pVosContext,
13720 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
13721
13722 if(!VOS_IS_STATUS_SUCCESS( status ))
13723 {
13724 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Ashish Kumar Dhanotiya532bdef2017-05-09 17:31:59 +053013725 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070013726 }
13727 }
13728
13729 pHddCtx->isLogpInProgress = FALSE;
13730 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
13731
Amar Singhala49cbc52013-10-08 18:37:44 -070013732#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070013733 /* initialize the NV module. This is required so that
13734 we can initialize the channel information in wiphy
13735 from the NV.bin data. The channel information in
13736 wiphy needs to be initialized before wiphy registration */
13737
13738 status = vos_nv_open();
13739 if (!VOS_IS_STATUS_SUCCESS(status))
13740 {
13741 /* NV module cannot be initialized */
13742 hddLog( VOS_TRACE_LEVEL_FATAL,
13743 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +053013744 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -070013745 }
13746
13747 status = vos_init_wiphy_from_nv_bin();
13748 if (!VOS_IS_STATUS_SUCCESS(status))
13749 {
13750 /* NV module cannot be initialized */
13751 hddLog( VOS_TRACE_LEVEL_FATAL,
13752 "%s: vos_init_wiphy failed", __func__);
13753 goto err_vos_nv_close;
13754 }
13755
Amar Singhala49cbc52013-10-08 18:37:44 -070013756#endif
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013757 //Initialize the nlink service
13758 if(nl_srv_init() != 0)
13759 {
13760 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
13761 goto err_vos_nv_close;
13762 }
13763
13764#ifdef WLAN_KD_READY_NOTIFIER
13765 pHddCtx->kd_nl_init = 1;
13766#endif /* WLAN_KD_READY_NOTIFIER */
13767
Girish Gowlibf0e1ab2015-01-19 16:05:16 +053013768 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053013769 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070013770 if ( !VOS_IS_STATUS_SUCCESS( status ))
13771 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013772 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013773 goto err_nl_srv;
Jeff Johnson295189b2012-06-20 16:38:30 -070013774 }
13775
Jeff Johnson295189b2012-06-20 16:38:30 -070013776 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
13777
13778 if ( NULL == pHddCtx->hHal )
13779 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013780 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013781 goto err_vosclose;
13782 }
13783
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013784 status = vos_preStart( pHddCtx->pvosContext );
13785 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13786 {
13787 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013788 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013789 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013790
Arif Hussaineaf68602013-12-30 23:10:44 -080013791 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
13792 {
13793 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
13794 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
13795 __func__, enable_dfs_chan_scan);
13796 }
13797 if (0 == enable_11d || 1 == enable_11d)
13798 {
13799 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
13800 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
13801 __func__, enable_11d);
13802 }
13803
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013804 /* Note that the vos_preStart() sequence triggers the cfg download.
13805 The cfg download must occur before we update the SME config
13806 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -070013807 status = hdd_set_sme_config( pHddCtx );
13808
13809 if ( VOS_STATUS_SUCCESS != status )
13810 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013811 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013812 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013813 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013814
Jeff Johnson295189b2012-06-20 16:38:30 -070013815 /* In the integrated architecture we update the configuration from
13816 the INI file and from NV before vOSS has been started so that
13817 the final contents are available to send down to the cCPU */
13818
13819 // Apply the cfg.ini to cfg.dat
13820 if (FALSE == hdd_update_config_dat(pHddCtx))
13821 {
13822 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013823 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013824 }
13825
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013826 // Get mac addr from platform driver
13827 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
13828
13829 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013830 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013831 /* Store the mac addr for first interface */
13832 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
13833
13834 hddLog(VOS_TRACE_LEVEL_ERROR,
13835 "%s: WLAN Mac Addr: "
13836 MAC_ADDRESS_STR, __func__,
13837 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
13838
13839 /* Here, passing Arg2 as 1 because we do not want to change the
13840 last 3 bytes (means non OUI bytes) of first interface mac
13841 addr.
13842 */
13843 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
13844 {
13845 hddLog(VOS_TRACE_LEVEL_ERROR,
13846 "%s: Failed to generate wlan interface mac addr "
13847 "using MAC from ini file ", __func__);
13848 }
13849 }
13850 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
13851 {
13852 // Apply the NV to cfg.dat
13853 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070013854#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
13855 /* There was not a valid set of MAC Addresses in NV. See if the
13856 default addresses were modified by the cfg.ini settings. If so,
13857 we'll use them, but if not, we'll autogenerate a set of MAC
13858 addresses based upon the device serial number */
13859
13860 static const v_MACADDR_t default_address =
13861 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070013862
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013863 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
13864 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013865 {
13866 /* cfg.ini has the default address, invoke autogen logic */
13867
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013868 /* Here, passing Arg2 as 0 because we want to change the
13869 last 3 bytes (means non OUI bytes) of all the interfaces
13870 mac addr.
13871 */
13872 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
13873 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070013874 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013875 hddLog(VOS_TRACE_LEVEL_ERROR,
13876 "%s: Failed to generate wlan interface mac addr "
13877 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
13878 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070013879 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013880 }
13881 else
13882#endif //WLAN_AUTOGEN_MACADDR_FEATURE
13883 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013884 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013885 "%s: Invalid MAC address in NV, using MAC from ini file "
13886 MAC_ADDRESS_STR, __func__,
13887 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
13888 }
13889 }
13890 {
13891 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013892
13893 /* Set the MAC Address Currently this is used by HAL to
13894 * add self sta. Remove this once self sta is added as
13895 * part of session open.
13896 */
Jeff Johnson295189b2012-06-20 16:38:30 -070013897 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
13898 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
13899 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013900
Jeff Johnson295189b2012-06-20 16:38:30 -070013901 if (!HAL_STATUS_SUCCESS( halStatus ))
13902 {
13903 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
13904 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013905 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013906 }
13907 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013908
13909 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
13910 Note: Firmware image will be read and downloaded inside vos_start API */
13911 status = vos_start( pHddCtx->pvosContext );
13912 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13913 {
13914 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053013915 if (isSsrPanicOnFailure())
13916 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013917 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013918 }
13919
Leo Chang6cec3e22014-01-21 15:33:49 -080013920#ifdef FEATURE_WLAN_CH_AVOID
13921 /* Plug in avoid channel notification callback
13922 * This should happen before ADD_SELF_STA
13923 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053013924
13925 /* check the Channel Avoidance is enabled */
13926 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
13927 {
13928 sme_AddChAvoidCallback(pHddCtx->hHal,
13929 hdd_hostapd_ch_avoid_cb);
13930 }
Leo Chang6cec3e22014-01-21 15:33:49 -080013931#endif /* FEATURE_WLAN_CH_AVOID */
13932
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070013933 /* Exchange capability info between Host and FW and also get versioning info from FW */
13934 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070013935
Agarwal Ashishad9281b2014-06-10 14:57:30 +053013936#ifdef CONFIG_ENABLE_LINUX_REG
13937 status = wlan_hdd_init_channels(pHddCtx);
13938 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13939 {
13940 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
13941 __func__);
13942 goto err_vosstop;
13943 }
13944#endif
13945
Jeff Johnson295189b2012-06-20 16:38:30 -070013946 status = hdd_post_voss_start_config( pHddCtx );
13947 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13948 {
13949 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
13950 __func__);
13951 goto err_vosstop;
13952 }
Amar Singhala49cbc52013-10-08 18:37:44 -070013953
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +053013954 wlan_hdd_cfg80211_scan_randomization_init(wiphy);
13955
Amar Singhala49cbc52013-10-08 18:37:44 -070013956#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013957 wlan_hdd_cfg80211_update_reg_info( wiphy );
13958
13959 /* registration of wiphy dev with cfg80211 */
13960 if (0 > wlan_hdd_cfg80211_register(wiphy))
13961 {
13962 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
13963 goto err_vosstop;
13964 }
Amar Singhala49cbc52013-10-08 18:37:44 -070013965#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013966
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013967#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013968 /* registration of wiphy dev with cfg80211 */
13969 if (0 > wlan_hdd_cfg80211_register(wiphy))
13970 {
13971 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
13972 goto err_vosstop;
13973 }
13974
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013975 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013976 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13977 {
13978 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
13979 __func__);
13980 goto err_unregister_wiphy;
13981 }
13982#endif
13983
c_hpothu4a298be2014-12-22 21:12:51 +053013984 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
13985
Rajeev Kumar Sirasanagandla4c068d42019-02-22 21:39:36 +053013986#ifdef SAP_AUTH_OFFLOAD
13987 if (!sme_IsFeatureSupportedByFW(SAP_OFFLOADS))
13988 {
13989 hddLog(VOS_TRACE_LEVEL_INFO, FL(" SAP AUTH OFFLOAD not supp by FW"));
13990 pHddCtx->cfg_ini->enable_sap_auth_offload = 0;
13991 }
13992#endif
13993
Jeff Johnson295189b2012-06-20 16:38:30 -070013994 if (VOS_STA_SAP_MODE == hdd_get_conparam())
13995 {
13996 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
13997 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13998 }
13999 else
14000 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014001 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
14002 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
14003 if (pAdapter != NULL)
14004 {
Katya Nigama7d81d72014-11-12 12:44:34 +053014005 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070014006 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053014007 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
14008 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
14009 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070014010
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053014011 /* Generate the P2P Device Address. This consists of the device's
14012 * primary MAC address with the locally administered bit set.
14013 */
14014 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070014015 }
14016 else
14017 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053014018 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
14019 if (p2p_dev_addr != NULL)
14020 {
14021 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
14022 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
14023 }
14024 else
14025 {
14026 hddLog(VOS_TRACE_LEVEL_FATAL,
14027 "%s: Failed to allocate mac_address for p2p_device",
14028 __func__);
14029 goto err_close_adapter;
14030 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014031 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014032
14033 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
14034 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
14035 if ( NULL == pP2pAdapter )
14036 {
14037 hddLog(VOS_TRACE_LEVEL_FATAL,
14038 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014039 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070014040 goto err_close_adapter;
14041 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014042 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014043 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014044
14045 if( pAdapter == NULL )
14046 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014047 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
14048 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070014049 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014050
Ashish Kumar Dhanotiya3ac85a22019-02-12 19:10:14 +053014051 if ((strlen(pHddCtx->cfg_ini->enabledefaultSAP) != 0) &&
14052 (strcmp(pHddCtx->cfg_ini->enabledefaultSAP, "") != 0)) {
Arunk Khandavalli95608be2019-01-22 13:12:54 +053014053 softapAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP,
14054 pHddCtx->cfg_ini->enabledefaultSAP,
14055 wlan_hdd_get_intf_addr(pHddCtx), FALSE);
14056 if (!softapAdapter) {
14057 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
14058 goto err_close_adapter;
14059 }
14060 }
14061
Arif Hussain66559122013-11-21 10:11:40 -080014062 if (country_code)
14063 {
14064 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080014065 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080014066 hdd_checkandupdate_dfssetting(pAdapter, country_code);
14067#ifndef CONFIG_ENABLE_LINUX_REG
14068 hdd_checkandupdate_phymode(pAdapter, country_code);
14069#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080014070 ret = sme_ChangeCountryCode(pHddCtx->hHal,
14071 (void *)(tSmeChangeCountryCallback)
14072 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080014073 country_code,
14074 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053014075 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080014076 if (eHAL_STATUS_SUCCESS == ret)
14077 {
Arif Hussaincb607082013-12-20 11:57:42 -080014078 ret = wait_for_completion_interruptible_timeout(
14079 &pAdapter->change_country_code,
14080 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
14081
14082 if (0 >= ret)
14083 {
14084 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14085 "%s: SME while setting country code timed out", __func__);
14086 }
Arif Hussain66559122013-11-21 10:11:40 -080014087 }
14088 else
14089 {
Arif Hussaincb607082013-12-20 11:57:42 -080014090 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14091 "%s: SME Change Country code from module param fail ret=%d",
14092 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080014093 }
14094 }
14095
Jeff Johnson295189b2012-06-20 16:38:30 -070014096#ifdef WLAN_BTAMP_FEATURE
14097 vStatus = WLANBAP_Open(pVosContext);
14098 if(!VOS_IS_STATUS_SUCCESS(vStatus))
14099 {
14100 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14101 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070014102 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070014103 }
14104
14105 vStatus = BSL_Init(pVosContext);
14106 if(!VOS_IS_STATUS_SUCCESS(vStatus))
14107 {
14108 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14109 "%s: Failed to Init BSL",__func__);
14110 goto err_bap_close;
14111 }
14112 vStatus = WLANBAP_Start(pVosContext);
14113 if (!VOS_IS_STATUS_SUCCESS(vStatus))
14114 {
14115 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14116 "%s: Failed to start TL",__func__);
14117 goto err_bap_close;
14118 }
14119
14120 pConfig = pHddCtx->cfg_ini;
14121 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
14122 status = WLANBAP_SetConfig(&btAmpConfig);
14123
14124#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070014125
Mihir Shete9c238772014-10-15 14:35:16 +053014126 /*
14127 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
14128 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
14129 * which is greater than 0xf. So the below check is safe to make
14130 * sure that there is no entry for UapsdMask in the ini
14131 */
14132 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
14133 {
14134 if(IS_DYNAMIC_WMM_PS_ENABLED)
14135 {
14136 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
14137 __func__);
14138 pHddCtx->cfg_ini->UapsdMask =
14139 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
14140 }
14141 else
14142 {
14143 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
14144 __func__);
14145 pHddCtx->cfg_ini->UapsdMask =
14146 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
14147 }
14148 }
14149
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070014150#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
14151 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
14152 {
14153 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
14154 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
14155 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
14156 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
14157 }
14158#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014159
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014160 wlan_hdd_tdls_init(pHddCtx);
14161
Masti, Narayanraddi26378462016-01-05 18:20:28 +053014162 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
14163
14164 vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work,
14165 wlan_hdd_schedule_defer_scan);
14166
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053014167 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
14168
Jeff Johnson295189b2012-06-20 16:38:30 -070014169 /* Register with platform driver as client for Suspend/Resume */
14170 status = hddRegisterPmOps(pHddCtx);
14171 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14172 {
14173 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
14174#ifdef WLAN_BTAMP_FEATURE
14175 goto err_bap_stop;
14176#else
Jeff Johnsone7245742012-09-05 17:12:55 -070014177 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070014178#endif //WLAN_BTAMP_FEATURE
14179 }
14180
Yue Ma0d4891e2013-08-06 17:01:45 -070014181 /* Open debugfs interface */
14182 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
14183 {
14184 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14185 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070014186 }
14187
Jeff Johnson295189b2012-06-20 16:38:30 -070014188 /* Register TM level change handler function to the platform */
14189 status = hddDevTmRegisterNotifyCallback(pHddCtx);
14190 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14191 {
14192 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
14193 goto err_unregister_pmops;
14194 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014195
Jeff Johnson295189b2012-06-20 16:38:30 -070014196 // register net device notifier for device change notification
14197 ret = register_netdevice_notifier(&hdd_netdev_notifier);
14198
14199 if(ret < 0)
14200 {
14201 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053014202 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070014203 }
14204
Jeff Johnson295189b2012-06-20 16:38:30 -070014205 //Initialize the BTC service
14206 if(btc_activate_service(pHddCtx) != 0)
14207 {
14208 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053014209 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070014210 }
14211
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053014212#ifdef FEATURE_OEM_DATA_SUPPORT
14213 //Initialize the OEM service
14214 if (oem_activate_service(pHddCtx) != 0)
14215 {
14216 hddLog(VOS_TRACE_LEVEL_FATAL,
14217 "%s: oem_activate_service failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014218 goto err_btc_activate_service;
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053014219 }
14220#endif
14221
Jeff Johnson295189b2012-06-20 16:38:30 -070014222#ifdef PTT_SOCK_SVC_ENABLE
14223 //Initialize the PTT service
14224 if(ptt_sock_activate_svc(pHddCtx) != 0)
14225 {
14226 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014227 goto err_oem_activate_service;
Jeff Johnson295189b2012-06-20 16:38:30 -070014228 }
14229#endif
14230
Abhishek Singh00b71972016-01-07 10:51:04 +053014231#ifdef WLAN_FEATURE_RMC
14232 if (hdd_open_cesium_nl_sock() < 0)
14233 {
14234 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014235 goto err_ptt_sock_activate_svc;
Abhishek Singh00b71972016-01-07 10:51:04 +053014236 }
14237#endif
14238
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014239#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14240 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
14241 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053014242 if(wlan_logging_sock_activate_svc(
14243 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053014244 pHddCtx->cfg_ini->wlanLoggingNumBuf,
14245 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
14246 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053014247 {
14248 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
14249 " failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014250 goto err_open_cesium_nl_sock;
Deepthi Gowri78083a32014-11-04 12:55:51 +053014251 }
14252 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
14253 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053014254 if (!pHddCtx->cfg_ini->gEnableDebugLog)
14255 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053014256 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
14257 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014258 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014259
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014260 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
14261 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053014262 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053014263 pHddCtx->cfg_ini->enableContFWLogging ||
14264 pHddCtx->cfg_ini->enableFwrMemDump )
14265 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014266 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014267 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014268 }
14269 else
14270 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014271 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014272 }
14273
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014274#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014275
Sushant Kaushik215778f2015-05-21 14:05:36 +053014276 if (vos_is_multicast_logging())
14277 wlan_logging_set_log_level();
14278
Jeff Johnson295189b2012-06-20 16:38:30 -070014279 hdd_register_mcast_bcast_filter(pHddCtx);
Bala Venkateshe65810a2019-02-18 20:32:36 +053014280
14281 /* Action frame registered in one adapter which will
14282 * applicable to all interfaces
14283 */
14284 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014285
14286 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053014287 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070014288
Jeff Johnsone7245742012-09-05 17:12:55 -070014289#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
14290 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014291 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070014292 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014293
Jeff Johnsone7245742012-09-05 17:12:55 -070014294#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080014295 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014296 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080014297 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014298
Jeff Johnsone7245742012-09-05 17:12:55 -070014299
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014300 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
14301 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070014302
Katya Nigam5c306ea2014-06-19 15:39:54 +053014303 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070014304 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014305 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053014306
14307#ifdef FEATURE_WLAN_SCAN_PNO
14308 /*SME must send channel update configuration to RIVA*/
14309 sme_UpdateChannelConfig(pHddCtx->hHal);
14310#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053014311 /* Send the update default channel list to the FW*/
14312 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053014313
14314 /* Fwr capabilities received, Set the Dot11 mode */
Abhishek Singh41ebce12016-02-03 10:43:21 +053014315 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
14316 hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode));
Mukul Sharma45063942015-04-01 20:07:59 +053014317 sme_SetDefDot11Mode(pHddCtx->hHal);
14318
Abhishek Singha306a442013-11-07 18:39:01 +053014319#ifndef CONFIG_ENABLE_LINUX_REG
14320 /*updating wiphy so that regulatory user hints can be processed*/
14321 if (wiphy)
14322 {
14323 regulatory_hint(wiphy, "00");
14324 }
14325#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070014326 // Initialize the restart logic
14327 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053014328
Hanumanth Reddy Pothula146bca42016-11-08 12:01:07 +053014329 if (pHddCtx->cfg_ini->fIsLogpEnabled) {
14330 vos_wdthread_init_timer_work(vos_process_wd_timer);
14331 /* Initialize the timer to detect thread stuck issues */
14332 vos_thread_stuck_timer_init(
14333 &((VosContextType*)pVosContext)->vosWatchdog);
14334 }
14335
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070014336 //Register the traffic monitor timer now
14337 if ( pHddCtx->cfg_ini->dynSplitscan)
14338 {
14339 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
14340 VOS_TIMER_TYPE_SW,
14341 hdd_tx_rx_pkt_cnt_stat_timer_handler,
14342 (void *)pHddCtx);
14343 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053014344 wlan_hdd_cfg80211_nan_init(pHddCtx);
14345
Bhargav Shahd0715912015-10-01 18:17:37 +053014346 mutex_init(&pHddCtx->cur_rx_level_lock);
14347 vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
14348 hdd_tcp_delack_compute_function,(void *)pHddCtx);
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053014349 vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW,
14350 wlan_hdd_change_tdls_mode, (void *)pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +053014351
Dino Mycle6fb96c12014-06-10 11:52:40 +053014352#ifdef WLAN_FEATURE_EXTSCAN
14353 sme_EXTScanRegisterCallback(pHddCtx->hHal,
14354 wlan_hdd_cfg80211_extscan_callback,
14355 pHddCtx);
14356#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014357
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053014358#ifdef FEATURE_OEM_DATA_SUPPORT
14359 sme_OemDataRegisterCallback(pHddCtx->hHal,
14360 wlan_hdd_cfg80211_oemdata_callback,
14361 pHddCtx);
14362#endif /* FEATURE_OEM_DATA_SUPPORT */
14363
Gupta, Kapil7c34b322015-09-30 13:12:35 +053014364 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014365#ifdef WLAN_NS_OFFLOAD
14366 // Register IPv6 notifier to notify if any change in IP
14367 // So that we can reconfigure the offload parameters
14368 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
14369 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
14370 if (ret)
14371 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014372 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014373 }
14374 else
14375 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014376 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014377 }
14378#endif
14379
Sravan Kumar Kairamb0edc612016-10-26 13:55:24 +053014380 vos_mem_set((uint8_t *)&pHddCtx->bad_sta, HDD_MAX_STA_COUNT, 0);
14381
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014382 // Register IPv4 notifier to notify if any change in IP
14383 // So that we can reconfigure the offload parameters
14384 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
14385 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
14386 if (ret)
14387 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014388 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014389 }
14390 else
14391 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014392 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014393 }
c_manjeecfd1efb2015-09-25 19:32:34 +053014394 /*Fw mem dump procfs initialization*/
14395 memdump_init();
Bhargav shah23c94942015-10-13 12:48:35 +053014396 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014397
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053014398 pHddCtx->is_ap_mode_wow_supported =
14399 sme_IsFeatureSupportedByFW(SAP_MODE_WOW);
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053014400
Hanumanth Reddy Pothulae92bcc12017-05-19 13:56:35 +053014401 pHddCtx->is_fatal_event_log_sup =
14402 sme_IsFeatureSupportedByFW(FATAL_EVENT_LOGGING);
14403 hddLog(VOS_TRACE_LEVEL_INFO, FL("FATAL_EVENT_LOGGING: %d"),
14404 pHddCtx->is_fatal_event_log_sup);
14405
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053014406 hdd_assoc_registerFwdEapolCB(pVosContext);
14407
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053014408 mutex_init(&pHddCtx->cache_channel_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070014409 goto success;
14410
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014411err_open_cesium_nl_sock:
14412#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14413 hdd_close_cesium_nl_sock();
14414#endif
14415
14416err_ptt_sock_activate_svc:
14417#ifdef PTT_SOCK_SVC_ENABLE
14418 ptt_sock_deactivate_svc(pHddCtx);
14419#endif
14420
14421err_oem_activate_service:
14422#ifdef FEATURE_OEM_DATA_SUPPORT
14423 oem_deactivate_service();
14424#endif
14425
14426err_btc_activate_service:
14427 btc_deactivate_service();
14428
Jeff Johnson295189b2012-06-20 16:38:30 -070014429err_reg_netdev:
14430 unregister_netdevice_notifier(&hdd_netdev_notifier);
14431
Jeff Johnson295189b2012-06-20 16:38:30 -070014432err_unregister_pmops:
14433 hddDevTmUnregisterNotifyCallback(pHddCtx);
14434 hddDeregisterPmOps(pHddCtx);
14435
Yue Ma0d4891e2013-08-06 17:01:45 -070014436 hdd_debugfs_exit(pHddCtx);
14437
Jeff Johnson295189b2012-06-20 16:38:30 -070014438#ifdef WLAN_BTAMP_FEATURE
14439err_bap_stop:
14440 WLANBAP_Stop(pVosContext);
14441#endif
14442
14443#ifdef WLAN_BTAMP_FEATURE
14444err_bap_close:
14445 WLANBAP_Close(pVosContext);
14446#endif
14447
Jeff Johnson295189b2012-06-20 16:38:30 -070014448err_close_adapter:
14449 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053014450#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053014451err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053014452#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053014453 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053014454 hdd_wlan_free_wiphy_channels(wiphy);
14455
Jeff Johnson295189b2012-06-20 16:38:30 -070014456err_vosstop:
14457 vos_stop(pVosContext);
14458
Amar Singhala49cbc52013-10-08 18:37:44 -070014459err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070014460 status = vos_sched_close( pVosContext );
14461 if (!VOS_IS_STATUS_SUCCESS(status)) {
14462 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
14463 "%s: Failed to close VOSS Scheduler", __func__);
14464 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
14465 }
Amar Singhala49cbc52013-10-08 18:37:44 -070014466 vos_close(pVosContext );
14467
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053014468err_nl_srv:
14469#ifdef WLAN_KD_READY_NOTIFIER
14470 nl_srv_exit(pHddCtx->ptt_pid);
14471#else
14472 nl_srv_exit();
14473#endif /* WLAN_KD_READY_NOTIFIER */
Amar Singhal0a402232013-10-11 20:57:16 -070014474err_vos_nv_close:
14475
c_hpothue6a36282014-03-19 12:27:38 +053014476#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070014477 vos_nv_close();
14478
c_hpothu70f8d812014-03-22 22:59:23 +053014479#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014480
14481err_wdclose:
14482 if(pHddCtx->cfg_ini->fIsLogpEnabled)
14483 vos_watchdog_close(pVosContext);
14484
Jeff Johnson295189b2012-06-20 16:38:30 -070014485err_config:
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053014486 hdd_request_manager_deinit();
Jeff Johnson295189b2012-06-20 16:38:30 -070014487 kfree(pHddCtx->cfg_ini);
14488 pHddCtx->cfg_ini= NULL;
14489
14490err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014491 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053014492 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070014493 wiphy_free(wiphy) ;
14494 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070014495 VOS_BUG(1);
14496
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080014497 if (hdd_is_ssr_required())
14498 {
14499 /* WDI timeout had happened during load, so SSR is needed here */
14500 subsystem_restart("wcnss");
14501 msleep(5000);
14502 }
14503 hdd_set_ssr_required (VOS_FALSE);
14504
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014505 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070014506
14507success:
14508 EXIT();
14509 return 0;
14510}
14511
14512/**---------------------------------------------------------------------------
14513
Jeff Johnson32d95a32012-09-10 13:15:23 -070014514 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070014515
Jeff Johnson32d95a32012-09-10 13:15:23 -070014516 This is the driver entry point - called in different timeline depending
14517 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070014518
14519 \param - None
14520
14521 \return - 0 for success, non zero for failure
14522
14523 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070014524static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070014525{
14526 VOS_STATUS status;
14527 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014528 struct device *dev = NULL;
14529 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014530#ifdef HAVE_WCNSS_CAL_DOWNLOAD
14531 int max_retries = 0;
14532#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014533#ifdef HAVE_CBC_DONE
14534 int max_cbc_retries = 0;
14535#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014536
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014537#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14538 wlan_logging_sock_init_svc();
14539#endif
14540
Jeff Johnson295189b2012-06-20 16:38:30 -070014541 ENTER();
14542
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014543 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070014544
14545 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
14546 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
14547
Jeff Johnson295189b2012-06-20 16:38:30 -070014548#ifdef ANI_BUS_TYPE_PCI
14549
14550 dev = wcnss_wlan_get_device();
14551
14552#endif // ANI_BUS_TYPE_PCI
14553
14554#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014555
14556#ifdef HAVE_WCNSS_CAL_DOWNLOAD
14557 /* wait until WCNSS driver downloads NV */
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053014558 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014559 msleep(1000);
14560 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014561
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053014562 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014563 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014564 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014565#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14566 wlan_logging_sock_deinit_svc();
14567#endif
14568
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014569 return -ENODEV;
14570 }
14571#endif
14572
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014573#ifdef HAVE_CBC_DONE
14574 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
14575 msleep(1000);
14576 }
14577 if (max_cbc_retries >= 10) {
14578 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
14579 }
14580#endif
14581
Jeff Johnson295189b2012-06-20 16:38:30 -070014582 dev = wcnss_wlan_get_device();
14583#endif // ANI_BUS_TYPE_PLATFORM
14584
14585
14586 do {
14587 if (NULL == dev) {
14588 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
14589 ret_status = -1;
14590 break;
14591 }
14592
Jeff Johnson295189b2012-06-20 16:38:30 -070014593#ifdef TIMER_MANAGER
14594 vos_timer_manager_init();
14595#endif
14596
14597 /* Preopen VOSS so that it is ready to start at least SAL */
14598 status = vos_preOpen(&pVosContext);
14599
14600 if (!VOS_IS_STATUS_SUCCESS(status))
14601 {
14602 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
14603 ret_status = -1;
14604 break;
14605 }
14606
Sushant Kaushik02beb352015-06-04 15:15:01 +053014607 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053014608 hdd_register_debug_callback();
14609
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014610#ifndef MODULE
14611 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
14612 */
14613 hdd_set_conparam((v_UINT_t)con_mode);
14614#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014615
14616 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014617 if (hdd_wlan_startup(dev))
14618 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014619 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014620 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014621 vos_preClose( &pVosContext );
14622 ret_status = -1;
14623 break;
14624 }
14625
Jeff Johnson295189b2012-06-20 16:38:30 -070014626 } while (0);
14627
14628 if (0 != ret_status)
14629 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014630#ifdef TIMER_MANAGER
14631 vos_timer_exit();
14632#endif
14633#ifdef MEMORY_DEBUG
14634 vos_mem_exit();
14635#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014636 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014637#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14638 wlan_logging_sock_deinit_svc();
14639#endif
14640
Jeff Johnson295189b2012-06-20 16:38:30 -070014641 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
14642 }
14643 else
14644 {
14645 //Send WLAN UP indication to Nlink Service
14646 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
14647
14648 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070014649 }
14650
14651 EXIT();
14652
14653 return ret_status;
14654}
14655
Jeff Johnson32d95a32012-09-10 13:15:23 -070014656/**---------------------------------------------------------------------------
14657
14658 \brief hdd_module_init() - Init Function
14659
14660 This is the driver entry point (invoked when module is loaded using insmod)
14661
14662 \param - None
14663
14664 \return - 0 for success, non zero for failure
14665
14666 --------------------------------------------------------------------------*/
14667#ifdef MODULE
14668static int __init hdd_module_init ( void)
14669{
14670 return hdd_driver_init();
14671}
Jeff Johnson32d95a32012-09-10 13:15:23 -070014672#else /* #ifdef MODULE */
14673static int __init hdd_module_init ( void)
14674{
14675 /* Driver initialization is delayed to fwpath_changed_handler */
14676 return 0;
14677}
Jeff Johnson32d95a32012-09-10 13:15:23 -070014678#endif /* #ifdef MODULE */
14679
Jeff Johnson295189b2012-06-20 16:38:30 -070014680
14681/**---------------------------------------------------------------------------
14682
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014683 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070014684
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014685 This is the driver exit point (invoked when module is unloaded using rmmod
14686 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070014687
14688 \param - None
14689
14690 \return - None
14691
14692 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014693static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070014694{
14695 hdd_context_t *pHddCtx = NULL;
14696 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053014697 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053014698 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014699
14700 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
14701
14702 //Get the global vos context
14703 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14704
14705 if(!pVosContext)
14706 {
14707 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
14708 goto done;
14709 }
14710
14711 //Get the HDD context.
14712 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
14713
14714 if(!pHddCtx)
14715 {
14716 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
14717 }
Katya Nigame7b69a82015-04-28 15:24:06 +053014718 else if (VOS_MONITOR_MODE == hdd_get_conparam())
14719 {
14720 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
14721 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
14722 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
14723 hdd_wlan_exit(pHddCtx);
14724 vos_preClose( &pVosContext );
14725 goto done;
14726 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014727 else
14728 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053014729 /* We wait for active entry threads to exit from driver
14730 * by waiting until rtnl_lock is available.
14731 */
14732 rtnl_lock();
14733 rtnl_unlock();
14734
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014735 INIT_COMPLETION(pHddCtx->ssr_comp_var);
14736 if ((pHddCtx->isLogpInProgress) && (FALSE ==
14737 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
14738 {
Siddharth Bhala204f572015-01-17 02:03:36 +053014739 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014740 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053014741 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
14742 msecs_to_jiffies(30000));
14743 if(!rc)
14744 {
14745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14746 "%s:SSR timedout, fatal error", __func__);
14747 VOS_BUG(0);
14748 }
14749 }
14750
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014751 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
14752 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070014753
c_hpothu8adb97b2014-12-08 19:38:20 +053014754 /* Driver Need to send country code 00 in below condition
14755 * 1) If gCountryCodePriority is set to 1; and last country
14756 * code set is through 11d. This needs to be done in case
14757 * when NV country code is 00.
14758 * This Needs to be done as when kernel store last country
14759 * code and if stored country code is not through 11d,
14760 * in sme_HandleChangeCountryCodeByUser we will disable 11d
14761 * in next load/unload as soon as we get any country through
14762 * 11d. In sme_HandleChangeCountryCodeByUser
14763 * pMsg->countryCode will be last countryCode and
14764 * pMac->scan.countryCode11d will be country through 11d so
14765 * due to mismatch driver will disable 11d.
14766 *
14767 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053014768
c_hpothu8adb97b2014-12-08 19:38:20 +053014769 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053014770 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053014771 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053014772 {
14773 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053014774 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053014775 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
14776 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053014777
c_hpothu8adb97b2014-12-08 19:38:20 +053014778 //Do all the cleanup before deregistering the driver
14779 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070014780 }
14781
Jeff Johnson295189b2012-06-20 16:38:30 -070014782 vos_preClose( &pVosContext );
14783
14784#ifdef TIMER_MANAGER
14785 vos_timer_exit();
14786#endif
14787#ifdef MEMORY_DEBUG
14788 vos_mem_exit();
14789#endif
14790
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014791#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14792 wlan_logging_sock_deinit_svc();
14793#endif
14794
Jeff Johnson295189b2012-06-20 16:38:30 -070014795done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014796 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014797
Jeff Johnson295189b2012-06-20 16:38:30 -070014798 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
14799}
14800
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014801/**---------------------------------------------------------------------------
14802
14803 \brief hdd_module_exit() - Exit function
14804
14805 This is the driver exit point (invoked when module is unloaded using rmmod)
14806
14807 \param - None
14808
14809 \return - None
14810
14811 --------------------------------------------------------------------------*/
14812static void __exit hdd_module_exit(void)
14813{
14814 hdd_driver_exit();
14815}
14816
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014817#ifdef MODULE
14818static int fwpath_changed_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014819 const struct kernel_param *kp)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014820{
Jeff Johnson76052702013-04-16 13:55:05 -070014821 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014822}
14823
14824static int con_mode_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014825 const struct kernel_param *kp)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014826{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070014827 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014828}
14829#else /* #ifdef MODULE */
14830/**---------------------------------------------------------------------------
14831
Jeff Johnson76052702013-04-16 13:55:05 -070014832 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014833
Jeff Johnson76052702013-04-16 13:55:05 -070014834 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014835 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070014836 - invoked when module parameter fwpath is modified from userspace to signal
14837 initializing the WLAN driver or when con_mode is modified from userspace
14838 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014839
14840 \return - 0 for success, non zero for failure
14841
14842 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070014843static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014844{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014845 int ret_status;
14846
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014847 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014848 ret_status = hdd_driver_init();
14849 wlan_hdd_inited = ret_status ? 0 : 1;
14850 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014851 }
14852
14853 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070014854
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014855 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070014856
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014857 ret_status = hdd_driver_init();
14858 wlan_hdd_inited = ret_status ? 0 : 1;
14859 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014860}
14861
Jeff Johnson295189b2012-06-20 16:38:30 -070014862/**---------------------------------------------------------------------------
14863
Jeff Johnson76052702013-04-16 13:55:05 -070014864 \brief fwpath_changed_handler() - Handler Function
14865
14866 Handle changes to the fwpath parameter
14867
14868 \return - 0 for success, non zero for failure
14869
14870 --------------------------------------------------------------------------*/
14871static int fwpath_changed_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014872 const struct kernel_param *kp)
Jeff Johnson76052702013-04-16 13:55:05 -070014873{
14874 int ret;
14875
14876 ret = param_set_copystring(kmessage, kp);
14877 if (0 == ret)
14878 ret = kickstart_driver();
14879 return ret;
14880}
14881
14882/**---------------------------------------------------------------------------
14883
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014884 \brief con_mode_handler() -
14885
14886 Handler function for module param con_mode when it is changed by userspace
14887 Dynamically linked - do nothing
14888 Statically linked - exit and init driver, as in rmmod and insmod
14889
Jeff Johnson76052702013-04-16 13:55:05 -070014890 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014891
Jeff Johnson76052702013-04-16 13:55:05 -070014892 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014893
14894 --------------------------------------------------------------------------*/
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014895static int con_mode_handler(const char *kmessage,
14896 const struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014897{
Jeff Johnson76052702013-04-16 13:55:05 -070014898 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014899
Jeff Johnson76052702013-04-16 13:55:05 -070014900 ret = param_set_int(kmessage, kp);
14901 if (0 == ret)
14902 ret = kickstart_driver();
14903 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014904}
14905#endif /* #ifdef MODULE */
14906
14907/**---------------------------------------------------------------------------
14908
Jeff Johnson295189b2012-06-20 16:38:30 -070014909 \brief hdd_get_conparam() -
14910
14911 This is the driver exit point (invoked when module is unloaded using rmmod)
14912
14913 \param - None
14914
14915 \return - tVOS_CON_MODE
14916
14917 --------------------------------------------------------------------------*/
14918tVOS_CON_MODE hdd_get_conparam ( void )
14919{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014920#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070014921 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014922#else
14923 return (tVOS_CON_MODE)curr_con_mode;
14924#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014925}
14926void hdd_set_conparam ( v_UINT_t newParam )
14927{
14928 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014929#ifndef MODULE
14930 curr_con_mode = con_mode;
14931#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014932}
14933/**---------------------------------------------------------------------------
14934
14935 \brief hdd_softap_sta_deauth() - function
14936
14937 This to take counter measure to handle deauth req from HDD
14938
14939 \param - pAdapter - Pointer to the HDD
14940
14941 \param - enable - boolean value
14942
14943 \return - None
14944
14945 --------------------------------------------------------------------------*/
14946
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014947VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
14948 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070014949{
Jeff Johnson295189b2012-06-20 16:38:30 -070014950 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014951 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014952 struct hdd_cache_sta_info *cache_sta_info;
14953 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014954
14955 ENTER();
14956
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014957 hddLog(LOG1, "hdd_softap_sta_deauth:(%pK, false)",
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070014958 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014959
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014960 if (!pSapCtx) {
14961 hddLog(LOGE, "sap context is NULL");
14962 return vosStatus;
14963 }
14964
14965 cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
14966 pDelStaParams->peerMacAddr);
14967 if (cache_sta_info) {
14968 cache_sta_info->reason_code = pDelStaParams->reason_code;
14969 cache_sta_info->rx_rate =
14970 wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
14971 WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
14972 &cache_sta_info->rssi);
14973 }
14974
Jeff Johnson295189b2012-06-20 16:38:30 -070014975 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014976 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014977 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070014978
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014979 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070014980
14981 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014982 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070014983}
14984
14985/**---------------------------------------------------------------------------
14986
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014987 \brief hdd_del_all_sta() - function
14988
14989 This function removes all the stations associated on stopping AP/P2P GO.
14990
14991 \param - pAdapter - Pointer to the HDD
14992
14993 \return - None
14994
14995 --------------------------------------------------------------------------*/
14996
14997int hdd_del_all_sta(hdd_adapter_t *pAdapter)
14998{
14999 v_U16_t i;
15000 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015001 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15002 ptSapContext pSapCtx = NULL;
15003 pSapCtx = VOS_GET_SAP_CB(pVosContext);
15004 if(pSapCtx == NULL){
15005 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15006 FL("psapCtx is NULL"));
15007 return 1;
15008 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053015009 ENTER();
15010
15011 hddLog(VOS_TRACE_LEVEL_INFO,
15012 "%s: Delete all STAs associated.",__func__);
15013 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
15014 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
15015 )
15016 {
15017 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
15018 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015019 if ((pSapCtx->aStaInfo[i].isUsed) &&
15020 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053015021 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015022 struct tagCsrDelStaParams delStaParams;
15023
15024 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015025 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053015026 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
15027 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015028 &delStaParams);
15029 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053015030 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015031 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053015032 }
15033 }
15034 }
15035
15036 EXIT();
15037 return 0;
15038}
15039
15040/**---------------------------------------------------------------------------
15041
Jeff Johnson295189b2012-06-20 16:38:30 -070015042 \brief hdd_softap_sta_disassoc() - function
15043
15044 This to take counter measure to handle deauth req from HDD
15045
15046 \param - pAdapter - Pointer to the HDD
15047
15048 \param - enable - boolean value
15049
15050 \return - None
15051
15052 --------------------------------------------------------------------------*/
15053
15054void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
15055{
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053015056 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15057 struct hdd_cache_sta_info *cache_sta_info;
15058 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070015059
15060 ENTER();
15061
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015062 hddLog( LOGE, "hdd_softap_sta_disassoc:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070015063
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053015064 if (!pSapCtx) {
15065 hddLog(LOGE, "sap context is NULL");
15066 return ;
15067 }
15068
Jeff Johnson295189b2012-06-20 16:38:30 -070015069 //Ignore request to disassoc bcmc station
15070 if( pDestMacAddress[0] & 0x1 )
15071 return;
15072
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053015073 cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
15074 pDestMacAddress);
15075 if (cache_sta_info) {
15076 cache_sta_info->reason_code = eSIR_MAC_DEAUTH_LEAVING_BSS_REASON;
15077 cache_sta_info->rx_rate =
15078 wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
15079 WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
15080 &cache_sta_info->rssi);
15081 }
15082
Jeff Johnson295189b2012-06-20 16:38:30 -070015083 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
15084}
15085
15086void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
15087{
15088 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15089
15090 ENTER();
15091
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015092 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070015093
15094 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
15095}
15096
Jeff Johnson295189b2012-06-20 16:38:30 -070015097/**---------------------------------------------------------------------------
15098 *
15099 * \brief hdd_get__concurrency_mode() -
15100 *
15101 *
15102 * \param - None
15103 *
15104 * \return - CONCURRENCY MODE
15105 *
15106 * --------------------------------------------------------------------------*/
15107tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
15108{
15109 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
15110 hdd_context_t *pHddCtx;
15111
15112 if (NULL != pVosContext)
15113 {
15114 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
15115 if (NULL != pHddCtx)
15116 {
15117 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
15118 }
15119 }
15120
15121 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015122 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015123 return VOS_STA;
15124}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015125v_BOOL_t
15126wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
15127{
15128 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015129
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015130 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
15131 if (pAdapter == NULL)
15132 {
15133 hddLog(VOS_TRACE_LEVEL_INFO,
15134 FL("GO doesn't exist"));
15135 return TRUE;
15136 }
15137 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
15138 {
15139 hddLog(VOS_TRACE_LEVEL_INFO,
15140 FL("GO started"));
15141 return TRUE;
15142 }
15143 else
15144 /* wait till GO changes its interface to p2p device */
15145 hddLog(VOS_TRACE_LEVEL_INFO,
15146 FL("Del_bss called, avoid apps suspend"));
15147 return FALSE;
15148
15149}
Jeff Johnson295189b2012-06-20 16:38:30 -070015150/* Decide whether to allow/not the apps power collapse.
15151 * Allow apps power collapse if we are in connected state.
15152 * if not, allow only if we are in IMPS */
15153v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
15154{
15155 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080015156 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080015157 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070015158 hdd_config_t *pConfig = pHddCtx->cfg_ini;
15159 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15160 hdd_adapter_t *pAdapter = NULL;
15161 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080015162 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015163
Jeff Johnson295189b2012-06-20 16:38:30 -070015164 if (VOS_STA_SAP_MODE == hdd_get_conparam())
15165 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015166
Yathish9f22e662012-12-10 14:21:35 -080015167 concurrent_state = hdd_get_concurrency_mode();
15168
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015169 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
15170 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
15171 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080015172#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015173
Yathish9f22e662012-12-10 14:21:35 -080015174 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015175 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080015176 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
15177 return TRUE;
15178#endif
15179
Jeff Johnson295189b2012-06-20 16:38:30 -070015180 /*loop through all adapters. TBD fix for Concurrency */
15181 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15182 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15183 {
15184 pAdapter = pAdapterNode->pAdapter;
15185 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
15186 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15187 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080015188 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053015189 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053015190 && pmcState != STOPPED && pmcState != STANDBY &&
15191 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080015192 (eANI_BOOLEAN_TRUE == scanRspPending) ||
15193 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070015194 {
Mukul Sharma4be88422015-03-09 20:29:07 +053015195 if(pmcState == FULL_POWER &&
15196 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
15197 {
15198 /*
15199 * When SCO indication comes from Coex module , host will
15200 * enter in to full power mode, but this should not prevent
15201 * apps processor power collapse.
15202 */
15203 hddLog(LOG1,
15204 FL("Allow apps power collapse"
15205 "even when sco indication is set"));
15206 return TRUE;
15207 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080015208 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Deepthi Gowri03a979f2016-11-03 15:20:19 +053015209 "pmcState = %d scanRspPending = %d "
15210 "inMiddleOfRoaming = %d connected = %d",
15211 __func__, pmcState, scanRspPending,
15212 inMiddleOfRoaming, hdd_connIsConnected(
15213 WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )));
15214 wlan_hdd_get_tdls_stats(pAdapter);
15215 return FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015216 }
15217 }
15218 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15219 pAdapterNode = pNext;
15220 }
15221 return TRUE;
15222}
15223
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080015224/* Decides whether to send suspend notification to Riva
15225 * if any adapter is in BMPS; then it is required */
15226v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
15227{
15228 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
15229 hdd_config_t *pConfig = pHddCtx->cfg_ini;
15230
15231 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
15232 {
15233 return TRUE;
15234 }
15235 return FALSE;
15236}
15237
Jeff Johnson295189b2012-06-20 16:38:30 -070015238void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15239{
15240 switch(mode)
15241 {
Chilam Ngc4244af2013-04-01 15:37:32 -070015242 case VOS_STA_MODE:
15243 case VOS_P2P_CLIENT_MODE:
15244 case VOS_P2P_GO_MODE:
15245 case VOS_STA_SAP_MODE:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015246 case VOS_MONITOR_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070015247 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053015248 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070015249 break;
15250 default:
15251 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015252 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015253 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
15254 "Number of open sessions for mode %d = %d"),
15255 pHddCtx->concurrency_mode, mode,
15256 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070015257}
15258
15259
15260void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15261{
15262 switch(mode)
15263 {
Chilam Ngc4244af2013-04-01 15:37:32 -070015264 case VOS_STA_MODE:
15265 case VOS_P2P_CLIENT_MODE:
15266 case VOS_P2P_GO_MODE:
15267 case VOS_STA_SAP_MODE:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015268 case VOS_MONITOR_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053015269 pHddCtx->no_of_open_sessions[mode]--;
15270 if (!(pHddCtx->no_of_open_sessions[mode]))
15271 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015272 break;
15273 default:
15274 break;
15275 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015276 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
15277 "Number of open sessions for mode %d = %d"),
15278 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
15279
15280}
15281/**---------------------------------------------------------------------------
15282 *
15283 * \brief wlan_hdd_incr_active_session()
15284 *
15285 * This function increments the number of active sessions
15286 * maintained per device mode
15287 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
15288 * Incase of SAP/P2P GO upon bss start it is incremented
15289 *
15290 * \param pHddCtx - HDD Context
15291 * \param mode - device mode
15292 *
15293 * \return - None
15294 *
15295 * --------------------------------------------------------------------------*/
15296void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15297{
15298 switch (mode) {
15299 case VOS_STA_MODE:
15300 case VOS_P2P_CLIENT_MODE:
15301 case VOS_P2P_GO_MODE:
15302 case VOS_STA_SAP_MODE:
15303 pHddCtx->no_of_active_sessions[mode]++;
15304 break;
15305 default:
15306 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
15307 break;
15308 }
15309 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
15310 mode,
15311 pHddCtx->no_of_active_sessions[mode]);
15312}
15313
15314/**---------------------------------------------------------------------------
15315 *
15316 * \brief wlan_hdd_decr_active_session()
15317 *
15318 * This function decrements the number of active sessions
15319 * maintained per device mode
15320 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
15321 * Incase of SAP/P2P GO upon bss stop it is decremented
15322 *
15323 * \param pHddCtx - HDD Context
15324 * \param mode - device mode
15325 *
15326 * \return - None
15327 *
15328 * --------------------------------------------------------------------------*/
15329void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15330{
Bhargav Shahd0715912015-10-01 18:17:37 +053015331
Agarwal Ashish51325b52014-06-16 16:50:49 +053015332 switch (mode) {
15333 case VOS_STA_MODE:
15334 case VOS_P2P_CLIENT_MODE:
15335 case VOS_P2P_GO_MODE:
15336 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053015337 if (pHddCtx->no_of_active_sessions[mode] > 0)
15338 pHddCtx->no_of_active_sessions[mode]--;
15339 else
15340 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
15341 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053015342 break;
15343 default:
15344 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
15345 break;
15346 }
15347 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
15348 mode,
15349 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070015350}
15351
Jeff Johnsone7245742012-09-05 17:12:55 -070015352/**---------------------------------------------------------------------------
15353 *
15354 * \brief wlan_hdd_restart_init
15355 *
15356 * This function initalizes restart timer/flag. An internal function.
15357 *
15358 * \param - pHddCtx
15359 *
15360 * \return - None
15361 *
15362 * --------------------------------------------------------------------------*/
15363
15364static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
15365{
15366 /* Initialize */
15367 pHddCtx->hdd_restart_retries = 0;
15368 atomic_set(&pHddCtx->isRestartInProgress, 0);
15369 vos_timer_init(&pHddCtx->hdd_restart_timer,
15370 VOS_TIMER_TYPE_SW,
15371 wlan_hdd_restart_timer_cb,
15372 pHddCtx);
15373}
15374/**---------------------------------------------------------------------------
15375 *
15376 * \brief wlan_hdd_restart_deinit
15377 *
15378 * This function cleans up the resources used. An internal function.
15379 *
15380 * \param - pHddCtx
15381 *
15382 * \return - None
15383 *
15384 * --------------------------------------------------------------------------*/
15385
15386static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
15387{
15388
15389 VOS_STATUS vos_status;
15390 /* Block any further calls */
15391 atomic_set(&pHddCtx->isRestartInProgress, 1);
15392 /* Cleanup */
15393 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
15394 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015395 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070015396 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
15397 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015398 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070015399
15400}
15401
15402/**---------------------------------------------------------------------------
15403 *
15404 * \brief wlan_hdd_framework_restart
15405 *
15406 * This function uses a cfg80211 API to start a framework initiated WLAN
15407 * driver module unload/load.
15408 *
15409 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
15410 *
15411 *
15412 * \param - pHddCtx
15413 *
15414 * \return - VOS_STATUS_SUCCESS: Success
15415 * VOS_STATUS_E_EMPTY: Adapter is Empty
15416 * VOS_STATUS_E_NOMEM: No memory
15417
15418 * --------------------------------------------------------------------------*/
15419
15420static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
15421{
15422 VOS_STATUS status = VOS_STATUS_SUCCESS;
15423 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015424 int len = (sizeof (struct ieee80211_mgmt));
15425 struct ieee80211_mgmt *mgmt = NULL;
15426
15427 /* Prepare the DEAUTH managment frame with reason code */
15428 mgmt = kzalloc(len, GFP_KERNEL);
15429 if(mgmt == NULL)
15430 {
15431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15432 "%s: memory allocation failed (%d bytes)", __func__, len);
15433 return VOS_STATUS_E_NOMEM;
15434 }
15435 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070015436
15437 /* Iterate over all adapters/devices */
15438 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015439 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
15440 {
15441 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015442 FL("fail to get adapter: %pK %d"), pAdapterNode, status);
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015443 goto end;
15444 }
15445
Jeff Johnsone7245742012-09-05 17:12:55 -070015446 do
15447 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015448 if(pAdapterNode->pAdapter &&
15449 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070015450 {
15451 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15452 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
15453 pAdapterNode->pAdapter->dev->name,
15454 pAdapterNode->pAdapter->device_mode,
15455 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015456 /*
15457 * CFG80211 event to restart the driver
15458 *
15459 * 'cfg80211_send_unprot_deauth' sends a
15460 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
15461 * of SME(Linux Kernel) state machine.
15462 *
15463 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
15464 * the driver.
15465 *
15466 */
Abhishek Singh00b71972016-01-07 10:51:04 +053015467
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053015468#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
15469 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
15470#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015471 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053015472#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070015473 }
15474 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15475 pAdapterNode = pNext;
15476 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
15477
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015478 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015479 /* Free the allocated management frame */
15480 kfree(mgmt);
15481
Jeff Johnsone7245742012-09-05 17:12:55 -070015482 /* Retry until we unload or reach max count */
15483 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
15484 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
15485
15486 return status;
15487
15488}
15489/**---------------------------------------------------------------------------
15490 *
15491 * \brief wlan_hdd_restart_timer_cb
15492 *
15493 * Restart timer callback. An internal function.
15494 *
15495 * \param - User data:
15496 *
15497 * \return - None
15498 *
15499 * --------------------------------------------------------------------------*/
15500
15501void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
15502{
15503 hdd_context_t *pHddCtx = usrDataForCallback;
15504 wlan_hdd_framework_restart(pHddCtx);
15505 return;
15506
15507}
15508
15509
15510/**---------------------------------------------------------------------------
15511 *
15512 * \brief wlan_hdd_restart_driver
15513 *
15514 * This function sends an event to supplicant to restart the WLAN driver.
15515 *
15516 * This function is called from vos_wlanRestart.
15517 *
15518 * \param - pHddCtx
15519 *
15520 * \return - VOS_STATUS_SUCCESS: Success
15521 * VOS_STATUS_E_EMPTY: Adapter is Empty
15522 * VOS_STATUS_E_ALREADY: Request already in progress
15523
15524 * --------------------------------------------------------------------------*/
15525VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
15526{
15527 VOS_STATUS status = VOS_STATUS_SUCCESS;
15528
15529 /* A tight check to make sure reentrancy */
15530 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
15531 {
Mihir Shetefd528652014-06-23 19:07:50 +053015532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070015533 "%s: WLAN restart is already in progress", __func__);
15534
15535 return VOS_STATUS_E_ALREADY;
15536 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070015537 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080015538#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053015539 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070015540#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070015541
Jeff Johnsone7245742012-09-05 17:12:55 -070015542 return status;
15543}
15544
Bhargav Shahd0715912015-10-01 18:17:37 +053015545/**
15546 * hdd_get_total_sessions() - provide total number of active sessions
15547 * @pHddCtx: Valid Global HDD context pointer
15548 *
15549 * This function iterates through pAdaptors and find the number of all active
15550 * sessions. This active sessions includes connected sta, p2p client and number
15551 * of client connected to sap/p2p go.
15552 *
15553 * Return: Total number of active sessions.
15554 */
15555v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx)
15556{
15557 v_U8_t active_session = 0;
15558 hdd_station_ctx_t *pHddStaCtx;
15559 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15560 hdd_adapter_t *pAdapter;
15561 VOS_STATUS status;
15562
15563 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
15564 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
15565 pAdapter = pAdapterNode->pAdapter;
15566 switch (pAdapter->device_mode) {
15567 case VOS_STA_MODE:
15568 case VOS_P2P_CLIENT_MODE:
15569 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15570 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15571 active_session += 1;
15572 break;
15573 case VOS_STA_SAP_MODE:
15574 case VOS_P2P_GO_MODE:
15575 active_session += hdd_softap_get_connected_sta(pAdapter);
15576 break;
15577 default:
15578 break;
15579 }
15580
15581 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
15582 pAdapterNode = pNext;
15583 }
15584
15585 return active_session;
15586}
15587
15588/**
15589 * hdd_set_delack_value() - Set delack value
15590 * @pHddCtx: Valid Global HDD context pointer
15591 * @next_rx_level: Value to set for delack
15592 *
15593 * This function compare present value and next value of delack. If the both
15594 * are diffrent then it sets next value .
15595 *
15596 * Return: void.
15597 */
15598void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
15599{
15600 if (pHddCtx->cur_rx_level != next_rx_level) {
Alok Kumarf3724462018-04-05 15:18:54 +053015601 struct wlan_rx_tp_data rx_tp_data = {0};
15602
Bhargav Shahd0715912015-10-01 18:17:37 +053015603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15604 "%s: TCP DELACK trigger level %d",
15605 __func__, next_rx_level);
15606 mutex_lock(&pHddCtx->cur_rx_level_lock);
15607 pHddCtx->cur_rx_level = next_rx_level;
15608 mutex_unlock(&pHddCtx->cur_rx_level_lock);
Alok Kumarf3724462018-04-05 15:18:54 +053015609
15610 rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
15611 rx_tp_data.level = next_rx_level;
15612
15613 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &rx_tp_data,
15614 sizeof(rx_tp_data));
Bhargav Shahd0715912015-10-01 18:17:37 +053015615 }
15616}
15617
15618/**
15619 * hdd_set_default_stop_delack_timer() - Start delack timer
15620 * @pHddCtx: Valid Global HDD context pointer
15621 *
15622 * This function stop delack timer and set delack value to default..
15623 *
15624 * Return: void.
15625 */
15626
15627void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
15628{
15629 if (VOS_TIMER_STATE_RUNNING !=
15630 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
15631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15632 "%s: Can not stop timer", __func__);
15633 return;
15634 }
15635
15636 vos_timer_stop(&pHddCtx->delack_timer);
Alok Kumarf3724462018-04-05 15:18:54 +053015637 hdd_set_delack_value(pHddCtx, WLAN_SVC_TP_LOW);
Bhargav Shahd0715912015-10-01 18:17:37 +053015638}
15639
15640/**
15641 * hdd_start_delack_timer() - Start delack timer
15642 * @pHddCtx: Valid Global HDD context pointer
15643 *
15644 * This function starts the delack timer for tcpDelAckComputeInterval time
15645 * interval.The default timer value is 2 second.
15646 *
15647 * Return: void.
15648 */
15649void hdd_start_delack_timer(hdd_context_t *pHddCtx)
15650{
15651 if (VOS_TIMER_STATE_RUNNING ==
15652 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
15653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15654 "%s: Timer is already running", __func__);
15655 return;
15656 }
15657
15658 vos_timer_start(&pHddCtx->delack_timer,
15659 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
15660}
15661
15662/**
15663 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
15664 * @pHddCtx: Valid Global HDD context pointer
15665 *
15666 * This function updates the prev_rx_packets count from the corresponding
15667 * pAdapter states. This prev_rx_packets will diffed with the packet count
15668 * at the end of delack timer. That can give number of RX packet is spacific
15669 * time.
15670 *
15671 * Return: void.
15672 */
15673void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
15674{
15675 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15676 hdd_adapter_t *pAdapter;
15677 VOS_STATUS status;
15678
15679 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15680 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
15681 pAdapter = pAdapterNode->pAdapter;
15682 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
15683 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15684 pAdapterNode = pNext;
15685 }
15686}
15687
15688/**
15689 * hdd_manage_delack_timer() - start\stop delack timer
15690 * @pHddCtx: Valid Global HDD context pointer
15691 *
15692 * This function check the number of concerent session present, it starts the
15693 * delack timer if only one session is present.
15694 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
15695 *
15696 * Return: void.
15697 */
15698void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
15699{
15700 uint8_t sessions;
15701
15702 if (!pHddCtx->cfg_ini->enable_delack) {
15703 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15704 "%s: TCP DELACK is not enabled", __func__);
15705 return;
15706 }
15707
15708 /* Blindly stop timer of BTCOEX and TDLS Session is up */
15709 if (pHddCtx->mode != 0) {
15710 hdd_set_default_stop_delack_timer(pHddCtx);
15711 return;
15712 }
15713
15714 sessions = hdd_get_total_sessions(pHddCtx);
15715 if (sessions == 1) {
15716 hdd_update_prev_rx_packet_count(pHddCtx);
15717 hdd_start_delack_timer(pHddCtx);
15718 } else {
15719 hdd_set_default_stop_delack_timer(pHddCtx);
15720 }
15721}
15722
Mihir Shetee1093ba2014-01-21 20:13:32 +053015723/**---------------------------------------------------------------------------
15724 *
15725 * \brief wlan_hdd_init_channels
15726 *
15727 * This function is used to initialize the channel list in CSR
15728 *
15729 * This function is called from hdd_wlan_startup
15730 *
15731 * \param - pHddCtx: HDD context
15732 *
15733 * \return - VOS_STATUS_SUCCESS: Success
15734 * VOS_STATUS_E_FAULT: Failure reported by SME
15735
15736 * --------------------------------------------------------------------------*/
15737static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
15738{
15739 eHalStatus status;
15740
15741 status = sme_InitChannels(pHddCtx->hHal);
15742 if (HAL_STATUS_SUCCESS(status))
15743 {
15744 return VOS_STATUS_SUCCESS;
15745 }
15746 else
15747 {
15748 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
15749 __func__, status);
15750 return VOS_STATUS_E_FAULT;
15751 }
15752}
15753
Mihir Shete04206452014-11-20 17:50:58 +053015754#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053015755VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053015756{
15757 eHalStatus status;
15758
Rajeev Kumar Sirasanagandlaf8fc27c2018-12-06 14:56:43 +053015759 if (init == INIT && init_by_reg_core_user) {
15760 init_by_reg_core_user = false;
15761 pr_info("driver regulatory hint is not required");
15762
15763 return VOS_STATUS_SUCCESS;
15764 }
15765
Agarwal Ashish6db9d532014-09-30 18:19:10 +053015766 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053015767 if (HAL_STATUS_SUCCESS(status))
15768 {
15769 return VOS_STATUS_SUCCESS;
15770 }
15771 else
15772 {
15773 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
15774 __func__, status);
15775 return VOS_STATUS_E_FAULT;
15776 }
15777}
Mihir Shete04206452014-11-20 17:50:58 +053015778#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070015779/*
15780 * API to find if there is any STA or P2P-Client is connected
15781 */
15782VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
15783{
15784 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
15785}
Jeff Johnsone7245742012-09-05 17:12:55 -070015786
Mihir Shetee2ae82a2015-03-16 14:08:49 +053015787
15788/*
15789 * API to find if the firmware will send logs using DXE channel
15790 */
15791v_U8_t hdd_is_fw_logging_enabled(void)
15792{
15793 hdd_context_t *pHddCtx;
15794
15795 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
15796 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
15797
Sravan Kumar Kairam1d5bf8e2019-03-21 00:33:56 +053015798 return (pHddCtx && pHddCtx->cfg_ini->wlanLoggingEnable &&
15799 pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053015800}
15801
Agarwal Ashish57e84372014-12-05 18:26:53 +053015802/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053015803 * API to find if the firmware will send trace logs using DXE channel
15804 */
15805v_U8_t hdd_is_fw_ev_logging_enabled(void)
15806{
15807 hdd_context_t *pHddCtx;
15808
15809 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
15810 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
15811
Sravan Kumar Kairam1d5bf8e2019-03-21 00:33:56 +053015812 return (pHddCtx && pHddCtx->cfg_ini->wlanLoggingEnable &&
15813 pHddCtx->cfg_ini->enableFWLogging);
Mihir Shetebe94ebb2015-05-26 12:07:14 +053015814}
Sravan Kumar Kairam1d5bf8e2019-03-21 00:33:56 +053015815
Mihir Shetebe94ebb2015-05-26 12:07:14 +053015816/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053015817 * API to find if there is any session connected
15818 */
15819VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
15820{
15821 return sme_is_any_session_connected(pHddCtx->hHal);
15822}
15823
15824
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015825int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
15826{
15827 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15828 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053015829 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053015830 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015831
15832 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053015833 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015834 if (pScanInfo->mScanPending)
15835 {
c_hpothua3d45d52015-01-05 14:11:17 +053015836 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
15837 eCSR_SCAN_ABORT_DEFAULT);
15838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15839 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015840
c_hpothua3d45d52015-01-05 14:11:17 +053015841 /* If there is active scan command lets wait for the completion else
15842 * there is no need to wait as scan command might be in the SME pending
15843 * command list.
15844 */
15845 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
15846 {
Mukul Sharmab392b642017-08-17 17:45:29 +053015847 status = wait_for_completion_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015848 &pScanInfo->abortscan_event_var,
15849 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053015850 if (0 >= status)
15851 {
15852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053015853 "%s: Timeout or Interrupt occurred while waiting for abort"
15854 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053015855 return -ETIMEDOUT;
15856 }
15857 }
15858 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
15859 {
15860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15861 FL("hdd_abort_mac_scan failed"));
15862 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015863 }
15864 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053015865 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015866}
15867
Abhishek Singh7d624e12015-11-30 14:29:27 +053015868/**
15869 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
15870 * user space
15871 * @frame_ind: Management frame data to be informed.
15872 *
15873 * This function is used to indicate management frame to
15874 * user space
15875 *
15876 * Return: None
15877 *
15878 */
15879void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
15880{
15881 hdd_context_t *hdd_ctx = NULL;
15882 hdd_adapter_t *adapter = NULL;
15883 v_CONTEXT_t vos_context = NULL;
Pragaspathi Thilagaraj4aa58d52019-05-27 18:35:26 +053015884 struct ieee80211_mgmt *mgmt =
15885 (struct ieee80211_mgmt *)frame_ind->frameBuf;
Abhishek Singh7d624e12015-11-30 14:29:27 +053015886
15887 /* Get the global VOSS context.*/
15888 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
15889 if (!vos_context) {
15890 hddLog(LOGE, FL("Global VOS context is Null"));
15891 return;
15892 }
15893 /* Get the HDD context.*/
15894 hdd_ctx =
15895 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
15896
15897 if (0 != wlan_hdd_validate_context(hdd_ctx))
15898 {
15899 return;
15900 }
Pragaspathi Thilagaraj4aa58d52019-05-27 18:35:26 +053015901
15902 if (frame_ind->frameLen < ieee80211_hdrlen(mgmt->frame_control)) {
15903 hddLog(LOGE, FL(" Invalid frame length"));
15904 return;
15905 }
15906
Abhishek Singh7d624e12015-11-30 14:29:27 +053015907 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
15908 frame_ind->sessionId);
15909
15910 if ((NULL != adapter) &&
15911 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
15912 __hdd_indicate_mgmt_frame(adapter,
15913 frame_ind->frameLen,
15914 frame_ind->frameBuf,
15915 frame_ind->frameType,
15916 frame_ind->rxChan,
15917 frame_ind->rxRssi);
15918 return;
15919
15920}
15921
c_hpothu225aa7c2014-10-22 17:45:13 +053015922VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
15923{
15924 hdd_adapter_t *pAdapter;
15925 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15926 VOS_STATUS vosStatus;
15927
15928 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15929 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
15930 {
15931 pAdapter = pAdapterNode->pAdapter;
15932 if (NULL != pAdapter)
15933 {
15934 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
15935 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
15936 WLAN_HDD_P2P_GO == pAdapter->device_mode)
15937 {
15938 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
15939 pAdapter->device_mode);
15940 if (VOS_STATUS_SUCCESS !=
15941 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
15942 {
15943 hddLog(LOGE, FL("failed to abort ROC"));
15944 return VOS_STATUS_E_FAILURE;
15945 }
15946 }
15947 }
15948 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15949 pAdapterNode = pNext;
15950 }
15951 return VOS_STATUS_SUCCESS;
15952}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053015953
Mihir Shete0be28772015-02-17 18:42:14 +053015954hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
15955{
15956 hdd_adapter_t *pAdapter;
15957 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15958 hdd_cfg80211_state_t *cfgState;
15959 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
15960 VOS_STATUS vosStatus;
15961
15962 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
15963 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
15964 {
15965 pAdapter = pAdapterNode->pAdapter;
15966 if (NULL != pAdapter)
15967 {
15968 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
15969 pRemainChanCtx = cfgState->remain_on_chan_ctx;
15970 if (pRemainChanCtx)
15971 break;
15972 }
15973 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
15974 pAdapterNode = pNext;
15975 }
15976 return pRemainChanCtx;
15977}
15978
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053015979/**
15980 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
15981 *
15982 * @pHddCtx: HDD context within host driver
15983 * @dfsScanMode: dfsScanMode passed from ioctl
15984 *
15985 */
15986
15987VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
15988 tANI_U8 dfsScanMode)
15989{
15990 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15991 hdd_adapter_t *pAdapter;
15992 VOS_STATUS vosStatus;
15993 hdd_station_ctx_t *pHddStaCtx;
15994 eHalStatus status = eHAL_STATUS_SUCCESS;
15995
15996 if(!pHddCtx)
15997 {
15998 hddLog(LOGE, FL("HDD context is Null"));
15999 return eHAL_STATUS_FAILURE;
16000 }
16001
16002 if (pHddCtx->scan_info.mScanPending)
16003 {
16004 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
16005 pHddCtx->scan_info.sessionId);
16006 hdd_abort_mac_scan(pHddCtx,
16007 pHddCtx->scan_info.sessionId,
16008 eCSR_SCAN_ABORT_DEFAULT);
16009 }
16010
16011 if (!dfsScanMode)
16012 {
16013 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
16014 while ((NULL != pAdapterNode) &&
16015 (VOS_STATUS_SUCCESS == vosStatus))
16016 {
16017 pAdapter = pAdapterNode->pAdapter;
16018
16019 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
16020 {
16021 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16022
16023 if(!pHddStaCtx)
16024 {
16025 hddLog(LOGE, FL("HDD STA context is Null"));
16026 return eHAL_STATUS_FAILURE;
16027 }
16028
16029 /* if STA is already connected on DFS channel,
16030 disconnect immediately*/
16031 if (hdd_connIsConnected(pHddStaCtx) &&
16032 (NV_CHANNEL_DFS ==
16033 vos_nv_getChannelEnabledState(
16034 pHddStaCtx->conn_info.operationChannel)))
16035 {
16036 status = sme_RoamDisconnect(pHddCtx->hHal,
16037 pAdapter->sessionId,
16038 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16039 hddLog(LOG1, FL("Client connected on DFS channel %d,"
16040 "sme_RoamDisconnect returned with status: %d"
16041 "for sessionid: %d"), pHddStaCtx->conn_info.
16042 operationChannel, status, pAdapter->sessionId);
16043 }
16044 }
16045
16046 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
16047 &pNext);
16048 pAdapterNode = pNext;
16049 }
16050 }
16051
16052 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
16053 sme_UpdateDFSRoamMode(pHddCtx->hHal,
16054 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
16055
16056 status = sme_HandleDFSChanScan(pHddCtx->hHal);
16057 if (!HAL_STATUS_SUCCESS(status))
16058 {
16059 hddLog(LOGE,
16060 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
16061 return status;
16062 }
16063
16064 return status;
16065}
16066
Nirav Shah7e3c8132015-06-22 23:51:42 +053016067static int hdd_log2_ceil(unsigned value)
16068{
16069 /* need to switch to unsigned math so that negative values
16070 * will right-shift towards 0 instead of -1
16071 */
16072 unsigned tmp = value;
16073 int log2 = -1;
16074
16075 if (value == 0)
16076 return 0;
16077
16078 while (tmp) {
16079 log2++;
16080 tmp >>= 1;
16081 }
16082 if (1U << log2 != value)
16083 log2++;
16084
16085 return log2;
16086}
16087
16088/**
16089 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
16090 * @pAdapter: adapter handle
16091 *
16092 * Return: vos status
16093 */
16094VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
16095{
16096 int hash_elem, log2, i;
16097
16098 spin_lock_bh( &pAdapter->sta_hash_lock);
16099 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
16100 spin_unlock_bh( &pAdapter->sta_hash_lock);
16101 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16102 "%s: hash already attached for session id %d",
16103 __func__, pAdapter->sessionId);
16104 return VOS_STATUS_SUCCESS;
16105 }
16106 spin_unlock_bh( &pAdapter->sta_hash_lock);
16107
16108 hash_elem = WLAN_MAX_STA_COUNT;
16109 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
16110 log2 = hdd_log2_ceil(hash_elem);
16111 hash_elem = 1 << log2;
16112
16113 pAdapter->sta_id_hash.mask = hash_elem - 1;
16114 pAdapter->sta_id_hash.idx_bits = log2;
16115 pAdapter->sta_id_hash.bins =
16116 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
16117 if (!pAdapter->sta_id_hash.bins) {
16118 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16119 "%s: malloc failed for session %d",
16120 __func__, pAdapter->sessionId);
16121 return VOS_STATUS_E_NOMEM;
16122 }
16123
16124 for (i = 0; i < hash_elem; i++)
16125 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
16126
16127 spin_lock_bh( &pAdapter->sta_hash_lock);
16128 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
16129 spin_unlock_bh( &pAdapter->sta_hash_lock);
16130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16131 "%s: Station ID Hash attached for session id %d",
16132 __func__, pAdapter->sessionId);
16133
16134 return VOS_STATUS_SUCCESS;
16135}
16136
16137/**
16138 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
16139 * @pAdapter: adapter handle
16140 *
16141 * Return: vos status
16142 */
16143VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
16144{
16145 int hash_elem, i;
16146 v_SIZE_t size;
16147
16148 spin_lock_bh( &pAdapter->sta_hash_lock);
16149 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16150 spin_unlock_bh( &pAdapter->sta_hash_lock);
16151 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16152 "%s: hash not initialized for session id %d",
16153 __func__, pAdapter->sessionId);
16154 return VOS_STATUS_SUCCESS;
16155 }
16156
16157 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
16158 spin_unlock_bh( &pAdapter->sta_hash_lock);
16159
16160 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
16161
16162 /* free all station info*/
16163 for (i = 0; i < hash_elem; i++) {
16164 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
16165 if (size != 0) {
16166 VOS_STATUS status;
16167 hdd_staid_hash_node_t *sta_info_node = NULL;
16168 hdd_staid_hash_node_t *next_node = NULL;
16169 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
16170 (hdd_list_node_t**) &sta_info_node );
16171
16172 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16173 {
16174 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
16175 &sta_info_node->node);
16176 vos_mem_free(sta_info_node);
16177
16178 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
16179 (hdd_list_node_t*)sta_info_node,
16180 (hdd_list_node_t**)&next_node);
16181 sta_info_node = next_node;
16182 }
16183 }
16184 }
16185
16186 vos_mem_free(pAdapter->sta_id_hash.bins);
16187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16188 "%s: Station ID Hash detached for session id %d",
16189 __func__, pAdapter->sessionId);
16190 return VOS_STATUS_SUCCESS;
16191}
16192
16193/**
16194 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
16195 * @pAdapter: adapter handle
16196 * @mac_addr_in: input mac address
16197 *
16198 * Return: index derived from mac address
16199 */
16200int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
16201 v_MACADDR_t *mac_addr_in)
16202{
16203 uint16 index;
16204 struct hdd_align_mac_addr_t * mac_addr =
16205 (struct hdd_align_mac_addr_t *)mac_addr_in;
16206
16207 index = mac_addr->bytes_ab ^
16208 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
16209 index ^= index >> pAdapter->sta_id_hash.idx_bits;
16210 index &= pAdapter->sta_id_hash.mask;
16211 return index;
16212}
16213
16214/**
16215 * hdd_sta_id_hash_add_entry() - add entry in hash
16216 * @pAdapter: adapter handle
16217 * @sta_id: station id
16218 * @mac_addr: mac address
16219 *
16220 * Return: vos status
16221 */
16222VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
16223 v_U8_t sta_id, v_MACADDR_t *mac_addr)
16224{
16225 uint16 index;
16226 hdd_staid_hash_node_t *sta_info_node = NULL;
16227
Nirav Shah7e3c8132015-06-22 23:51:42 +053016228 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
16229 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
16230 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053016231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16232 "%s: malloc failed", __func__);
16233 return VOS_STATUS_E_NOMEM;
16234 }
16235
16236 sta_info_node->sta_id = sta_id;
16237 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
16238
Nirav Shah303ed5c2015-08-24 10:29:25 +053016239 spin_lock_bh( &pAdapter->sta_hash_lock);
16240 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16241 spin_unlock_bh( &pAdapter->sta_hash_lock);
16242 vos_mem_free(sta_info_node);
16243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16244 "%s: hash is not initialized for session id %d",
16245 __func__, pAdapter->sessionId);
16246 return VOS_STATUS_E_FAILURE;
16247 }
16248
Nirav Shah7e3c8132015-06-22 23:51:42 +053016249 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
16250 (hdd_list_node_t*) sta_info_node );
16251 spin_unlock_bh( &pAdapter->sta_hash_lock);
16252 return VOS_STATUS_SUCCESS;
16253}
16254
16255/**
16256 * hdd_sta_id_hash_remove_entry() - remove entry from hash
16257 * @pAdapter: adapter handle
16258 * @sta_id: station id
16259 * @mac_addr: mac address
16260 *
16261 * Return: vos status
16262 */
16263VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
16264 v_U8_t sta_id, v_MACADDR_t *mac_addr)
16265{
16266 uint16 index;
16267 VOS_STATUS status;
16268 hdd_staid_hash_node_t *sta_info_node = NULL;
16269 hdd_staid_hash_node_t *next_node = NULL;
16270
16271 spin_lock_bh( &pAdapter->sta_hash_lock);
16272 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16273 spin_unlock_bh( &pAdapter->sta_hash_lock);
16274 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16275 "%s: hash is not initialized for session id %d",
16276 __func__, pAdapter->sessionId);
16277 return VOS_STATUS_E_FAILURE;
16278 }
16279
16280 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
16281 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
16282 (hdd_list_node_t**) &sta_info_node );
16283
16284 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16285 {
16286 if (sta_info_node->sta_id == sta_id) {
16287 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
16288 &sta_info_node->node);
16289 vos_mem_free(sta_info_node);
16290 break;
16291 }
16292 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
16293 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
16294 sta_info_node = next_node;
16295 }
16296 spin_unlock_bh( &pAdapter->sta_hash_lock);
16297 return status;
16298}
16299
16300/**
16301 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
16302 * @pAdapter: adapter handle
16303 * @mac_addr_in: mac address
16304 *
16305 * Return: station id
16306 */
16307int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
16308 v_MACADDR_t *mac_addr_in)
16309{
16310 uint8 is_found = 0;
16311 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
16312 uint16 index;
16313 VOS_STATUS status;
16314 hdd_staid_hash_node_t *sta_info_node = NULL;
16315 hdd_staid_hash_node_t *next_node = NULL;
16316
16317 spin_lock_bh( &pAdapter->sta_hash_lock);
16318 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16319 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053016320 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053016321 FL("hash is not initialized for session id %d"),
16322 pAdapter->sessionId);
16323 return HDD_WLAN_INVALID_STA_ID;
16324 }
16325
16326 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
16327 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
16328 (hdd_list_node_t**) &sta_info_node );
16329
16330 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16331 {
16332 if (vos_mem_compare(&sta_info_node->mac_addr,
16333 mac_addr_in, sizeof(v_MACADDR_t))) {
16334 is_found = 1;
16335 sta_id = sta_info_node->sta_id;
16336 break;
16337 }
16338 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
16339 (hdd_list_node_t*)sta_info_node,
16340 (hdd_list_node_t**)&next_node);
16341 sta_info_node = next_node;
16342 }
16343 spin_unlock_bh( &pAdapter->sta_hash_lock);
16344 return sta_id;
16345}
16346
c_manjeecfd1efb2015-09-25 19:32:34 +053016347/*FW memory dump feature*/
16348/**
16349 * This structure hold information about the /proc file
16350 *
16351 */
16352static struct proc_dir_entry *proc_file, *proc_dir;
16353
16354/**
16355 * memdump_read() - perform read operation in memory dump proc file
16356 *
16357 * @file - handle for the proc file.
16358 * @buf - pointer to user space buffer.
16359 * @count - number of bytes to be read.
16360 * @pos - offset in the from buffer.
16361 *
16362 * This function performs read operation for the memory dump proc file.
16363 *
16364 * Return: number of bytes read on success, error code otherwise.
16365 */
16366static ssize_t memdump_read(struct file *file, char __user *buf,
16367 size_t count, loff_t *pos)
16368{
16369 int status;
16370 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
16371 size_t ret_count;
c_manjeef1495642015-10-13 18:35:01 +053016372 loff_t bytes_left;
c_manjeecfd1efb2015-09-25 19:32:34 +053016373 ENTER();
16374
16375 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
16376 status = wlan_hdd_validate_context(hdd_ctx);
16377 if (0 != status) {
16378 return -EINVAL;
16379 }
16380
16381 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
16382 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
16383 return -EINVAL;
16384 }
16385
16386 /* run fs_read_handler in an atomic context*/
16387 vos_ssr_protect(__func__);
c_manjeef1495642015-10-13 18:35:01 +053016388 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left);
16389 if(bytes_left == 0)
c_manjeecfd1efb2015-09-25 19:32:34 +053016390 {
16391 /*Free the fwr mem dump buffer */
16392 wlan_free_fwr_mem_dump_buffer();
16393 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeef1495642015-10-13 18:35:01 +053016394 ret_count=0;
c_manjeecfd1efb2015-09-25 19:32:34 +053016395 }
16396 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
16397 vos_ssr_unprotect(__func__);
16398 EXIT();
16399 return ret_count;
16400}
16401
16402/**
16403 * struct memdump_fops - file operations for memory dump feature
16404 * @read - read function for memory dump operation.
16405 *
16406 * This structure initialize the file operation handle for memory
16407 * dump feature
16408 */
16409static const struct file_operations memdump_fops = {
16410 read: memdump_read
16411};
16412
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016413struct fw_mem_dump_priv {
16414 uint32_t status;
16415};
16416
c_manjeecfd1efb2015-09-25 19:32:34 +053016417/*
16418* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
16419* To be passed by HDD to WDA and called upon receiving of response
16420* from firmware
16421* @fwMemDumpReqContext : memory dump request context
16422* @dump_rsp : dump response from HAL
16423* Returns none
16424*/
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016425void wlan_hdd_fw_mem_dump_cb(void *context,
c_manjeecfd1efb2015-09-25 19:32:34 +053016426 tAniFwrDumpRsp *dump_rsp)
16427{
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016428 struct hdd_request *request;
16429 struct fw_mem_dump_priv *priv;
c_manjeecfd1efb2015-09-25 19:32:34 +053016430
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016431 request = hdd_request_get(context);
16432 if (!request) {
16433 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
16434 return;
16435 }
c_manjeecfd1efb2015-09-25 19:32:34 +053016436
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016437 ENTER();
16438
16439 priv = hdd_request_priv(request);
16440 priv->status = dump_rsp->dump_status;
16441
16442 /* report the status to requesting function and free mem.*/
16443 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
16444 hddLog(LOGE, FL("fw dump request declined by fwr"));
16445 //set the request completion variable
16446 hdd_request_complete(request);
16447 //Free the allocated fwr dump
16448 wlan_free_fwr_mem_dump_buffer();
16449 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
16450 } else {
16451 hddLog(LOG1, FL("fw dump request accepted by fwr"));
16452 /* register the HDD callback which will be called by SVC */
16453 wlan_set_svc_fw_mem_dump_req_cb(
16454 (void*)wlan_hdd_fw_mem_dump_req_cb,
16455 context);
16456 }
16457
16458 hdd_request_put(request);
16459
16460 EXIT();
c_manjeecfd1efb2015-09-25 19:32:34 +053016461}
16462
16463/**
16464 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
16465 *
16466 * This function removes file/dir under proc file system that was
16467 * processing firmware memory dump
16468 *
16469 * Return: None
16470 */
16471static void memdump_procfs_remove(void)
16472{
16473 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
16474 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
16475 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
16476 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
16477 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
16478}
16479
16480/**
16481 * memdump_procfs_init() - Initialize procfs for memory dump
16482 *
16483 * @vos_ctx - Global vos context.
16484 *
16485 * This function create file under proc file system to be used later for
16486 * processing firmware memory dump
16487 *
16488 * Return: 0 on success, error code otherwise.
16489 */
16490static int memdump_procfs_init(void *vos_ctx)
16491{
16492 hdd_context_t *hdd_ctx;
16493
16494 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16495 if (!hdd_ctx) {
16496 hddLog(LOGE , FL("Invalid HDD context"));
16497 return -EINVAL;
16498 }
16499
16500 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
16501 if (proc_dir == NULL) {
16502 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
16503 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
16504 PROCFS_MEMDUMP_DIR);
16505 return -ENOMEM;
16506 }
16507
16508 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
16509 S_IRUSR | S_IWUSR, proc_dir,
16510 &memdump_fops, hdd_ctx);
16511 if (proc_file == NULL) {
16512 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
16513 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
16514 PROCFS_MEMDUMP_NAME);
16515 return -ENOMEM;
16516 }
16517
16518 hddLog(LOG1 , FL("/proc/%s/%s created"),
16519 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
16520
16521 return 0;
16522}
16523
16524/**
16525 * memdump_init() - Initialization function for memory dump feature
16526 *
16527 * This function creates proc file for memdump feature and registers
16528 * HDD callback function with SME.
16529 *
16530 * Return - 0 on success, error otherwise
16531 */
16532int memdump_init(void)
16533{
16534 hdd_context_t *hdd_ctx;
16535 void *vos_ctx;
16536 int status = 0;
16537
16538 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
16539 if (!vos_ctx) {
16540 hddLog(LOGE, FL("Invalid VOS context"));
16541 return -EINVAL;
16542 }
16543
16544 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16545 if (!hdd_ctx) {
16546 hddLog(LOGE , FL("Invalid HDD context"));
16547 return -EINVAL;
16548 }
16549
16550 status = memdump_procfs_init(vos_ctx);
16551 if (status) {
16552 hddLog(LOGE , FL("Failed to create proc file"));
16553 return status;
16554 }
16555
16556 return 0;
16557}
16558
16559/**
16560 * memdump_deinit() - De initialize memdump feature
16561 *
16562 * This function removes proc file created for memdump feature.
16563 *
16564 * Return: None
16565 */
16566int memdump_deinit(void)
16567{
16568 hdd_context_t *hdd_ctx;
16569 void *vos_ctx;
16570
16571 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
16572 if (!vos_ctx) {
16573 hddLog(LOGE, FL("Invalid VOS context"));
16574 return -EINVAL;
16575 }
16576
16577 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16578 if(!hdd_ctx) {
16579 hddLog(LOGE , FL("Invalid HDD context"));
16580 return -EINVAL;
16581 }
16582
16583 memdump_procfs_remove();
16584 return 0;
16585}
16586
16587/**
16588 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
16589 * Return: HAL status
16590 */
16591
16592int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
16593{
16594 tAniFwrDumpReq fw_mem_dump_req={0};
16595 eHalStatus status = eHAL_STATUS_FAILURE;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016596 int ret=0, dump_status;
16597 void *cookie;
16598 struct hdd_request *request;
16599 struct fw_mem_dump_priv *priv;
16600 static const struct hdd_request_params params = {
16601 .priv_size = sizeof(*priv),
16602 .timeout_ms = FW_MEM_DUMP_TIMEOUT_MS,
16603 };
16604
c_manjeecfd1efb2015-09-25 19:32:34 +053016605 ENTER();
c_manjeef1495642015-10-13 18:35:01 +053016606
c_manjeecfd1efb2015-09-25 19:32:34 +053016607 /*Check whether a dump request is already going on
16608 *Caution this function will free previously held memory if new dump request is allowed*/
16609 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
16610 hddLog(LOGE, FL("Fw memdump already in progress"));
16611 return -EBUSY;
16612 }
16613 //Allocate memory for fw mem dump buffer
16614 ret = wlan_fwr_mem_dump_buffer_allocation();
16615 if(ret == -EFAULT)
16616 {
16617 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
16618 return ret;
16619 }
16620 if (0 != ret) {
16621 hddLog(LOGE, FL("Fwr mem Allocation failed"));
16622 return -ENOMEM;
16623 }
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016624
16625 request = hdd_request_alloc(&params);
16626 if (!request) {
16627 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
16628 return VOS_STATUS_E_NOMEM;
16629 }
16630 cookie = hdd_request_cookie(request);
c_manjeef1495642015-10-13 18:35:01 +053016631
c_manjeecfd1efb2015-09-25 19:32:34 +053016632 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016633 fw_mem_dump_req.fwMemDumpReqContext = cookie;
c_manjeecfd1efb2015-09-25 19:32:34 +053016634 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
16635 if(eHAL_STATUS_SUCCESS != status)
16636 {
16637 hddLog(VOS_TRACE_LEVEL_ERROR,
16638 "%s: fw_mem_dump_req failed ", __func__);
16639 wlan_free_fwr_mem_dump_buffer();
c_manjeef1495642015-10-13 18:35:01 +053016640 ret = -EFAULT;
16641 goto cleanup;
c_manjeecfd1efb2015-09-25 19:32:34 +053016642 }
c_manjeef1495642015-10-13 18:35:01 +053016643 /*wait for fw mem dump completion to send event to userspace*/
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016644 ret = hdd_request_wait_for_response(request);
16645 if (ret)
c_manjeef1495642015-10-13 18:35:01 +053016646 {
16647 hddLog(VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016648 "%s: fw_mem_dump_req timeout %d ", __func__,ret);
Abhishek Singh4eca9822015-12-09 18:07:34 +053016649 ret = -ETIMEDOUT;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016650 }else {
16651 priv = hdd_request_priv(request);
16652 dump_status = priv->status;
c_manjeef1495642015-10-13 18:35:01 +053016653 }
16654cleanup:
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016655 hdd_request_put(request);
16656 if(!ret && !dump_status)
Abhishek Singh4eca9822015-12-09 18:07:34 +053016657 ret = -EFAULT;
c_manjeecfd1efb2015-09-25 19:32:34 +053016658
c_manjeef1495642015-10-13 18:35:01 +053016659 EXIT();
Abhishek Singh4eca9822015-12-09 18:07:34 +053016660 return ret;
c_manjeef1495642015-10-13 18:35:01 +053016661}
16662
16663/**
16664 * HDD callback which will be called by SVC to indicate mem dump completion.
16665 */
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016666void wlan_hdd_fw_mem_dump_req_cb(void *context)
c_manjeef1495642015-10-13 18:35:01 +053016667{
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016668 struct hdd_request *request;
16669 struct fw_mem_dump_priv *priv;
16670
16671 request = hdd_request_get(context);
16672 if (!request) {
16673 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
16674 return;
16675 }
16676
16677 priv = hdd_request_priv(request);
16678 priv->status = true;
16679
16680 hdd_request_complete(request);
16681 hdd_request_put(request);
c_manjeecfd1efb2015-09-25 19:32:34 +053016682}
16683
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053016684void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
16685{
16686 if (NULL == pAdapter)
16687 {
16688 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
16689 return;
16690 }
16691 init_completion(&pAdapter->session_open_comp_var);
16692 init_completion(&pAdapter->session_close_comp_var);
16693 init_completion(&pAdapter->disconnect_comp_var);
16694 init_completion(&pAdapter->linkup_event_var);
16695 init_completion(&pAdapter->cancel_rem_on_chan_var);
16696 init_completion(&pAdapter->rem_on_chan_ready_event);
16697 init_completion(&pAdapter->pno_comp_var);
16698#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16699 init_completion(&pAdapter->offchannel_tx_event);
16700#endif
16701 init_completion(&pAdapter->tx_action_cnf_event);
16702#ifdef FEATURE_WLAN_TDLS
16703 init_completion(&pAdapter->tdls_add_station_comp);
16704 init_completion(&pAdapter->tdls_del_station_comp);
16705 init_completion(&pAdapter->tdls_mgmt_comp);
16706 init_completion(&pAdapter->tdls_link_establish_req_comp);
16707#endif
16708
16709#ifdef WLAN_FEATURE_RMC
16710 init_completion(&pAdapter->ibss_peer_info_comp);
16711#endif /* WLAN_FEATURE_RMC */
16712 init_completion(&pAdapter->ula_complete);
16713 init_completion(&pAdapter->change_country_code);
16714
16715#ifdef FEATURE_WLAN_BATCH_SCAN
16716 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
16717 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
16718#endif
Kapil Gupta2b44acb2016-12-30 16:49:51 +053016719 init_completion(&pAdapter->wlan_suspend_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053016720
16721 return;
16722}
c_manjeecfd1efb2015-09-25 19:32:34 +053016723
Anurag Chouhan0b29de02016-12-16 13:18:40 +053016724#ifdef MDNS_OFFLOAD
16725
16726/**
16727 * hdd_mdns_enable_offload_done() - mdns enable offload response api
16728 * @padapter: holds adapter
16729 * @status: response status
16730 *
16731 * Return - None
16732 */
16733void hdd_mdns_enable_offload_done(void *padapter, VOS_STATUS status)
16734{
16735 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16736
16737 ENTER();
16738
16739 if (NULL == adapter)
16740 {
16741 hddLog(VOS_TRACE_LEVEL_ERROR,
16742 "%s: adapter is NULL",__func__);
16743 return;
16744 }
16745
16746 adapter->mdns_status.mdns_enable_status = status;
16747 vos_event_set(&adapter->mdns_status.vos_event);
16748 return;
16749}
16750
16751/**
16752 * hdd_mdns_fqdn_offload_done() - mdns fqdn offload response api
16753 * @padapter: holds adapter
16754 * @status: responce status
16755 *
16756 * Return - None
16757 */
16758void hdd_mdns_fqdn_offload_done(void *padapter, VOS_STATUS status)
16759{
16760 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16761
16762 ENTER();
16763
16764 if (NULL == adapter)
16765 {
16766 hddLog(VOS_TRACE_LEVEL_ERROR,
16767 "%s: adapter is NULL",__func__);
16768 return;
16769 }
16770
16771 adapter->mdns_status.mdns_fqdn_status = status;
16772 return;
16773}
16774
16775/**
16776 * hdd_mdns_resp_offload_done() - mdns resp offload response api
16777 * @padapter: holds adapter
16778 * @status: responce status
16779 *
16780 * Return - None
16781 */
16782void hdd_mdns_resp_offload_done(void *padapter, VOS_STATUS status)
16783{
16784 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16785
16786 ENTER();
16787
16788 if (NULL == adapter)
16789 {
16790 hddLog(VOS_TRACE_LEVEL_ERROR,
16791 "%s: adapter is NULL",__func__);
16792 return;
16793 }
16794
16795 adapter->mdns_status.mdns_resp_status = status;
16796 return;
16797}
16798
16799/**
16800 * wlan_hdd_mdns_process_response_dname() - Process mDNS domain name
16801 * @response: Pointer to a struct hdd_mdns_resp_info
16802 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16803 *
16804 * This function will pack the whole domain name without compression. It will
16805 * add the leading len for each field and add zero length octet to terminate
16806 * the domain name.
16807 *
16808 * Return: Return boolean. TRUE for success, FALSE for fail.
16809 */
16810static bool
16811wlan_hdd_mdns_process_response_dname(struct hdd_mdns_resp_info *response,
16812 sir_mdns_resp_info resp_info)
16813{
16814 uint8_t num;
16815 uint16_t idx;
16816 uint8_t len = 0;
16817
16818 if ((response == NULL) || (response->data == NULL) ||
16819 (response->offset == NULL)) {
16820 hddLog(LOGE, FL("Either data or offset in response is NULL!"));
16821 return FALSE;
16822 }
16823
16824 if ((resp_info == NULL) ||
16825 (resp_info->resp_len >= MAX_MDNS_RESP_LEN)) {
16826 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16827 return FALSE;
16828 }
16829
16830 for (num = 0; num < response->num_entries; num++) {
16831 response->offset[num] =
16832 resp_info->resp_len + MDNS_HEADER_LEN;
16833 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16834 len = strlen((char *)&response->data[idx]);
16835 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
16836 hddLog(LOGE, FL("resp_len exceeds %d!"),
16837 MAX_MDNS_RESP_LEN);
16838 return FALSE;
16839 }
16840 resp_info->resp_data[resp_info->resp_len] = len;
16841 resp_info->resp_len++;
16842 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
16843 &response->data[idx], len);
16844 resp_info->resp_len += len;
16845 }
16846
16847 /* The domain name terminates with the zero length octet */
16848 if (num == response->num_entries) {
16849 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
16850 hddLog(LOGE, FL("resp_len exceeds %d!"),
16851 MAX_MDNS_RESP_LEN);
16852 return FALSE;
16853 }
16854 resp_info->resp_data[resp_info->resp_len] = 0;
16855 resp_info->resp_len++;
16856 }
16857
16858 return TRUE;
16859}
16860
16861/**
16862 * wlan_hdd_mdns_format_response_u16() - Form uint16_t response data
16863 * @value: The uint16_t value is formed to the struct tSirMDNSResponseInfo
16864 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16865 *
16866 * Return: None
16867 */
16868static void wlan_hdd_mdns_format_response_u16(uint16_t value,
16869 sir_mdns_resp_info resp_info)
16870{
16871 uint8_t val_u8;
16872
16873 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
16874 return;
16875 val_u8 = (value & 0xff00) >> 8;
16876 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16877 val_u8 = value & 0xff;
16878 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16879}
16880
16881/**
16882 * wlan_hdd_mdns_format_response_u32() - Form uint32_t response data
16883 * @value: The uint32_t value is formed to the struct tSirMDNSResponseInfo
16884 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16885 *
16886 * Return: None
16887 */
16888static void wlan_hdd_mdns_format_response_u32(uint32_t value,
16889 sir_mdns_resp_info resp_info)
16890{
16891 uint8_t val_u8;
16892
16893 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
16894 return;
16895 val_u8 = (value & 0xff000000) >> 24;
16896 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16897 val_u8 = (value & 0xff0000) >> 16;
16898 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16899 val_u8 = (value & 0xff00) >> 8;
16900 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16901 val_u8 = value & 0xff;
16902 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16903}
16904
16905/**
16906 * wlan_hdd_mdns_process_response_misc() - Process misc info in mDNS response
16907 * @resp_type: Response type for mDNS
16908 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16909 *
16910 * This function will pack the response type, class and TTL (Time To Live).
16911 *
16912 * Return: Return boolean. TRUE for success, FALSE for fail.
16913 */
16914static bool wlan_hdd_mdns_process_response_misc(uint16_t resp_type,
16915 sir_mdns_resp_info resp_info)
16916{
16917 uint16_t len;
16918
16919 if (resp_info == NULL) {
16920 hddLog(LOGE, FL("resp_info is NULL!"));
16921 return FALSE;
16922 }
16923
16924 len = resp_info->resp_len + (2 * sizeof(uint16_t) + sizeof(uint32_t));
16925 if (len >= MAX_MDNS_RESP_LEN) {
16926 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16927 return FALSE;
16928 }
16929
16930 /* Fill Type, Class, TTL */
16931 wlan_hdd_mdns_format_response_u16(resp_type, resp_info);
16932 wlan_hdd_mdns_format_response_u16(MDNS_CLASS, resp_info);
16933 wlan_hdd_mdns_format_response_u32(MDNS_TTL, resp_info);
16934
16935 return TRUE;
16936}
16937
16938/**
16939 * wlan_hdd_mdns_compress_data() - Compress the domain name in mDNS response
16940 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16941 * @response_dst: The response which domain name is compressed.
16942 * @response_src: The response which domain name is matched with response_dst.
16943 * Its offset is used for data compression.
16944 * @num_matched: The number of matched entries between response_dst and
16945 * response_src
16946 *
16947 * This function will form the different fields of domain name in response_dst
16948 * if any. Then use the offset of the matched domain name in response_src to
16949 * compress the matched domain name.
16950 *
16951 * Return: Return boolean. TRUE for success, FALSE for fail.
16952 */
16953static bool
16954wlan_hdd_mdns_compress_data(sir_mdns_resp_info resp_info,
16955 struct hdd_mdns_resp_info *response_dst,
16956 struct hdd_mdns_resp_info *response_src,
16957 uint8_t num_matched)
16958{
16959 uint8_t num, num_diff;
16960 uint16_t value, idx;
16961 uint8_t len = 0;
16962
16963 if ((response_src == NULL) || (response_dst == NULL) ||
16964 (resp_info == NULL)) {
16965 hddLog(LOGE, FL("response info is NULL!"));
16966 return FALSE;
16967 }
16968
16969 if (response_dst->num_entries < num_matched) {
16970 hddLog(LOGE, FL("num_entries is less than num_matched!"));
16971 return FALSE;
16972 }
16973
16974 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
16975 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16976 return FALSE;
16977 }
16978
16979 num_diff = response_dst->num_entries - num_matched;
16980 if ((num_diff > 0) && (response_dst->data == NULL)) {
16981 hddLog(LOGE, FL("response_dst->data is NULL!"));
16982 return FALSE;
16983 }
16984
16985 /*
16986 * Handle the unmatched string at the beginning
16987 * Store the length of octets and the octets
16988 */
16989 for (num = 0; num < num_diff; num++) {
16990 response_dst->offset[num] =
16991 resp_info->resp_len + MDNS_HEADER_LEN;
16992 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16993 len = strlen((char *)&response_dst->data[idx]);
16994 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
16995 hddLog(LOGE, FL("resp_len exceeds %d!"),
16996 MAX_MDNS_RESP_LEN);
16997 return FALSE;
16998 }
16999 resp_info->resp_data[resp_info->resp_len] = len;
17000 resp_info->resp_len++;
17001 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
17002 &response_dst->data[idx], len);
17003 resp_info->resp_len += len;
17004 }
17005 /*
17006 * Handle the matched string from the end
17007 * Just keep the offset and mask the leading two bit
17008 */
17009 if (response_src->num_entries >= num_matched) {
17010 num_diff = response_src->num_entries - num_matched;
17011 value = response_src->offset[num_diff];
17012 if (value > 0) {
17013 value |= 0xc000;
17014 if ((resp_info->resp_len + sizeof(uint16_t)) >=
17015 MAX_MDNS_RESP_LEN) {
17016 hddLog(LOGE, FL("resp_len exceeds %d!"),
17017 MAX_MDNS_RESP_LEN);
17018 return FALSE;
17019 }
17020 wlan_hdd_mdns_format_response_u16(value, resp_info);
17021 return TRUE;
17022 }
17023 }
17024 return FALSE;
17025}
17026
17027/**
17028 * wlan_hdd_mdns_reset_response() - Reset the response info
17029 * @response: The response which info is reset.
17030 *
17031 * Return: None
17032 */
17033static void wlan_hdd_mdns_reset_response(struct hdd_mdns_resp_info *response)
17034{
17035 if (response == NULL)
17036 return;
17037 response->num_entries = 0;
17038 response->data = NULL;
17039 response->offset = NULL;
17040}
17041
17042/**
17043 * wlan_hdd_mdns_init_response() - Initialize the response info
17044 * @response: The response which info is initiatized.
17045 * @resp_dname: The domain name string which might be tokenized.
17046 *
17047 * This function will allocate the memory for both response->data and
17048 * response->offset. Besides, it will also tokenize the domain name to some
17049 * entries and fill response->num_entries with the num of entries.
17050 *
17051 * Return: Return boolean. TRUE for success, FALSE for fail.
17052 */
17053static bool wlan_hdd_mdns_init_response(struct hdd_mdns_resp_info *response,
17054 uint8_t *resp_dname, char separator)
17055{
17056 uint16_t size;
17057
17058 if ((resp_dname == NULL) || (response == NULL)) {
17059 hddLog(LOGE, FL("resp_dname or response is NULL!"));
17060 return FALSE;
17061 }
17062
17063 size = MAX_NUM_FIELD_DOMAINNAME * MAX_LEN_DOMAINNAME_FIELD;
17064 response->data = vos_mem_malloc(size);
17065 if (response->data) {
17066 vos_mem_zero(response->data, size);
17067 if (VOS_STATUS_SUCCESS !=
17068 hdd_string_to_string_array((char *)resp_dname,
17069 response->data,
17070 separator,
17071 &response->num_entries,
17072 MAX_NUM_FIELD_DOMAINNAME,
17073 MAX_LEN_DOMAINNAME_FIELD)) {
17074 hddLog(LOGE, FL("hdd_string_to_string_array fail!"));
17075 goto err_init_resp;
17076 }
17077
17078 if ((response->num_entries > 0) &&
17079 (strlen((char *)&response->data[0]) > 0)) {
17080 size = sizeof(uint16_t) * response->num_entries;
17081 response->offset = vos_mem_malloc(size);
17082 if (response->offset) {
17083 vos_mem_zero(response->offset, size);
17084 return TRUE;
17085 }
17086 }
17087 }
17088
17089err_init_resp:
17090 if (response->data)
17091 vos_mem_free(response->data);
17092 wlan_hdd_mdns_reset_response(response);
17093 return FALSE;
17094}
17095
17096/**
17097 * wlan_hdd_mdns_find_entries_from_end() - Find the matched entries
17098 * @response1: The response info is used to be compared.
17099 * @response2: The response info is used to be compared.
17100 *
17101 * This function will find the matched entries from the end.
17102 *
17103 * Return: Return the number of the matched entries.
17104 */
17105static uint8_t
17106wlan_hdd_mdns_find_entries_from_end(struct hdd_mdns_resp_info *response1,
17107 struct hdd_mdns_resp_info *response2)
17108{
17109 uint8_t min, len1, i;
17110 uint16_t num1, num2;
17111 uint8_t num_matched = 0;
17112
17113 min = VOS_MIN(response1->num_entries, response2->num_entries);
17114
17115 for (i = 1; i <= min; i++) {
17116 num1 = (response1->num_entries - i);
17117 num1 *= MAX_LEN_DOMAINNAME_FIELD;
17118 num2 = (response2->num_entries - i);
17119 num2 *= MAX_LEN_DOMAINNAME_FIELD;
17120 len1 = strlen((char *)&response1->data[num1]);
17121
17122 if ((len1 == 0) ||
17123 (len1 != strlen((char *)&response2->data[num2])))
17124 break;
17125 if (memcmp(&response1->data[num1],
17126 &response2->data[num2], len1))
17127 break;
17128 else
17129 num_matched++;
17130 }
17131
17132 return num_matched;
17133}
17134
17135/**
17136 * wlan_hdd_mdns_find_max() - Find the maximum number of the matched entries
17137 * @matchedlist: Pointer to the array of struct hdd_mdns_resp_matched
17138 * @numlist: The number of the elements in the array matchedlist.
17139 *
17140 * Find the max number of the matched entries among the array matchedlist.
17141 *
17142 * Return: None
17143 */
17144static void wlan_hdd_mdns_find_max(struct hdd_mdns_resp_matched *matchedlist,
17145 uint8_t numlist)
17146{
17147 int j;
17148 struct hdd_mdns_resp_matched tmp;
17149
17150 /* At least two values are used for sorting */
17151 if ((numlist < 2) || (matchedlist == NULL)) {
17152 hddLog(LOGE, FL("At least two values are used for sorting!"));
17153 return;
17154 }
17155
17156 for (j = 0; j < numlist-1; j++) {
17157 if (matchedlist[j].num_matched >
17158 matchedlist[j+1].num_matched) {
17159 vos_mem_copy(&tmp, &matchedlist[j],
17160 sizeof(struct hdd_mdns_resp_matched));
17161 vos_mem_copy(&matchedlist[j], &matchedlist[j+1],
17162 sizeof(struct hdd_mdns_resp_matched));
17163 vos_mem_copy(&matchedlist[j+1], &tmp,
17164 sizeof(struct hdd_mdns_resp_matched));
17165 }
17166 }
17167}
17168
17169/**
17170 * wlan_hdd_mdns_pack_response_type_a() - Pack Type A response
17171 * @ini_config: Pointer to the struct hdd_config_t
17172 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17173 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17174 *
17175 * Type A response include QName, response type, class, TTL and Ipv4.
17176 *
17177 * Return: Return boolean. TRUE for success, FALSE for fail.
17178 */
17179static bool
17180wlan_hdd_mdns_pack_response_type_a(hdd_config_t *ini_config,
17181 sir_mdns_resp_info resp_info,
17182 struct hdd_mdns_resp_info *resptype_a)
17183{
17184 uint16_t value;
17185 uint32_t len;
17186
17187 ENTER();
17188 if ((ini_config == NULL) || (resp_info == NULL) ||
17189 (resptype_a == NULL)) {
17190 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17191 return FALSE;
17192 }
17193
17194 /* No Type A response */
17195 if (strlen((char *)ini_config->mdns_resp_type_a) <= 0)
17196 return TRUE;
17197
17198 /* Wrong response is assigned, just ignore this response */
17199 if (!wlan_hdd_mdns_init_response(resptype_a,
17200 ini_config->mdns_resp_type_a, '.'))
17201 return TRUE;
17202
17203 /* Process response domain name */
17204 if (!wlan_hdd_mdns_process_response_dname(resptype_a, resp_info)) {
17205 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17206 MDNS_TYPE_A);
17207 return FALSE;
17208 }
17209
17210 /* Process response Type, Class, TTL */
17211 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_A, resp_info)) {
17212 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17213 MDNS_TYPE_A);
17214 return FALSE;
17215 }
17216
17217 /* Process response RDLength, RData */
17218 len = sizeof(uint16_t) + sizeof(uint32_t);
17219 len += resp_info->resp_len;
17220 if (len >= MAX_MDNS_RESP_LEN) {
17221 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17222 return FALSE;
17223 }
17224 value = sizeof(uint32_t);
17225 wlan_hdd_mdns_format_response_u16(value, resp_info);
17226 wlan_hdd_mdns_format_response_u32(ini_config->mdns_resp_type_a_ipv4,
17227 resp_info);
17228
17229 EXIT();
17230 return TRUE;
17231}
17232
17233/**
17234 * wlan_hdd_mdns_pack_response_type_txt() - Pack Type Txt response
17235 * @ini_config: Pointer to the struct hdd_config_t
17236 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17237 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type txt
17238 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17239 *
17240 * Type Txt response include QName, response type, class, TTL and text content.
17241 * Also, it will find the matched QName from resptype_A and compress the data.
17242 *
17243 * Return: Return boolean. TRUE for success, FALSE for fail.
17244 */
17245static bool
17246wlan_hdd_mdns_pack_response_type_txt(hdd_config_t *ini_config,
17247 sir_mdns_resp_info resp_info,
17248 struct hdd_mdns_resp_info *resptype_txt,
17249 struct hdd_mdns_resp_info *resptype_a)
17250{
17251 uint8_t num_matched;
17252 uint8_t num;
17253 uint16_t idx;
17254 uint16_t value = 0;
17255 uint32_t len;
17256 uint32_t total_len;
17257 bool status;
17258 struct hdd_mdns_resp_info resptype_content;
17259
17260 ENTER();
17261
17262 if ((ini_config == NULL) || (resp_info == NULL) ||
17263 (resptype_txt == NULL)) {
17264 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17265 return FALSE;
17266 }
17267
17268 /* No Type Txt response */
17269 if (strlen((char *)ini_config->mdns_resp_type_txt) <= 0)
17270 return TRUE;
17271
17272 /* Wrong response is assigned, just ignore this response */
17273 if (!wlan_hdd_mdns_init_response(resptype_txt,
17274 ini_config->mdns_resp_type_txt, '.'))
17275 return TRUE;
17276
17277 /*
17278 * For data compression
17279 * Check if any strings are matched with Type A response
17280 */
17281 if (resptype_a && (resptype_a->num_entries > 0)) {
17282 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_txt,
17283 resptype_a);
17284 if (num_matched > 0) {
17285 if (!wlan_hdd_mdns_compress_data(resp_info,
17286 resptype_txt, resptype_a, num_matched)) {
17287 hddLog(LOGE, FL("Fail to compress mDNS "
17288 "response (%d)!"), MDNS_TYPE_TXT);
17289 return FALSE;
17290 }
17291 } else {
17292 /*
17293 * num_matched is zero. Error!
17294 * At least ".local" is needed.
17295 */
17296 hddLog(LOGE, FL("No matched string! Fail to pack mDNS "
17297 "response (%d)!"), MDNS_TYPE_TXT);
17298 return FALSE;
17299 }
17300 } else {
17301 /* no TypeA response, so show the whole data */
17302 if (!wlan_hdd_mdns_process_response_dname(resptype_txt,
17303 resp_info)) {
17304 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17305 MDNS_TYPE_TXT);
17306 return FALSE;
17307 }
17308 }
17309
17310 /* Process response Type, Class, TTL */
17311 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_TXT, resp_info)) {
17312 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17313 MDNS_TYPE_TXT);
17314 return FALSE;
17315 }
17316
17317 /*
17318 * Process response RDLength, RData.
17319 * TypeTxt RData include len.
17320 */
17321 status = wlan_hdd_mdns_init_response(&resptype_content,
17322 ini_config->mdns_resp_type_txt_content,
17323 '/');
17324 if (status == FALSE) {
17325 hddLog(LOGE, FL("wlan_hdd_mdns_init_response FAIL"));
17326 return FALSE;
17327 }
17328
17329 for (num = 0; num < resptype_content.num_entries; num++) {
17330 idx = num * MAX_LEN_DOMAINNAME_FIELD;
17331 value += strlen((char *)&resptype_content.data[idx]);
17332 }
17333
17334 /* content len is uint16_t */
17335 total_len = sizeof(uint16_t);
17336 total_len += resp_info->resp_len + value +
17337 resptype_content.num_entries;
17338
17339 if (total_len >= MAX_MDNS_RESP_LEN) {
17340 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17341 return FALSE;
17342 }
17343 wlan_hdd_mdns_format_response_u16(value + resptype_content.num_entries,
17344 resp_info);
17345
17346 for (num = 0; num < resptype_content.num_entries; num++) {
17347 idx = num * MAX_LEN_DOMAINNAME_FIELD;
17348 len = strlen((char *)&resptype_content.data[idx]);
17349 resp_info->resp_data[resp_info->resp_len] = len;
17350 resp_info->resp_len++;
17351
17352 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
17353 &resptype_content.data[idx], len);
17354
17355 resp_info->resp_len += len;
17356 hddLog(LOG1, FL("index = %d, len = %d, str = %s"),
17357 num, len, &resptype_content.data[idx]);
17358 }
17359
17360 EXIT();
17361 return TRUE;
17362}
17363
17364/**
17365 * wlan_hdd_mdns_pack_response_type_ptr_dname() - Pack Type PTR domain name
17366 * @ini_config: Pointer to the struct hdd_config_t
17367 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17368 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17369 * domain name
17370 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17371 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17372 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17373 *
17374 * The Type Ptr response include Type PTR domain name in its data field.
17375 * Also, it will find the matched QName from the existing resptype_ptr,
17376 * resptype_txt, resptype_a and then compress the data.
17377 *
17378 * Return: Return boolean. TRUE for success, FALSE for fail.
17379 */
17380static bool
17381wlan_hdd_mdns_pack_response_type_ptr_dname(hdd_config_t *ini_config,
17382 sir_mdns_resp_info resp_info,
17383 struct hdd_mdns_resp_info *resptype_ptr_dn,
17384 struct hdd_mdns_resp_info *resptype_ptr,
17385 struct hdd_mdns_resp_info *resptype_txt,
17386 struct hdd_mdns_resp_info *resptype_a)
17387{
17388 uint8_t num_matched, numlist, size;
17389 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17390 struct hdd_mdns_resp_info *resp;
17391
17392 if ((ini_config == NULL) || (resp_info == NULL) ||
17393 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
17394 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17395 return FALSE;
17396 }
17397
17398 /* No Type Ptr domain name response */
17399 if (strlen((char *)ini_config->mdns_resp_type_ptr_dname) <= 0)
17400 return TRUE;
17401
17402 /* Wrong response is assigned, just ignore this response */
17403 if (!wlan_hdd_mdns_init_response(resptype_ptr_dn,
17404 ini_config->mdns_resp_type_ptr_dname, '.'))
17405 return TRUE;
17406
17407 /*
17408 * For data compression
17409 * Check if any strings are matched with previous
17410 * response.
17411 */
17412 numlist = 0;
17413 size = (MAX_MDNS_RESP_TYPE-1);
17414 size *= sizeof(struct hdd_mdns_resp_matched);
17415 vos_mem_zero(matchedlist, size);
17416 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr_dn,
17417 resptype_ptr);
17418 if (num_matched > 0) {
17419 matchedlist[numlist].num_matched = num_matched;
17420 matchedlist[numlist].type = MDNS_TYPE_PTR;
17421 numlist++;
17422 }
17423 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17424 num_matched = wlan_hdd_mdns_find_entries_from_end(
17425 resptype_ptr_dn, resptype_txt);
17426 if (num_matched > 0) {
17427 matchedlist[numlist].num_matched = num_matched;
17428 matchedlist[numlist].type = MDNS_TYPE_TXT;
17429 numlist++;
17430 }
17431 }
17432 if (resptype_a && (resptype_a->num_entries > 0)) {
17433 num_matched = wlan_hdd_mdns_find_entries_from_end(
17434 resptype_ptr_dn,resptype_a);
17435 if (num_matched > 0) {
17436 matchedlist[numlist].num_matched = num_matched;
17437 matchedlist[numlist].type = MDNS_TYPE_A;
17438 numlist++;
17439 }
17440 }
17441 if (numlist > 0) {
17442 if (numlist > 1)
17443 wlan_hdd_mdns_find_max(matchedlist, numlist);
17444 resp = NULL;
17445 switch (matchedlist[numlist-1].type) {
17446 case MDNS_TYPE_A:
17447 resp = resptype_a;
17448 break;
17449 case MDNS_TYPE_TXT:
17450 resp = resptype_txt;
17451 break;
17452 case MDNS_TYPE_PTR:
17453 resp = resptype_ptr;
17454 break;
17455 default:
17456 hddLog(LOGE, FL("Fail to compress mDNS response "
17457 "(%d)!"), MDNS_TYPE_PTR_DNAME);
17458 return FALSE;
17459 }
17460 num_matched = matchedlist[numlist-1].num_matched;
17461 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_ptr_dn,
17462 resp, num_matched)) {
17463 hddLog(LOGE, FL("Fail to compress mDNS response "
17464 "(%d)!"), MDNS_TYPE_PTR_DNAME);
17465 return FALSE;
17466 }
17467 } else {
17468 /* num = 0 -> no matched string */
17469 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr_dn,
17470 resp_info)) {
17471 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17472 MDNS_TYPE_PTR_DNAME);
17473 return FALSE;
17474 }
17475 }
17476
17477 return TRUE;
17478}
17479
17480/**
17481 * wlan_hdd_mdns_pack_response_type_ptr() - Pack Type PTR response
17482 * @ini_config: Pointer to the struct hdd_config_t
17483 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17484 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17485 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17486 * domain name
17487 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17488 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17489 *
17490 * The Type Ptr response include QName, response type, class, TTL and
17491 * Type PTR domain name. Also, it will find the matched QName from the
17492 * existing resptype_txt, resptype_a and then compress the data.
17493 *
17494 * Return: Return boolean. TRUE for success, FALSE for fail.
17495 */
17496static bool
17497wlan_hdd_mdns_pack_response_type_ptr(hdd_config_t *ini_config,
17498 sir_mdns_resp_info resp_info,
17499 struct hdd_mdns_resp_info *resptype_ptr,
17500 struct hdd_mdns_resp_info *resptype_ptr_dn,
17501 struct hdd_mdns_resp_info *resptype_txt,
17502 struct hdd_mdns_resp_info *resptype_a)
17503{
17504 uint8_t num_matched, num_matched1;
17505 uint16_t value;
17506 uint8_t val_u8;
17507 uint32_t offset_data_len, len;
17508
17509 ENTER();
17510 if ((ini_config == NULL) || (resp_info == NULL) ||
17511 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
17512 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17513 return FALSE;
17514 }
17515
17516 /* No Type Ptr response */
17517 if (strlen((char *)ini_config->mdns_resp_type_ptr) <= 0)
17518 return TRUE;
17519
17520 /* Wrong response is assigned, just ignore this response */
17521 if (!wlan_hdd_mdns_init_response(resptype_ptr,
17522 ini_config->mdns_resp_type_ptr, '.'))
17523 return TRUE;
17524
17525 /*
17526 * For data compression
17527 * Check if any strings are matched with Type A response
17528 */
17529 num_matched = 0;
17530 num_matched1 = 0;
17531 if (resptype_a && (resptype_a->num_entries > 0)) {
17532 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr,
17533 resptype_a);
17534 }
17535 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17536 num_matched1 = wlan_hdd_mdns_find_entries_from_end(
17537 resptype_ptr, resptype_txt);
17538 }
17539 if ((num_matched != num_matched1) ||
17540 ((num_matched > 0) && (num_matched1 > 0))) {
17541 if (num_matched >= num_matched1) {
17542 if (!wlan_hdd_mdns_compress_data(resp_info,
17543 resptype_ptr, resptype_a, num_matched)) {
17544 hddLog(LOGE, FL("Fail to compress mDNS "
17545 "response (%d)!"), MDNS_TYPE_PTR);
17546 return FALSE;
17547 }
17548 } else {
17549 /* num_matched is less than num_matched1 */
17550 if (!wlan_hdd_mdns_compress_data(resp_info,
17551 resptype_ptr, resptype_txt, num_matched1)) {
17552 hddLog(LOGE, FL("Fail to compress mDNS "
17553 "response (%d)!"), MDNS_TYPE_PTR);
17554 return FALSE;
17555 }
17556 }
17557 } else {
17558 /*
17559 * Both num_matched and num_matched1 are zero.
17560 * no TypeA & TypeTxt
17561 */
17562 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr,
17563 resp_info)) {
17564 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17565 MDNS_TYPE_PTR);
17566 return FALSE;
17567 }
17568 }
17569
17570 /* Process response Type, Class, TTL */
17571 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_PTR, resp_info)) {
17572 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17573 MDNS_TYPE_PTR);
17574 return FALSE;
17575 }
17576
17577 /*
17578 * Process response RDLength, RData (Ptr domain name)
17579 * Save the offset of RData length
17580 */
17581 offset_data_len = resp_info->resp_len;
17582 resp_info->resp_len += sizeof(uint16_t);
17583
17584 if (!wlan_hdd_mdns_pack_response_type_ptr_dname(ini_config, resp_info,
17585 resptype_ptr_dn, resptype_ptr,
17586 resptype_txt, resptype_a)) {
17587 return FALSE;
17588 }
17589 /* Set the RData length */
17590 len = offset_data_len + sizeof(uint16_t);
17591 if ((resptype_ptr_dn->num_entries > 0) &&
17592 (resp_info->resp_len > len)) {
17593 value = resp_info->resp_len - len;
17594 val_u8 = (value & 0xff00) >> 8;
17595 resp_info->resp_data[offset_data_len] = val_u8;
17596 val_u8 = value & 0xff;
17597 resp_info->resp_data[offset_data_len+1] = val_u8;
17598 } else {
17599 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17600 MDNS_TYPE_PTR);
17601 return FALSE;
17602 }
17603
17604 EXIT();
17605 return TRUE;
17606}
17607
17608/**
17609 * wlan_hdd_mdns_pack_response_type_srv_target()- Pack Type Service Target
17610 * @ini_config: Pointer to the struct hdd_config_t
17611 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17612 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
17613 * target
17614 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
17615 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17616 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17617 * domain name
17618 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17619 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17620 *
17621 * The Type service target is one of the data field in the Type SRV response.
17622 * Also, it will find the matched QName from the existing resptype_srv,
17623 * resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and then compress
17624 * the data.
17625 *
17626 * Return: Return boolean. TRUE for success, FALSE for fail.
17627 */
17628static bool
17629wlan_hdd_mdns_pack_response_type_srv_target(hdd_config_t *ini_config,
17630 sir_mdns_resp_info resp_info,
17631 struct hdd_mdns_resp_info *resptype_srv_tgt,
17632 struct hdd_mdns_resp_info *resptype_srv,
17633 struct hdd_mdns_resp_info *resptype_ptr,
17634 struct hdd_mdns_resp_info *resptype_ptr_dn,
17635 struct hdd_mdns_resp_info *resptype_txt,
17636 struct hdd_mdns_resp_info *resptype_a)
17637{
17638 uint8_t num_matched, num, size;
17639 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17640 struct hdd_mdns_resp_info *resp;
17641
17642 if ((ini_config == NULL) || (resp_info == NULL) ||
17643 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
17644 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17645 return FALSE;
17646 }
17647
17648 /* No Type Srv Target response */
17649 if (strlen((char *)ini_config->mdns_resp_type_srv_target) <= 0)
17650 return TRUE;
17651
17652 /* Wrong response is assigned, just ignore this response */
17653 if (!wlan_hdd_mdns_init_response(resptype_srv_tgt,
17654 ini_config->mdns_resp_type_srv_target, '.'))
17655 return TRUE;
17656
17657 /*
17658 * For data compression
17659 * Check if any strings are matched with previous response.
17660 */
17661 num = 0;
17662 size = (MAX_MDNS_RESP_TYPE-1);
17663 size *= sizeof(struct hdd_mdns_resp_matched);
17664 vos_mem_zero(matchedlist, size);
17665 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv_tgt,
17666 resptype_srv);
17667 if (num_matched > 0) {
17668 matchedlist[num].num_matched = num_matched;
17669 matchedlist[num].type = MDNS_TYPE_SRV;
17670 num++;
17671 }
17672 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
17673 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
17674 num_matched = wlan_hdd_mdns_find_entries_from_end(
17675 resptype_srv_tgt, resptype_ptr_dn);
17676 if (num_matched > 0) {
17677 matchedlist[num].num_matched = num_matched;
17678 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
17679 num++;
17680 }
17681 }
17682 num_matched = wlan_hdd_mdns_find_entries_from_end(
17683 resptype_srv_tgt, resptype_ptr);
17684 if (num_matched > 0) {
17685 matchedlist[num].num_matched = num_matched;
17686 matchedlist[num].type = MDNS_TYPE_PTR;
17687 num++;
17688 }
17689 }
17690 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17691 num_matched = wlan_hdd_mdns_find_entries_from_end(
17692 resptype_srv_tgt, resptype_txt);
17693 if (num_matched > 0) {
17694 matchedlist[num].num_matched = num_matched;
17695 matchedlist[num].type = MDNS_TYPE_TXT;
17696 num++;
17697 }
17698 }
17699 if (resptype_a && (resptype_a->num_entries > 0)) {
17700 num_matched = wlan_hdd_mdns_find_entries_from_end(
17701 resptype_srv_tgt, resptype_a);
17702 if (num_matched > 0) {
17703 matchedlist[num].num_matched = num_matched;
17704 matchedlist[num].type = MDNS_TYPE_A;
17705 num++;
17706 }
17707 }
17708 if (num > 0) {
17709 if (num > 1)
17710 wlan_hdd_mdns_find_max(matchedlist, num);
17711 resp = NULL;
17712 switch (matchedlist[num-1].type) {
17713 case MDNS_TYPE_A:
17714 resp = resptype_a;
17715 break;
17716 case MDNS_TYPE_TXT:
17717 resp = resptype_txt;
17718 break;
17719 case MDNS_TYPE_PTR:
17720 resp = resptype_ptr;
17721 break;
17722 case MDNS_TYPE_PTR_DNAME:
17723 resp = resptype_ptr_dn;
17724 break;
17725 case MDNS_TYPE_SRV:
17726 resp = resptype_srv;
17727 break;
17728 default:
17729 hddLog(LOGE, FL("Fail to compress mDNS response "
17730 "(%d)!"), MDNS_TYPE_SRV_TARGET);
17731 return FALSE;
17732 }
17733 num_matched = matchedlist[num-1].num_matched;
17734 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv_tgt,
17735 resp, num_matched)) {
17736 hddLog(LOGE, FL("Fail to compress mDNS response "
17737 "(%d)!"), MDNS_TYPE_SRV_TARGET);
17738 return FALSE;
17739 }
17740 } else {
17741 /* num = 0 -> no matched string */
17742 if (!wlan_hdd_mdns_process_response_dname(resptype_srv_tgt,
17743 resp_info)) {
17744 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17745 MDNS_TYPE_SRV_TARGET);
17746 return FALSE;
17747 }
17748 }
17749
17750 return TRUE;
17751}
17752
17753/**
17754 * wlan_hdd_mdns_pack_response_type_srv()- Pack Type Service response
17755 * @ini_config: Pointer to the struct hdd_config_t
17756 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17757 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
17758 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
17759 * target
17760 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17761 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17762 * domain name
17763 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17764 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17765 *
17766 * The Type SRV (Service) response include QName, response type, class, TTL
17767 * and four kinds of data fields. Also, it will find the matched QName from
17768 * the existing resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and
17769 * then compress the data.
17770 *
17771 * Return: Return boolean. TRUE for success, FALSE for fail.
17772 */
17773static bool
17774wlan_hdd_mdns_pack_response_type_srv(hdd_config_t *ini_config,
17775 sir_mdns_resp_info resp_info,
17776 struct hdd_mdns_resp_info *resptype_srv,
17777 struct hdd_mdns_resp_info *resptype_srv_tgt,
17778 struct hdd_mdns_resp_info *resptype_ptr,
17779 struct hdd_mdns_resp_info *resptype_ptr_dn,
17780 struct hdd_mdns_resp_info *resptype_txt,
17781 struct hdd_mdns_resp_info *resptype_a)
17782{
17783 uint8_t num_matched, num, size;
17784 uint16_t value;
17785 uint8_t val_u8;
17786 uint32_t offset_data_len, len;
17787 struct hdd_mdns_resp_info *resp;
17788 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17789
17790 ENTER();
17791
17792 if ((ini_config == NULL) || (resp_info == NULL) ||
17793 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
17794 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17795 return FALSE;
17796 }
17797
17798 /* No Type Srv response */
17799 if (strlen((char *)ini_config->mdns_resp_type_srv) <= 0)
17800 return TRUE;
17801
17802 /* Wrong response is assigned, just ignore this response */
17803 if (!wlan_hdd_mdns_init_response(resptype_srv,
17804 ini_config->mdns_resp_type_srv, '.'))
17805 return TRUE;
17806
17807 /*
17808 * For data compression
17809 * Check if any strings are matched with Type A response
17810 */
17811 num = 0;
17812 size = (MAX_MDNS_RESP_TYPE-1);
17813 size *= sizeof(struct hdd_mdns_resp_matched);
17814 vos_mem_zero(matchedlist, size);
17815 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
17816 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
17817 num_matched = wlan_hdd_mdns_find_entries_from_end(
17818 resptype_srv,
17819 resptype_ptr_dn);
17820 if (num_matched > 0) {
17821 matchedlist[num].num_matched = num_matched;
17822 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
17823 num++;
17824 }
17825 }
17826 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17827 resptype_ptr);
17828 if (num_matched > 0) {
17829 matchedlist[num].num_matched = num_matched;
17830 matchedlist[num].type = MDNS_TYPE_PTR;
17831 num++;
17832 }
17833 }
17834 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17835 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17836 resptype_txt);
17837 if (num_matched > 0) {
17838 matchedlist[num].num_matched =num_matched;
17839 matchedlist[num].type = MDNS_TYPE_TXT;
17840 num++;
17841 }
17842 }
17843 if (resptype_a && (resptype_a->num_entries > 0)) {
17844 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17845 resptype_a);
17846 if (num_matched > 0) {
17847 matchedlist[num].num_matched = num_matched;
17848 matchedlist[num].type = MDNS_TYPE_A;
17849 num++;
17850 }
17851 }
17852 if (num > 0) {
17853 if (num > 1)
17854 wlan_hdd_mdns_find_max(matchedlist, num);
17855 resp = NULL;
17856 switch (matchedlist[num-1].type) {
17857 case MDNS_TYPE_A:
17858 resp = resptype_a;
17859 break;
17860 case MDNS_TYPE_TXT:
17861 resp = resptype_txt;
17862 break;
17863 case MDNS_TYPE_PTR:
17864 resp = resptype_ptr;
17865 break;
17866 case MDNS_TYPE_PTR_DNAME:
17867 resp = resptype_ptr_dn;
17868 break;
17869 default:
17870 hddLog(LOGE, FL("Fail to compress mDNS response "
17871 "(%d)!"), MDNS_TYPE_SRV);
17872 return FALSE;
17873 }
17874 num_matched = matchedlist[num-1].num_matched;
17875 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv,
17876 resp, num_matched)) {
17877 hddLog(LOGE, FL("Fail to compress mDNS response "
17878 "(%d)!"), MDNS_TYPE_SRV);
17879 return FALSE;
17880 }
17881 } else {
17882 /* num = 0 -> no matched string */
17883 if (!wlan_hdd_mdns_process_response_dname(resptype_srv,
17884 resp_info)) {
17885 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17886 MDNS_TYPE_SRV);
17887 return FALSE;
17888 }
17889 }
17890
17891 /* Process response Type, Class, TTL */
17892 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_SRV, resp_info)) {
17893 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17894 MDNS_TYPE_SRV);
17895 return FALSE;
17896 }
17897
17898 /*
17899 * Process response RDLength, RData (Srv target name)
17900 * Save the offset of RData length
17901 */
17902 offset_data_len = resp_info->resp_len;
17903 resp_info->resp_len += sizeof(uint16_t);
17904
17905 len = resp_info->resp_len + (3 * sizeof(uint16_t));
17906 if (len >= MAX_MDNS_RESP_LEN) {
17907 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17908 return FALSE;
17909 }
17910
17911 /* set Srv Priority */
17912 value = ini_config->mdns_resp_type_srv_priority;
17913 wlan_hdd_mdns_format_response_u16(value, resp_info);
17914 /* set Srv Weight */
17915 value = ini_config->mdns_resp_type_srv_weight;
17916 wlan_hdd_mdns_format_response_u16(value, resp_info);
17917 /* set Srv Port */
17918 value = ini_config->mdns_resp_type_srv_port;
17919 wlan_hdd_mdns_format_response_u16(value, resp_info);
17920
17921 if (!wlan_hdd_mdns_pack_response_type_srv_target(ini_config, resp_info,
17922 resptype_srv_tgt, resptype_srv,
17923 resptype_ptr, resptype_ptr_dn,
17924 resptype_txt, resptype_a)) {
17925 return FALSE;
17926 }
17927 /* Set the RData length */
17928 len = offset_data_len + sizeof(uint16_t);
17929 if ((resptype_srv_tgt->num_entries > 0) &&
17930 (resp_info->resp_len > len)) {
17931 value = resp_info->resp_len - len;
17932 val_u8 = (value & 0xff00) >> 8;
17933 resp_info->resp_data[offset_data_len] = val_u8;
17934 val_u8 = value & 0xff;
17935 resp_info->resp_data[offset_data_len+1] = val_u8;
17936 } else {
17937 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17938 MDNS_TYPE_SRV);
17939 return FALSE;
17940 }
17941
17942 EXIT();
17943 return TRUE;
17944}
17945
17946/**
17947 * wlan_hdd_mdns_free_mem() - Free the allocated memory
17948 * @response: Pointer to the struct hdd_mdns_resp_info
17949 *
17950 * Return: None
17951 */
17952static void wlan_hdd_mdns_free_mem(struct hdd_mdns_resp_info *response)
17953{
17954 if (response && response->data)
17955 vos_mem_free(response->data);
17956 if (response && response->offset)
17957 vos_mem_free(response->offset);
17958}
17959
17960/**
17961 * wlan_hdd_mdns_pack_response() - Pack mDNS response
17962 * @ini_config: Pointer to the struct hdd_config_t
17963 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17964 *
17965 * This function will pack four types of responses (Type A, Type Txt, Type Ptr
17966 * and Type Service). Each response contains QName, response type, class, TTL
17967 * and data fields.
17968 *
17969 * Return: Return boolean. TRUE for success, FALSE for fail.
17970 */
17971static bool wlan_hdd_mdns_pack_response(hdd_config_t *ini_config,
17972 sir_mdns_resp_info resp_info)
17973{
17974 struct hdd_mdns_resp_info resptype_a, resptype_txt;
17975 struct hdd_mdns_resp_info resptype_ptr, resptype_ptr_dn;
17976 struct hdd_mdns_resp_info resptype_srv, resptype_srv_tgt;
17977 uint32_t num_res_records = 0;
17978 bool status = FALSE;
17979
17980 ENTER();
17981
17982 wlan_hdd_mdns_reset_response(&resptype_a);
17983 wlan_hdd_mdns_reset_response(&resptype_txt);
17984 wlan_hdd_mdns_reset_response(&resptype_ptr);
17985 wlan_hdd_mdns_reset_response(&resptype_ptr_dn);
17986 wlan_hdd_mdns_reset_response(&resptype_srv);
17987 wlan_hdd_mdns_reset_response(&resptype_srv_tgt);
17988
17989 resp_info->resp_len = 0;
17990
17991 /* Process Type A response */
17992 if (!wlan_hdd_mdns_pack_response_type_a(ini_config, resp_info,
17993 &resptype_a))
17994 goto err_resptype_a;
17995
17996 if ((resptype_a.num_entries > 0) &&
17997 (strlen((char *)&resptype_a.data[0]) > 0))
17998 num_res_records++;
17999
18000 /* Process Type TXT response */
18001 if (!wlan_hdd_mdns_pack_response_type_txt(ini_config, resp_info,
18002 &resptype_txt, &resptype_a))
18003 goto err_resptype_txt;
18004
18005 if ((resptype_txt.num_entries > 0) &&
18006 (strlen((char *)&resptype_txt.data[0]) > 0))
18007 num_res_records++;
18008
18009 /* Process Type PTR response */
18010 if (!wlan_hdd_mdns_pack_response_type_ptr(ini_config, resp_info,
18011 &resptype_ptr, &resptype_ptr_dn,
18012 &resptype_txt, &resptype_a))
18013 goto err_resptype_ptr;
18014
18015 if ((resptype_ptr.num_entries > 0) &&
18016 (strlen((char *)&resptype_ptr.data[0]) > 0))
18017 num_res_records++;
18018
18019 /* Process Type SRV response */
18020 if (!wlan_hdd_mdns_pack_response_type_srv(ini_config, resp_info,
18021 &resptype_srv, &resptype_srv_tgt,
18022 &resptype_ptr, &resptype_ptr_dn,
18023 &resptype_txt, &resptype_a))
18024 goto err_resptype_srv;
18025
18026 if ((resptype_srv.num_entries > 0) &&
18027 (strlen((char *)&resptype_srv.data[0]) > 0))
18028 num_res_records++;
18029
18030 resp_info->resourceRecord_count = num_res_records;
18031 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
18032 "%s: Pack mDNS response data successfully!", __func__);
18033 status = TRUE;
18034
18035err_resptype_srv:
18036 wlan_hdd_mdns_free_mem(&resptype_srv);
18037 wlan_hdd_mdns_free_mem(&resptype_srv_tgt);
18038
18039err_resptype_ptr:
18040 wlan_hdd_mdns_free_mem(&resptype_ptr);
18041 wlan_hdd_mdns_free_mem(&resptype_ptr_dn);
18042
18043err_resptype_txt:
18044 wlan_hdd_mdns_free_mem(&resptype_txt);
18045
18046err_resptype_a:
18047 wlan_hdd_mdns_free_mem(&resptype_a);
18048
18049 EXIT();
18050 return status;
18051}
18052
18053/**
18054 * wlan_hdd_set_mdns_offload() - Enable mDNS offload
18055 * @hostapd_adapter: Pointer to the struct hdd_adapter_t
18056 *
18057 * This function will set FQDN/unique FQDN (full qualified domain name)
18058 * and the mDNS response. Then send them to SME.
18059 *
18060 * Return: Return boolean. TRUE for success, FALSE for fail.
18061 */
18062bool wlan_hdd_set_mdns_offload(hdd_adapter_t *hostapd_adapter)
18063{
18064 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
18065 sir_mdns_offload_info mdns_offload_info;
18066 sir_mdns_fqdn_info mdns_fqdn_info;
18067 sir_mdns_resp_info mdns_resp_info;
18068 uint32_t fqdn_len, ufqdn_len;
18069
18070 ENTER();
18071
18072 /* 1. Prepare the MDNS fqdn request to send to SME */
18073 fqdn_len = strlen(hdd_ctx->cfg_ini->mdns_fqdn);
18074 ufqdn_len = strlen(hdd_ctx->cfg_ini->mdns_uniquefqdn);
18075 if ((fqdn_len == 0) && (ufqdn_len == 0)) {
18076 hddLog(LOGE, FL("No mDNS FQDN or UFQDN is assigned fqdn_len %d,"
18077 "ufqdn_len %d!"), fqdn_len, ufqdn_len);
18078 return FALSE;
18079 }
18080
18081 mdns_fqdn_info = vos_mem_malloc(sizeof(*mdns_fqdn_info));
18082 if (NULL == mdns_fqdn_info) {
18083 hddLog(LOGE, FL("could not allocate tSirMDNSFqdnInfo!"));
18084 return FALSE;
18085 }
18086 /* MDNS fqdn request */
18087 if (fqdn_len > 0) {
18088 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
18089 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
18090 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_GENERAL;
18091 mdns_fqdn_info->fqdn_len = fqdn_len;
18092 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
18093 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
18094 vos_mem_copy(mdns_fqdn_info->fqdn_data,
18095 hdd_ctx->cfg_ini->mdns_fqdn,
18096 mdns_fqdn_info->fqdn_len);
18097
18098 if (eHAL_STATUS_SUCCESS !=
18099 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
18100 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
18101 vos_mem_free(mdns_fqdn_info);
18102 return FALSE;
18103 }
18104 }
18105 /* MDNS unique fqdn request */
18106 if (ufqdn_len > 0) {
18107 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
18108 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
18109 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_UNIQUE;
18110 mdns_fqdn_info->fqdn_len = ufqdn_len;
18111 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
18112 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
18113 vos_mem_copy(mdns_fqdn_info->fqdn_data,
18114 hdd_ctx->cfg_ini->mdns_uniquefqdn,
18115 mdns_fqdn_info->fqdn_len);
18116 if (eHAL_STATUS_SUCCESS !=
18117 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
18118 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
18119 vos_mem_free(mdns_fqdn_info);
18120 return FALSE;
18121 }
18122 }
18123 vos_mem_free(mdns_fqdn_info);
18124
18125 /* 2. Prepare the MDNS response request to send to SME */
18126 mdns_resp_info = vos_mem_malloc(sizeof(*mdns_resp_info));
18127 if (NULL == mdns_resp_info) {
18128 hddLog(LOGE, FL("could not allocate tSirMDNSResponseInfo!"));
18129 return FALSE;
18130 }
18131
18132 vos_mem_zero(mdns_resp_info, sizeof(*mdns_resp_info));
18133 mdns_resp_info->bss_idx = hostapd_adapter->sessionId;
18134 mdns_resp_info->mdns_resp_callback = hdd_mdns_resp_offload_done;
18135 mdns_resp_info->mdns_resp_cb_context = hostapd_adapter;
18136 if (!wlan_hdd_mdns_pack_response(hdd_ctx->cfg_ini, mdns_resp_info)) {
18137 hddLog(LOGE, FL("wlan_hdd_pack_mdns_response fail!"));
18138 vos_mem_free(mdns_resp_info);
18139 return FALSE;
18140 }
18141 if (eHAL_STATUS_SUCCESS !=
18142 sme_set_mdns_resp(hdd_ctx->hHal, mdns_resp_info)) {
18143 hddLog(LOGE, FL("sme_set_mdns_resp fail!"));
18144 vos_mem_free(mdns_resp_info);
18145 return FALSE;
18146 }
18147 vos_mem_free(mdns_resp_info);
18148
18149 /* 3. Prepare the MDNS Enable request to send to SME */
18150 mdns_offload_info = vos_mem_malloc(sizeof(*mdns_offload_info));
18151 if (NULL == mdns_offload_info) {
18152 hddLog(LOGE, FL("could not allocate tSirMDNSOffloadInfo!"));
18153 return FALSE;
18154 }
18155
18156 vos_mem_zero(mdns_offload_info, sizeof(*mdns_offload_info));
18157
18158 mdns_offload_info->bss_idx = hostapd_adapter->sessionId;
18159 mdns_offload_info->enable = hdd_ctx->cfg_ini->enable_mdns_offload;
18160 mdns_offload_info->mdns_enable_callback = hdd_mdns_enable_offload_done;
18161 mdns_offload_info->mdns_enable_cb_context = hostapd_adapter;
18162 if (eHAL_STATUS_SUCCESS !=
18163 sme_set_mdns_offload(hdd_ctx->hHal, mdns_offload_info)) {
18164 hddLog(LOGE, FL("sme_set_mdns_offload fail!"));
18165 vos_mem_free(mdns_offload_info);
18166 return FALSE;
18167 }
18168
18169 vos_mem_free(mdns_offload_info);
18170 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
18171 "%s: enable mDNS offload successfully!", __func__);
18172 return TRUE;
18173}
Manjeet Singh3ed79242017-01-11 19:04:32 +053018174
18175
Anurag Chouhan0b29de02016-12-16 13:18:40 +053018176#endif /* MDNS_OFFLOAD */
c_manjeecfd1efb2015-09-25 19:32:34 +053018177
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053018178/**
18179 * wlan_hdd_start_sap() - This function starts bss of SAP.
18180 * @ap_adapter: SAP adapter
18181 *
18182 * This function will process the starting of sap adapter.
18183 *
18184 * Return: void.
18185 */
18186void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter)
18187{
18188 hdd_ap_ctx_t *hdd_ap_ctx;
18189 hdd_hostapd_state_t *hostapd_state;
18190 VOS_STATUS vos_status;
18191 hdd_context_t *hdd_ctx;
18192 tsap_Config_t *pConfig;
18193
18194 if (NULL == ap_adapter) {
18195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18196 FL("ap_adapter is NULL here"));
18197 return;
18198 }
18199
18200 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
18201 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
18202 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
18203 pConfig = &ap_adapter->sessionCtx.ap.sapConfig;
18204
18205 mutex_lock(&hdd_ctx->sap_lock);
18206 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
18207 goto end;
18208
18209 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
18210 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
18211 goto end;
18212 }
18213
18214 vos_event_reset(&hostapd_state->vosEvent);
18215 if (WLANSAP_StartBss(hdd_ctx->pvosContext, hdd_hostapd_SAPEventCB,
18216 &hdd_ap_ctx->sapConfig, (v_PVOID_t)ap_adapter->dev)
18217 != VOS_STATUS_SUCCESS) {
18218 goto end;
18219 }
18220
18221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
18222 FL("Waiting for SAP to start"));
18223 vos_status = vos_wait_single_event(&hostapd_state->vosEvent, 10000);
18224 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
18225 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18226 FL("SAP Start failed"));
18227 goto end;
18228 }
18229 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
18230 FL("SAP Start Success"));
18231 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
18232
18233 wlan_hdd_incr_active_session(hdd_ctx, ap_adapter->device_mode);
18234 hostapd_state->bCommit = TRUE;
18235
18236end:
18237 mutex_unlock(&hdd_ctx->sap_lock);
18238 return;
18239}
18240
Manjeet Singh3ed79242017-01-11 19:04:32 +053018241#ifdef WLAN_FEATURE_TSF
18242
18243/**
18244 * hdd_tsf_cb() - handle tsf request callback
18245 *
18246 * @pcb_cxt: pointer to the hdd_contex
18247 * @ptsf: pointer to struct stsf
18248 *
18249 * Based on the request sent .
18250 *
18251 * Return: Describe the execute result of this routine
18252 */
18253static int hdd_tsf_cb(void *pcb_ctx, struct stsf *ptsf)
18254{
18255 hdd_context_t *hddctx;
18256 int status;
18257 hdd_adapter_t* adapter = (hdd_adapter_t*)pcb_ctx;
18258
18259 if (pcb_ctx == NULL || ptsf == NULL) {
18260 hddLog(VOS_TRACE_LEVEL_ERROR,
18261 FL("HDD context is not valid"));
18262 return -EINVAL;
18263 }
18264
18265 hddctx = (hdd_context_t *)pcb_ctx;
18266 status = wlan_hdd_validate_context(hddctx);
18267 if (0 != status)
18268 return -EINVAL;
18269
18270 if (NULL == adapter) {
18271 hddLog(VOS_TRACE_LEVEL_ERROR,
18272 FL("failed to find adapter"));
18273 return -EINVAL;
18274 }
18275
18276 hddLog(VOS_TRACE_LEVEL_INFO,
18277 FL("tsf cb handle event, device_mode is %d"),
18278 adapter->device_mode);
18279
18280 /* copy the return value to hdd_tsf_ctx in adapter*/
18281 if (ptsf->tsf_req_status) {
18282
18283 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18284 adapter->tsf_cap_ctx.tsf_get_state = TSF_NOT_RETURNED_BY_FW;
18285 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18286 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
18287 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18288
18289 hddLog(VOS_TRACE_LEVEL_ERROR, FL("tsf req failure :%d"),
18290 ptsf->tsf_req_status);
18291 return ptsf->tsf_req_status;
18292 }
18293 /* If this is a get request.Store the tsf values in adapter. */
18294 if (!ptsf->set_tsf_req) {
18295 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18296 adapter->tsf_cap_ctx.tsf_low = ptsf->tsf_low;
18297 adapter->tsf_cap_ctx.tsf_high = ptsf->tsf_high;
18298 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
18299 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18300 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18301
18302 hddLog(VOS_TRACE_LEVEL_INFO,
18303 FL("hdd_get_tsf_cb sta=%u, tsf_low=%u, tsf_high=%u"),
18304 adapter->sessionId, ptsf->tsf_low, ptsf->tsf_high);
18305 }
18306 else {
18307 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18308 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
18309 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
18310 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18311 }
18312 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18313 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
18314 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18315
18316 /* free allocated mem */
18317 vos_mem_free(ptsf);
18318
18319 return 0;
18320}
18321
18322/**
18323 * hdd_capture_tsf() - capture tsf
18324 *
18325 * @adapter: pointer to adapter
18326 * @buf: pointer to upper layer buf
18327 * @len : the length of buf
18328 *
18329 * This function returns tsf value to uplayer.
18330 *
18331 * Return: Describe the execute result of this routine
18332 */
18333int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
18334{
18335 int ret = 0;
18336 hdd_station_ctx_t *hdd_sta_ctx;
18337 hdd_context_t *hdd_ctx;
18338 tSirCapTsfParams cap_tsf_params;
18339 VOS_STATUS status;
18340
18341 if (adapter == NULL || buf == NULL) {
18342 hddLog(VOS_TRACE_LEVEL_ERROR,
18343 FL("invalid pointer"));
18344 return -EINVAL;
18345 }
18346 if (len != 1)
18347 return -EINVAL;
18348
18349 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
18350
18351 if (wlan_hdd_validate_context(hdd_ctx)) {
18352 hddLog(VOS_TRACE_LEVEL_ERROR,
18353 FL("invalid hdd ctx"));
18354 return -EINVAL;
18355 }
18356 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18357 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
18358 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18359 if (hdd_sta_ctx->conn_info.connState !=
18360 eConnectionState_Associated) {
18361
18362 hddLog(VOS_TRACE_LEVEL_INFO,
18363 FL("failed to cap tsf, not connect with ap"));
18364 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
18365 return ret;
18366 }
18367 }
18368 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
18369 adapter->device_mode == WLAN_HDD_P2P_GO) &&
18370 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
18371 hddLog(VOS_TRACE_LEVEL_INFO,
18372 FL("Soft AP / P2p GO not beaconing"));
18373 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
18374 return ret;
18375 }
18376 if (adapter->tsf_cap_ctx.tsf_capture_state == TSF_CAP_STATE) {
18377 hddLog(VOS_TRACE_LEVEL_INFO,
18378 FL("current in capture state, pls reset"));
18379 buf[0] = TSF_CURRENT_IN_CAP_STATE;
18380 } else {
18381 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
18382 buf[0] = TSF_RETURN;
18383 cap_tsf_params.session_id = adapter->sessionId;
18384 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
18385 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
18386
18387 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18388 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
18389 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
18390 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18391
18392 ret = sme_capture_tsf_req(hdd_ctx->hHal, cap_tsf_params);
18393
18394 if (ret != VOS_STATUS_SUCCESS) {
18395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
18396 buf[0] = TSF_CAPTURE_FAIL;
18397 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18398 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18399 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18400 return -EINVAL;
18401 }
18402 /* wait till we get a response from fw */
18403 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
18404 tsf_capture_done_event,
18405 HDD_TSF_CAP_REQ_TIMEOUT);
18406
18407 if (!VOS_IS_STATUS_SUCCESS(status)) {
18408 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18409 ("capture tsf vos wait for single_event failed!! %d"),
18410 adapter->tsf_cap_ctx.tsf_get_state);
18411
18412 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18413 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18414 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18415
18416 return -EINVAL;
18417 }
18418 }
18419 buf[0] = TSF_RETURN;
18420 hddLog(VOS_TRACE_LEVEL_INFO,
18421 FL("ioctl return cap tsf cmd, ret = %d"), ret);
18422 return ret;
18423}
18424
18425/**
18426 * hdd_indicate_tsf() - return tsf to uplayer
18427 *
18428 * @adapter: pointer to adapter
18429 * @buf: pointer to uplayer buf
18430 * @len : the length of buf
18431 *
18432 * This function returns tsf value to uplayer.
18433 *
18434 * Return: Describe the execute result of this routine
18435 */
18436int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
18437{
18438 int ret = 0;
18439 hdd_station_ctx_t *hdd_sta_ctx;
18440 hdd_context_t *hdd_ctx;
18441 tSirCapTsfParams cap_tsf_params;
18442 VOS_STATUS status;
18443
18444 if (adapter == NULL || buf == NULL) {
18445 hddLog(VOS_TRACE_LEVEL_ERROR,
18446 FL("invalid pointer"));
18447 return -EINVAL;
18448 }
18449 if (len != 3)
18450 return -EINVAL;
18451
18452 buf [1] = 0;
18453 buf [2] = 0;
18454 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
18455
18456 if (wlan_hdd_validate_context(hdd_ctx)) {
18457 hddLog(VOS_TRACE_LEVEL_ERROR,
18458 FL("invalid hdd ctx"));
18459 return -EINVAL;
18460 }
18461 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18462 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
18463 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18464 if (hdd_sta_ctx->conn_info.connState !=
18465 eConnectionState_Associated) {
18466
18467 hddLog(VOS_TRACE_LEVEL_INFO,
18468 FL("failed to cap tsf, not connect with ap"));
18469 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
18470 return ret;
18471 }
18472 }
18473 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
18474 adapter->device_mode == WLAN_HDD_P2P_GO) &&
18475 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
18476 hddLog(VOS_TRACE_LEVEL_INFO,
18477 FL("Soft AP / P2p GO not beaconing"));
18478 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
18479 return ret;
18480 }
18481
18482 if (adapter->tsf_cap_ctx.tsf_capture_state != TSF_CAP_STATE ||
18483 adapter->tsf_cap_ctx.tsf_get_state != TSF_CURRENT_IN_CAP_STATE ) {
18484 hddLog(VOS_TRACE_LEVEL_INFO,
18485 FL("Not in capture state,Enter capture state first"));
18486 buf[0] = TSF_GET_FAIL;
18487 } else {
18488 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
18489 cap_tsf_params.session_id = adapter->sessionId;
18490 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
18491 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
18492
18493 ret = sme_get_tsf_req(hdd_ctx->hHal, cap_tsf_params);
18494
18495 if (ret != VOS_STATUS_SUCCESS) {
18496 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
18497 buf[0] = TSF_CAPTURE_FAIL;
18498 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18499 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18500 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18501 return -EINVAL;
18502 }
18503 /* wait till we get a response from fw */
18504 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
18505 tsf_capture_done_event,
18506 HDD_TSF_GET_REQ_TIMEOUT);
18507
18508 if (!VOS_IS_STATUS_SUCCESS(status)) {
18509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18510 ("capture tsf vos wait for single_event failed!! %d"),
18511 status);
18512
18513 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18514 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18515 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18516 return status;
18517 }
18518 buf[1] = adapter->tsf_cap_ctx.tsf_low;
18519 buf[2] = adapter->tsf_cap_ctx.tsf_high;
18520
18521 hddLog(VOS_TRACE_LEVEL_INFO,
18522 FL("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u"),
18523 buf[0], buf[1], buf[2]);
18524 }
18525 hddLog(VOS_TRACE_LEVEL_INFO,
18526 FL("ioctl return cap tsf cmd, ret = %d"), ret);
18527 return ret;
18528}
18529
18530void wlan_hdd_tsf_init(hdd_adapter_t *adapter)
18531{
18532
18533 if (adapter == NULL) {
18534 hddLog(VOS_TRACE_LEVEL_ERROR,
18535 FL("TSF init on a null adapter!"));
18536 return;
18537 }
18538
18539 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
18540 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18541 vos_event_init(&adapter->tsf_cap_ctx.tsf_capture_done_event);
18542 vos_spin_lock_init(&adapter->tsf_cap_ctx.tsf_lock);
18543 adapter->tsf_cap_ctx.tsf_high = 0;
18544 adapter->tsf_cap_ctx.tsf_low = 0;
18545}
18546
18547#endif
18548
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +053018549bool hdd_is_memdump_supported(void)
18550{
18551#ifdef WLAN_FEATURE_MEMDUMP
18552 return true;
18553#endif
18554 return false;
18555}
18556
Hanumanth Reddy Pothula972e1df2018-06-14 13:33:47 +053018557bool hdd_is_cli_iface_up(hdd_context_t *hdd_ctx)
18558{
18559 hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
18560 hdd_adapter_t *adapter;
18561 VOS_STATUS status;
18562
18563 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
18564 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
18565 adapter = adapter_node->pAdapter;
18566 if ((adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18567 adapter->device_mode == WLAN_HDD_P2P_CLIENT) &&
18568 test_bit(DEVICE_IFACE_OPENED,
18569 &adapter->event_flags)){
18570 return true;
18571 }
18572 status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
18573 adapter_node = next;
18574 }
18575
18576 return false;
18577}
18578
Jeff Johnson295189b2012-06-20 16:38:30 -070018579//Register the module init/exit functions
18580module_init(hdd_module_init);
18581module_exit(hdd_module_exit);
18582
18583MODULE_LICENSE("Dual BSD/GPL");
18584MODULE_AUTHOR("Qualcomm Atheros, Inc.");
18585MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
18586
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018587static const struct kernel_param_ops con_mode_ops = {
18588 .set = con_mode_handler,
18589 .get = param_get_int,
18590};
18591
18592static const struct kernel_param_ops fwpath_ops = {
18593 .set = fwpath_changed_handler,
18594 .get = param_get_string,
18595};
18596
Hanumanth Reddy Pothula99219872018-06-08 14:45:18 +053018597#ifdef MODULE
18598module_param(con_mode, int, 0);
18599#else
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018600module_param_cb(con_mode, &con_mode_ops, &con_mode,
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070018601 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Hanumanth Reddy Pothula99219872018-06-08 14:45:18 +053018602#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -070018603
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018604module_param_cb(fwpath, &fwpath_ops, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070018605 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080018606
18607module_param(enable_dfs_chan_scan, int,
18608 S_IRUSR | S_IRGRP | S_IROTH);
18609
18610module_param(enable_11d, int,
18611 S_IRUSR | S_IRGRP | S_IROTH);
18612
18613module_param(country_code, charp,
18614 S_IRUSR | S_IRGRP | S_IROTH);